-
Payments
Add idempotency to payment operations
Makes retries, double-clicks, and webhook replays safe by deduping charge and refund operations.
Free Prompt
Add idempotency to every operation in my app that moves money or changes billing state: charge creation, refund creation, subscription changes, and webhook event processing.
Implement: the client generates a unique idempotency key per checkout attempt (a UUID created when the user starts checkout, reused if they retry or double-click the pay button), the server stores processed keys and returns the original result for repeat submissions instead of charging again, and the payment provider's own idempotency support is used on API calls (Stripe accepts an Idempotency-Key header; use it). For webhooks, record each processed event ID and skip ones already handled, since providers retry delivery and the same event arrives multiple times. Store keys and event IDs with the record they produced, and expire old keys after a sensible window (24-72 hours for checkout keys; keep webhook event IDs longer).
Don't dedupe so aggressively that legitimate separate purchases get merged; a key is per attempt, and a genuinely new checkout gets a new key. Don't rely on disabling the pay button as the defense; that's a hint, not a mechanism.
Deliver: each operation with its idempotency mechanism, the storage for keys and event IDs, and verification: submit the same payment request twice with the same key (one charge), replay a webhook event (processed once), and double-click the pay button (one charge).
What This Does / How This Helps
Makes every money operation safe to retry, so double-clicks, page refreshes, and webhook redeliveries can't create duplicate charges or refunds. Networks fail in the worst spot: the charge goes through but the response times out, so the code retries and charges again. Or the user clicks pay twice. Or Stripe redelivers a webhook and your handler grants access twice. Idempotency keys turn all of these into a single recorded operation. The verification covers the three classic duplicate paths: repeated request, replayed webhook, and the double-click.
Want to skip doing this by hand?
Fortivibe audits your app for all of the areas these prompts cover (and more).