How do I stop a MonCash payment from being fulfilled twice?
poze 2 months ago656 gadeen
Sometimes an order gets marked paid twice and we ship twice: the customer refreshes the return page, and our background checker also finds the payment. How do I make fulfilment safe?
Dyagnostik IA
Se IA ki fè l. Se pa yon repons — kominote a anba a konfime oswa korije l. Toujou verifye anvan ou fye l.
1 Repons
Make "mark as paid" idempotent at the database level, not just in application code. Two requests arriving at the same moment will both pass an if (order.status !== 'PAID') check.
1. Store the MonCash transaction id with a unique constraint
ALTER TABLE payments ADD CONSTRAINT payments_moncash_tx_unique UNIQUE (moncash_transaction_id);
2. Transition the order with a conditional update
async function markPaidOnce(orderId: string, transactionId: string) {
return db.$transaction(async (tx) => {
// only one caller can move PENDING → PAID
const { count } = await tx.order.updateMany({
where: { id: orderId, status: "PENDING" },
data: { status: "PAID", paidAt: new Date() },
});
if (count === 0) return false; // someone else already did it
await tx.payment.create({ data: { orderId, provider: "MONCASH", moncashTransactionId: transactionId } });
return true;
});
}
Only the caller that gets true sends the confirmation email or ships. Everyone else just shows "already paid".
3. Use one orderId per payment attempt. If a customer abandons and retries, create a new attempt with its own id that links back to the order. MonCash rejects a duplicate orderId, and you get a clean audit trail.
Konekte pou di lòt moun si li te mache.
Sign in and verify your email to post an answer.