import {
Payment,
ExternalPaymentEvent,
PaymentProcessingState,
} from '../types';
import { matchExternalStatus } from '../status_matching';
import { tracer } from '@capchase/tracer';
import { convertFromPrisma } from '../converters';
import { prisma } from '../prisma';
import { create } from './create';
import { callLog } from '../call_log';
import { incrementMetric } from '@capchase/metrics';
const internalHandleEvent = async (
event: ExternalPaymentEvent,
actionBy: string
): Promise<Payment> => {
await callLog({
callName: 'handlePayment',
actionBy,
args: [event, actionBy],
});
const span = tracer?.scope()?.active();
const {
id,
status,
service,
event_id,
external_url,
metadata,
created_at,
payment_id,
} = event;
span?.addTags({
status,
service,
event_data: event,
});
const payment = convertFromPrisma(
(
await prisma.payment.findMany({
take: 1,
orderBy: [
{
id: 'desc',
},
],
// If the `payment_id` is set, then we can use
// this directly for handling the event.
where: payment_id
? { key: payment_id }
: {
externalKey: id,
},
})
)[0]
);
const matchedStatus = matchExternalStatus(payment.status, service, status);
incrementMetric('payment_system.payment.external_event', {
status: matchedStatus,
external_status: status,
service,
action_by: actionBy,
});
return await create({
...payment,
status: matchedStatus,
processingState: PaymentProcessingState.UNPROCESSED,
externalKey: id,
externalStatus: status,
externalService: service,
eventData: {
id: event_id,
url: external_url,
metadata: metadata,
createdAt: new Date(created_at).toISOString(),
},
});
};
/**
* Handles an external event and process it.
*
* @param {ExternalPaymentEvent} paymentKey Payment key
* @param {string} actionBy Action executor
* @return {Promise<Payment>} The handled payment
*
* @async
* @function
* @memberOf module:payments/actions
* @access public
*/
const handleEvent =
tracer?.wrap('payments.handleEvent', internalHandleEvent) ||
internalHandleEvent;
export { handleEvent };