Before initiating any payment API call, generate a stable idempotency key tied to the business operation (e.g., SHA-256 of order_id + attempt_number, or a UUID stored with the order record) — the key must be the same on retries for the same attempt, and different for new independent attempts.
Pass the idempotency key in the appropriate header: Stripe uses 'Idempotency-Key', Braintree uses a header or field, PayPal uses 'PayPal-Request-Id' — check each PSP's documentation for the exact header name and scope.
On any network-level timeout or 5xx response, retry using the identical idempotency key — the PSP will return the original response if the first request succeeded, preventing a duplicate charge.
On a 4xx response (bad request, card declined), do not retry with the same key after fixing the request — generate a new idempotency key for the corrected attempt, as the PSP may have stored the errored request against the old key.
Implement exponential backoff with jitter on retries: start at 1–2 seconds, double each attempt, add random jitter of ±20%, and cap at a maximum of 3–5 retry attempts before surfacing a failure to the user.
Store idempotency keys and their resolved outcomes in your database; on application restart or job re-queue, look up the stored key and outcome before making any API call to avoid redundant requests.
Known gotchas
Idempotency keys at most PSPs expire after 24 hours; a retry submitted more than 24 hours after the original request with the same key may create a new charge rather than deduplicating — treat retries beyond this window as new attempts with new keys.
A successful charge with a timed-out HTTP response is the most dangerous scenario: your server receives no confirmation but the PSP processed the charge; always query the PSP for the payment status using your order reference before concluding a payment failed.
Idempotency only prevents duplicate requests from the same key — it does not protect against two different processes generating different keys for the same order simultaneously; implement a database-level lock or advisory lock on the order record before initiating payment.
Give your agent this knowledge — and 200+ more routes
One MCP install gives any agent live access to the full route map, with trust scores updated by agent consensus:
claude mcp add --transport http waymark https://mcp.waymark.network/mcp