fix: make payment event reduction monotonic
Quality / quality (ubuntu-latest) (push) Failing after 9m53s
Quality / quality (windows-latest) (push) Canceled after 0s

This commit is contained in:
Clintchiz committed 2026-08-23 21:34:59 +05:30
1 parent 98e0813061
commit fe44bc2091
11 files changed
+458 -16

No files matched your search

+31 -1
View File
@@ -39,7 +39,35 @@ const gatewayFault = <T>(reason: string): PaymentResult<T> => ({
reason,
});
export function derivePaymentStatus(events: readonly PaymentEvent[]): PaymentStatus {
return events.at(-1)?.status ?? "created";
const ordered = [...events].sort((left, right) => {
if (left.sequence !== undefined && right.sequence !== undefined) {
const numeric = Number(left.sequence) - Number(right.sequence);
if (Number.isFinite(numeric) && numeric !== 0) return numeric;
const lexical = String(left.sequence).localeCompare(String(right.sequence));
if (lexical) return lexical;
}
return (
(left.occurredAt ?? left.at) - (right.occurredAt ?? right.at) ||
left.id.localeCompare(right.id)
);
});
let status: PaymentStatus = "created";
for (const event of ordered) {
if (status === "refunded") continue;
if (
status === "partially_refunded" &&
!["partially_refunded", "refunded"].includes(event.status)
)
continue;
if (
status === "captured" &&
["created", "pending", "authorized", "failed", "cancelled"].includes(event.status)
)
continue;
if (status === "authorized" && ["created", "pending"].includes(event.status)) continue;
status = event.status;
}
return status;
}
export function defineGateway<T extends PaymentGateway>(gateway: T): T {
if (!gateway.id.trim()) throw new Error("WRN-PAYMENT-GATEWAY: id is required");
@@ -269,6 +297,8 @@ export function definePayment(options: PaymentOptions) {
type: event.type,
status: event.status,
at: Date.now(),
occurredAt: event.occurredAt,
sequence: event.sequence,
payload: event.payload,
});
}