import { Payment, PaymentProcessingState } from '../types';
import { convertFromPrisma } from '../converters';
import { prisma } from '../prisma';
import { tracer } from '@capchase/tracer';
import { create } from './create';
import { callLog } from '../call_log';
import { incrementMetric } from '@capchase/metrics';
const internalProcessPayment = async (
paymentKey: string,
processingKey: string,
actionBy: string
): Promise<Payment> => {
await callLog({
callName: 'processPayment',
actionBy,
args: [paymentKey, processingKey, actionBy],
});
const span = tracer?.scope()?.active();
span?.addTags({
payment_key: paymentKey,
processing_key: processingKey,
action_by: actionBy,
});
// TODO(SHI-1454): Validate actual user permissions
if (actionBy.length === 0) {
throw new Error('Action by should be set');
}
const payment = convertFromPrisma(
(
await prisma.payment.findMany({
where: {
key: paymentKey,
processingKey,
},
})
)[0]
);
// If the last payment has already been processed
// return it directly, i.e. noop
if (payment.processingState === PaymentProcessingState.PROCESSED) {
return payment;
}
// Append a new copy of the current payment marking it as processed
const processedPayment = await create({
...payment,
processingState: PaymentProcessingState.PROCESSED,
actionBy: actionBy,
});
incrementMetric('payment_system.payment.process', {
status: processedPayment.status,
processing_state: processedPayment.processingState,
contract_name: processedPayment.contractName,
action_by: actionBy,
});
return processedPayment;
};
/**
* Marks a payment for a given (`paymentKey`, `processingKey`) pair as processed.
*
* @param {string} paymentKey Payment key
* @param {string} processingKey Processing key
* @param {string} actionBy Action executor
* @return {Promise<Payment>} The processed payment
*
* @throws {Error} If no unprocessed payment with the requested params is not found.
*
* @async
* @function
* @memberOf module:payments/actions
* @access public
*/
const processPayment =
tracer?.wrap('payments.processPayment', internalProcessPayment) ||
internalProcessPayment;
export { processPayment };