import { AppError } from '../common/errors/app-error'; import type { CapturedPayment } from './gateway.contract'; export interface ExpectedPayment { orderId: string; paymentId: string; amountMinor: string; currency: string; expiresAt: Date; cancelled: boolean; alreadyCaptured: boolean; } export function captureDecision( expected: ExpectedPayment, event: CapturedPayment, now: Date, ) { if ( event.orderId !== expected.orderId || event.paymentId !== expected.paymentId ) throw new AppError('PAYMENT_REFERENCE_MISMATCH'); if (event.currency !== expected.currency) throw new AppError('PAYMENT_CURRENCY_MISMATCH'); if (event.amountMinor !== expected.amountMinor) throw new AppError('PAYMENT_AMOUNT_MISMATCH'); if (expected.alreadyCaptured) return 'DUPLICATE' as const; if (expected.cancelled || expected.expiresAt <= now) return 'REVIEW_AND_REFUND' as const; return 'COMMIT_RESERVED_STOCK' as const; } export function refundAmount( captured: bigint, completed: bigint, pending: bigint, requested: bigint, ) { if ( [captured, completed, pending].some((value) => value < 0n) || requested <= 0n || completed + pending + requested > captured ) throw new AppError('REFUND_AMOUNT_INVALID'); return requested.toString(); }