mirror of
https://github.com/Tria-plc/edr-platform.git
synced 2026-08-28 11:21:18 +00:00
67 lines
2.0 KiB
TypeScript
67 lines
2.0 KiB
TypeScript
import { randomUUID } from "node:crypto";
|
|
import {
|
|
PaymentEvent,
|
|
PaymentFailedEvent,
|
|
PaymentSucceededEvent,
|
|
} from "@edr/types";
|
|
import { PaymentIntent } from "../intents/entities/payment-intent.entity";
|
|
import { NotificationOutbox } from "./entities/notification-outbox.entity";
|
|
|
|
/**
|
|
* Build a ready-to-insert outbox row for a terminal intent. Pure (no DI) so the intents
|
|
* state machine can insert it inside its own DB transaction without a module cycle.
|
|
* The row id is generated here because the event envelope embeds it as `eventId`.
|
|
*/
|
|
export function buildOutboxRow(
|
|
intent: PaymentIntent,
|
|
terminal:
|
|
| { eventType: "payment.succeeded"; providerTxnId?: string; paidAt: Date }
|
|
| {
|
|
eventType: "payment.failed";
|
|
failureCode?: string;
|
|
failureMessage?: string;
|
|
},
|
|
): Partial<NotificationOutbox> {
|
|
const id = randomUUID();
|
|
const base = {
|
|
version: 1 as const,
|
|
eventId: id,
|
|
occurredAt: new Date().toISOString(),
|
|
service: intent.service,
|
|
intentId: intent.id,
|
|
referenceType: intent.referenceType,
|
|
referenceId: intent.referenceId,
|
|
merchantOrderId: intent.merchantOrderId,
|
|
provider: intent.provider,
|
|
amountMinor: intent.amountMinor,
|
|
currency: intent.currency,
|
|
};
|
|
|
|
const event: PaymentEvent =
|
|
terminal.eventType === "payment.succeeded"
|
|
? ({
|
|
...base,
|
|
eventType: "payment.succeeded",
|
|
providerTxnId: terminal.providerTxnId,
|
|
paidAt: terminal.paidAt.toISOString(),
|
|
} satisfies PaymentSucceededEvent)
|
|
: ({
|
|
...base,
|
|
eventType: "payment.failed",
|
|
failureCode: terminal.failureCode,
|
|
failureMessage: terminal.failureMessage,
|
|
} satisfies PaymentFailedEvent);
|
|
|
|
return {
|
|
id,
|
|
eventType: event.eventType,
|
|
service: intent.service,
|
|
intentId: intent.id,
|
|
referenceType: intent.referenceType,
|
|
referenceId: intent.referenceId,
|
|
payload: event,
|
|
status: "PENDING",
|
|
attempts: 0,
|
|
};
|
|
}
|