const Roles = require('../../../lib/Roles') const logger = require('../../../lib/logger') const generateMemberships = require('../../../lib/generateMemberships') const sendPaymentSuccessful = require('../../../lib/payments/sendPaymentSuccessful') module.exports = async (_, args, {pgdb, req, t}) => { Roles.ensureUserHasRole(req.user, 'supporter') const { paymentId, status, reason } = args const now = new Date() const transaction = await pgdb.transactionBegin() try { const payment = await transaction.public.payments.findOne({id: paymentId}) if (!payment) { logger.error('payment not found', { req: req._log(), args }) throw new Error(t('api/payment/404')) } // check if state transform is allowed if (status === 'PAID') { if (payment.status !== 'WAITING') { logger.error('only payments with status WAITING can be set to PAID', { req: req._log(), args, payment } ) throw new Error(t('api/unexpected')) } if (!reason) { logger.error('need reason', { req: req._log(), args, payment }) throw new Error(t('package/customize/userPrice/reason/error')) } } else if (status === 'REFUNDED') { if (payment.status !== 'WAITING_FOR_REFUND') { logger.error('only payments with status WAITING_FOR_REFUND can be REFUNDED', { req: req._log(), args, payment } ) throw new Error(t('api/unexpected')) } } else { logger.error('only change to PAID and REFUNDED supported.', { req: req._log(), args, payment }) throw new Error(t('api/unexpected')) } let prefixedReason if (reason) { prefixedReason = 'Support: ' + reason } await transaction.public.payments.updateOne({ id: payment.id }, { status, pspPayload: prefixedReason, updatedAt: now }, { skipUndefined: true }) // update pledge status if (status === 'PAID') { const pledge = (await transaction.query(` SELECT p.* FROM "pledgePayments" pp JOIN pledges p ON pp."pledgeId" = p.id WHERE pp."paymentId" = :paymentId `, { paymentId }))[0] if (pledge.reason !== 'SUCCESSFUL') { await transaction.public.pledges.updateOne({ id: pledge.id }, { status: 'SUCCESSFUL', updatedAt: now }) } if (pledge.total > 100000) { await generateMemberships(pledge.id, transaction, t) } await sendPaymentSuccessful(pledge.id, transaction, t) } await transaction.transactionCommit() } catch (e) { await transaction.transactionRollback() logger.info('transaction rollback', { req: req._log(), args, error: e }) throw e } return pgdb.public.payments.findOne({id: paymentId}) }