How does an idempotency key stop duplicate payments?
The client sends a unique key with each payment request. The server stores the key with the result; if the same key arrives again, it returns the saved result instead of charging again.
Explain it simply
You tap Pay in a shopping app, the network drops, and the screen hangs. You tap again. Without protection, you may be charged twice.
An idempotency key solves this. The client generates a unique value (a UUID) for each intended payment and sends it in a header such as Idempotency-Key. The same key is reused on retries of that same payment.
Server logic:
- Look up the key in a store.
- Not found: process the payment, save key plus response, return it.
- Found and finished: return the saved response, do no new work.
- Found and still running: return a conflict or wait, to handle two simultaneous retries.
Details that matter:
- Store key and result atomically with the payment (unique constraint on the key).
- Compare the request body too; same key with a different amount should be rejected.
- Expire keys after a window, such as 24 hours.
New intent means new key; retry of the same intent means the same key.
Example
POST /pay Idempotency-Key: 7f3a-c1 amount=499
-> key new -> charge 499 -> store {key, 200, receipt R1}
POST /pay Idempotency-Key: 7f3a-c1 amount=499 (retry)
-> key found -> return receipt R1, no second charge
POST /pay Idempotency-Key: 7f3a-c1 amount=999
-> 422: key reused with different payloadWhat to say in the interview
"The client sends a unique key per intended action and the server records the key with its outcome atomically. Retries get the stored response and never repeat the side effect. I also validate the payload, handle concurrent duplicates and expire keys after a window."