Payment Idempotency Keys: One Charge Despite Nine Identical Requests
Payment Idempotency Keys: One Charge Despite Nine Identical Requests
Source: https://x.com/i/status/2081224042372325856
📌 An idempotency key lets clients retry the same payment safely: the server treats the key as the operation’s identity, charges once, and replays the stored result for every later request with that key. This stops double billing from timeouts, double taps, and gateway retries without needing long-lived locks.
🔑 What an idempotency key is
The client generates a unique id for one logical payment. Same key + same payload means: do not charge again—return the prior result.
🔄 Why the same request arrives nine times
Timeouts, flaky networks, double taps, load balancers, and payment-gateway retries freely re-send the same request. Without idempotency, each retry can bill again.
🛡️ How the server stops the other eight
Insert or look up a row keyed by the idempotency key (often with a unique DB constraint). Only the first writer processes the charge; others get the cached response or a still-processing signal.
💾 Decide once, store, replay
Side effects (the money move) happen once; responses can be repeated safely. You need a durable map from key to first result—not a forever lock or global queue.
⚠️ Failure modes to avoid
Reject the same key with a different body. Always persist the outcome; if you never save the result, retries can still double-charge.
Key facts
| Fact | Value |
|---|---|
| Idempotency key | Client-generated unique id for one logical payment; same key + same payload means return prior result, do not charge again. |
| Why retries happen | Timeouts, client double-submit, load balancers, and payment-gateway retries can deliver the same request many times. |
| What stops the other eight | Server-side check of the key against stored outcomes—not a separate lock service or job queue for every request. |
| Typical storage pattern | Unique constraint / insert-or-lookup on the key; first writer processes; others get the cached response or a still-processing signal. |
| Failure mode to avoid | Reusing the same key with a different body (should be rejected) or never persisting the result (retries can double-charge). |
| Business impact | Prevents double charges and support disputes while keeping payment APIs safe to retry over unreliable networks. |
Details
A common production and interview problem: the same payment request arrives many times—same body, same headers, same client-supplied key—yet the customer must be charged only once. The mechanism is an idempotency key. The client generates a unique key for one logical payment; the server treats that key as the identity of the operation. The first successful processing records the outcome under that key; every later request with the same key returns the stored result instead of running the charge again.
This matters because networks, browsers, and mobile apps retry freely. Distributed locks and queues can serialize work, but they are heavier and can fail under contention; payment APIs usually do not rely on holding a lock forever. Idempotency is a decide-once, store-result, replay-forever design: the money move happens once; responses can be repeated safely.
In practice the server inserts or looks up a row keyed by the idempotency key (often with a unique database constraint), processes only if it is first, then saves the HTTP response or payment id and status for reuse. Concurrent duplicates either lose the race and wait/replay, or hit the unique key and return the same outcome. Stripe-style Idempotency-Key headers expose this so clients can retry without fear of double billing. The interview gotcha is realizing you do not need a long-lived lock or a global queue—you need a durable map from key to first result.
Sources
- I watched a senior candidate freeze on this one (payment request nine times)
- Design An Idempotent Payment API — Exactly-Once, No Double Charges
- How Stripe Prevents Double Payment Using Idempotent API
- Ensuring Reliable Payment Systems with Idempotency
- Idempotency Keys in Payment API Design
- Payment Gateway System Design - Part 1: Idempotence