Generate idempotency keys as UUID v4 strings tied to the logical payment attempt identity (e.g., hash of order_id + attempt_number) rather than random values
Store the idempotency key alongside the payment attempt record in your database before making the Stripe API call
On a network timeout or 5xx response, retry the exact same API call with the same idempotency key; do not generate a new key until you have confirmed the previous attempt's outcome
Handle the case where Stripe returns a 409 Conflict with error code idempotency_key_in_use, indicating a concurrent request with the same key is in flight; back off and retry after a short delay
After a successful response, do not reuse the idempotency key for a different payment even if the parameters are different; Stripe returns the cached result for 24 hours
After 24 hours, Stripe considers the key expired; use a new key for a retry on the following day
Known gotchas
Changing any request parameter while reusing the same idempotency key causes Stripe to return a 400 Bad Request with error code idempotency_key_mismatch; this can cause false negatives in retry logic
Idempotency keys are scoped to the API mode (live vs test) and the specific API endpoint; the same key can be used independently on different endpoints
Do not rely solely on idempotency keys for deduplication; implement your own duplicate detection using Stripe event IDs in your webhook handler since webhooks have no idempotency key concept
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