insight
Idempotency Is a Product Reliability Feature
Safe retries are not an implementation detail in payment and workflow APIs. They are part of the promise the product makes to users.
A client retries because it did not receive a trustworthy answer. The server may still have completed the original request. That uncertainty is exactly why a payment endpoint needs an idempotency contract.
Bind the key to the request
An idempotency key should not be reusable for a different payload. Storing a request hash with the key lets the API return a conflict when a caller accidentally changes the amount, currency, or other protected input.
Represent in-flight work
Two matching requests can arrive before the first one finishes. A reliable design marks the key as processing, coordinates concurrent callers, and returns or waits for the same eventual result. Simply checking a completed-response cache leaves a race window.
Replay the original outcome
Once processing completes, later retries should receive the stored status and response. A response header can make the replay visible without changing the business payload.
Expire intentionally
Keys need a documented lifetime. A TTL prevents unlimited growth, but it also defines how long the API promises duplicate protection. That is a product and risk decision, not merely a memory optimisation.
When idempotency is designed as an explicit state machine, users can retry safely and operators can explain exactly what happened.