Never charge twice: Idempotency keys (Mock Interview Notes)
How to prevent payment double charges: why a timeout doesn't mean failure, why the common answers fail, the full idempotency key design, 409 vs 422, and the answer to the server-crash question.
By InternHack Team · · 8 min read · Interview Prep
The interview question: "The user tapped the Pay button twice, or the network retried the request. How do you make sure they aren't charged twice?"
This question comes up a lot in payments, fintech and backend interviews because it tests three things at once: how networks fail, race conditions, and database guarantees. And it's not just theory. In Dec 2024, staff on Zerodha's forum said some UPI AutoPay SIP debits were "processed twice by the sponsor bank" because of an issue at the payment aggregator. One retry, two debits, even at a big name.
In these notes: where the problem comes from, which answers are weak and why, the strong design step by step, the answer to the reel's last question ("the charge reached the bank, then the server crashed, now what?"), and a ready answer to give in the interview.
The problem isn't the button: a timeout doesn't mean failure
First, understand where duplicate requests come from. According to Stripe's engineering blog, a connection can break in three places:
- Before the request reaches the server
- While the server is doing the work
- After the work is done, but before the response reaches the client
In all three cases the client sees exactly the same thing: a timeout. It has no idea whether the money moved. Stripe's docs put it plainly: regaining connectivity doesn't tell you whether the original request succeeded. So the client retries, and if the charge endpoint runs twice, the customer is double charged.
Sources of duplicates:
- A user double-tapping, or tapping again out of frustration
- The SDK's automatic retries (the Stripe and AWS SDKs retry on their own)
- The app retrying after a mobile network drop
- Duplicate webhooks (on the incoming side)
Also remember the HTTP rule (RFC 9110): GET, PUT and DELETE are idempotent; POST is not. A client shouldn't automatically retry a non-idempotent request unless it knows the request is effectively idempotent. Making the payment POST idempotent is exactly today's job.
Idempotent means: send the same request N times, and the effect on the server is the same as sending it once.
Sign up free to unlock the full notes
Aage ke sections free InternHack account ke saath khulte hain:
- Weak answers that fail in interviews
- The strong design: idempotency keys, step by step
- The reel's last question: the charge reached the bank, then the server crashed. Now what?
- How to answer this in an interview
Sources
- Stripe engineering blog on idempotency (Brandur Leach, 22 Feb 2017): https://stripe.com/blog/idempotency
- Stripe docs, idempotent requests: https://docs.stripe.com/api/idempotent_requests
- Stripe docs, low-level error handling (409, replay, 24h retention): https://docs.stripe.com/error-low-level
- Brandur Leach, "Implementing Stripe-like idempotency keys in Postgres": https://brandur.org/idempotency-keys
- IETF draft, The Idempotency-Key HTTP Header Field (409, 422): https://datatracker.ietf.org/doc/draft-ietf-httpapi-idempotency-key-header/
- AWS Builders' Library, "Making retries safe with idempotent APIs": https://aws.amazon.com/builders-library/making-retries-safe-with-idempotent-APIs/
- RFC 9110, section 9.2.2 (idempotent methods): https://www.rfc-editor.org/rfc/rfc9110#section-9.2.2
- PostgreSQL docs, INSERT ... ON CONFLICT: https://www.postgresql.org/docs/current/sql-insert.html
- Redis docs, SET with NX: https://redis.io/docs/latest/commands/set/
- Razorpay payouts idempotency (X-Payout-Idempotency): https://razorpay.com/docs/api/x/payout-idempotency/
- Razorpay Orders (one successful payment per order): https://razorpay.com/docs/payments/orders/
- PayPal idempotency (PayPal-Request-Id): https://developer.paypal.com/api/rest/reference/idempotency/
- Gunnar Morling, "On idempotency keys" (exactly-once processing): https://www.morling.dev/blog/on-idempotency-keys/
- Zerodha forum, UPI AutoPay double debit (Dec 2024): https://tradingqna.com/t/introducing-upi-autopay-for-sip-payments/173064?page=4
- NPCI UPI status-check rules (via MediaNama): https://www.medianama.com/2025/04/223-npci-new-guidelines-upi-outage/