{
  "id": 12393184,
  "title": "Why Your Payment Got Charged Twice: Idempotency Keys Explained",
  "url": "https://urgent.news/2026/10/06/why-your-payment-got-charged-twice-idempotency-keys-explained",
  "topic": "tech",
  "section": "Tech",
  "published": "2026-10-06T14:15:06.000Z",
  "source": {
    "name": "Dev.to",
    "slug": "dev-to",
    "url": "https://dev.to/system_design_lab/why-your-payment-got-charged-twice-idempotency-keys-explained-2kcm"
  },
  "original_language": "en",
  "account": "When you use a payment app, like Maya tapping Pay for a $20 ride, there's a risk the request can time out and be retried. This can sometimes lead to being charged twice. Stripe's solution involves using idempotency keys. An idempotent operation is one that can be performed multiple times without changing the outcome beyond the initial application.\n\nFor payments, this means if a request is retried, it should have the same effect as the first request. To achieve this, a unique string called an idempotency key is included in the request. The client creates this key, which becomes the identifier for the request. Stripe then stores the server's response to this key. If the same key is sent again, the server returns the saved response, ensuring the transaction isn't duplicated.\n\nIf a request fails in the middle and crashes, the server will remember the progress thanks to the idempotency key. This ensures the client isn't charged twice. However, this system has its challenges. For instance, if two retries occur simultaneously with the same key, one will wait while the other completes its task, preventing duplication.\n\nTo avoid hammering the system with retries, Stripe uses an exponential backoff strategy, which involves waiting longer between retries. Additionally, random delays or 'jitter' are added to the wait times to prevent all retries from occurring at the same time.\n\nIn summary, idempotency keys play a crucial role in ensuring that payment requests are safe to retry without causing double charges. This mechanism allows the server to remember the result of a request and return it on subsequent retries, ensuring consistency and reliability in the payment process.",
  "summary": "Maya taps Pay for a $20 ride. Ten seconds later: request timed out. The app retries, and Maya gets charged $40 . The retry went through. So did the first attempt. The first request never failed: it worked perfectly, and the answer just never made it back. Stripe's fix for this is one extra header on the request, a random string called an idempotency key . This post walks through how it works and…",
  "key_points": [
    "Idempotent operations can be repeated without changing outcome beyond initial application",
    "Idempotency keys are unique strings included in payment requests to prevent duplication",
    "Server stores response to idempotency key; same key triggers returning saved response"
  ],
  "editors_take": null,
  "illustration": null,
  "coverage": {
    "outlets": 1,
    "also_reported_by": []
  },
  "ai_generated": true,
  "disclaimer": "Summaries, key points and the editor’s take are written by software from other outlets’ reporting and may contain errors — always check the linked original."
}