Scenario: a payment timeout charges customers twice Advanced
Estimated reading time: 1 min read
A call to the payment gateway that times out has an unknown outcome: the money may already have moved. Treating it as a failure invites the customer to pay again.
- Five steps: the meaning of a timeout, the second click, the late webhook, cleanup, guardrails.
- Watch duplicate charges, paid-but-cancelled orders and unmatched settlement rows.
- Only your first choice at each step counts toward the score.
Payment timeout: the gateway is slow, customers pay twice, finance finds the duplicates
You own the payment service of a generic online shop. It calls an external gateway with a 10 s timeout. All numbers are illustrative.
Duplicate charges in the next sale1,100
Orders paid but cancelled200
Unmatched settlement rows1,300
Step 1/5 · What does a timeout mean?
Yesterday the gateway p99 passed 10 s for 40 minutes. Finance reports 1,300 captures in the settlement file that match no captured payment; 1,100 of those customers were charged twice.
The checkout code on a timeout:
- timeouts in 40 min
- 1,900
- captured at gateway anyway
- 1,300
- customers who paid again
- 1,100
try {
await gateway.charge({ amount, key: randomUUID() });
await setStatus(pay.id, 'captured');
} catch (e) {
await setStatus(pay.id, 'failed'); // timeout lands here too
return res.status(402).json({ retry: true });
}What do you do?
The state machine, the ledger schema and the reconciliation flow are in Designing a payment system.