import { Payment } from '../../lib/models.js'; import { API } from "../../lib/api.js"; import logging from '../../lib/logging.js'; import dayjs from 'dayjs'; import { product_id, fake_payments, register_enabled } from "../../client/config.js"; import { paypal_private } from "../../lib/config.js"; import assert from 'assert'; import * as queues from "../../lib/queues.js"; const pay_queue = queues.create("paypal/validate_order"); const log = logging.create("api/payments/paypal.js"); const rules = { sys_primary_id: "required", sys_secondary_id: "required", sys_created_on: "required|date" } export const post = async (req, res) => { const api = new API(req, res); if(!register_enabled) { return api.error(500, {errors: { main: "Registration is disabled."}}); } try { assert(!fake_payments, "You have fake_payments set so use /api/user/payment/fake APIs instead."); assert(!paypal_private.disabled, "Paypal Payments are disabled in secrets/config.json"); const msg = api.validate(rules); if(msg._valid) { log.debug("Paypal recieved message", msg); let internal_id = Payment.gen_internal_id(); // TODO: see if we can use date-fns instead of dayjs here let payment = await Payment.insert({ user_id: api.user.id, system: 'paypal', status: 'complete', internal_id, sys_primary_id: msg.sys_primary_id, sys_secondary_id: msg.sys_secondary_id, sys_created_on: dayjs(msg.sys_created_on) }); // TODO: should we await here? pay_queue.add({payment_id: payment.id}); assert(payment && payment.internal_id, "Failed to save payment."); let result = { sys_primary_id: payment.sys_primary_id, status: payment.status, internal_id: payment.internal_id } queues.send_welcome(api.user); queues.send_receipt(api.user, payment.id, product_id); log.debug(result); return api.reply(200, result); } else { log.error(msg._errors, "paypal validation failure"); return api.validation_error(res, msg); } } catch(error) { log.error(error); return api.error(403, 'PayPal configuration failed'); } } post.authenticated = true;