Understand that Stripe caches idempotency key results for 24 hours after the first successful request; after expiry, reusing the same key with different parameters will create a new request rather than returning a cached result.
Generate idempotency keys that are globally unique per logical payment attempt: incorporate customer ID, order ID, and attempt number to avoid accidental collisions across retries for different orders.
Handle the 'IdempotencyError' (status 422) that Stripe returns when an idempotency key is reused within the cache window with different request parameters — log and alert on this, as it indicates a key-generation bug.
For asynchronous job queues, bind the idempotency key to the job ID rather than generating a fresh key on each dequeue, ensuring that redelivered jobs do not create duplicate charges.
After a network timeout (no HTTP response received), always retry with the original idempotency key rather than generating a new one — this is the primary protection against double-charges.
Periodically audit your idempotency key generation logic in load tests to confirm uniqueness under concurrent request conditions.
Known gotchas
The 24-hour idempotency cache window means that a job delayed by more than 24 hours and retried with the original key will result in a new charge rather than a cached no-op — consider whether your retry windows exceed this.
Idempotency keys are scoped to your Stripe API key; using the same key across multiple Stripe accounts (e.g., in a Connect platform) does not prevent duplicate charges on different connected accounts.
Stripe does not guarantee idempotency for list or read endpoints — only mutating API calls (POST) carry idempotency semantics; do not rely on idempotency keys for GET requests.
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