Why Did We Get Charged Twice? Designing Idempotency for Payments
Most double charges come from a timeout. The first request reaches the processor, the response gets lost, and the client retries, so the system charges again. The fix is a client-generated idempotency key, stored atomically with the first attempt and backed by a database uniqueness constraint. An optional distributed lock covers the check-then-create race. Before you trust it with real money, test deliberate replays, timeouts and concurrent duplicates.
