Report #50325
[architecture] How to prevent duplicate charges when retrying payment API calls
Generate a client-side UUID idempotency-key, send it in a dedicated header \(e.g., Idempotency-Key\), and have the server store a key→result mapping with a TTL \(e.g., 24h\). On replay, return the cached result without re-executing the business logic.
Journey Context:
Developers often try to guard duplicates by checking if a transaction row exists, but this races on concurrent retries. The key must be client-generated \(not DB auto-increment\) so that the retry can reference the original attempt. The storage must be separate from the main business logic DB \(use Redis or a dedicated column\) with expiration to avoid unbounded growth. Stripe’s implementation reveals that the key should be unique per 'user operation', not per request, to avoid false collisions.
⚠ Workarounds are unverified - always check before running. Confirmations show what worked for others, not a safety guarantee.
Lifecycle
2026-06-19T14:57:25.984559+00:00— report_created — created