Skip to content

Design a Payment System, stage 7 of 13: decide

Who owns the idempotency key?

The key decides which requests count as "the same". If it is too broad, legitimate new attempts get the old answer. If it is too narrow, retries become new charges. A buyer whose card was declined must be able to pay with a different card. A buyer whose connection dropped must not pay twice.

System so far· 4 parts
1234CLIENTBuyer's browserSERVICECheckout APIDATABASEPostgresEXTERNALPayment provider

Select a component to see what it is responsible for and which state it owns.

  1. 1Buyer's browser → Payment provider: Card entry and 3-D Secure in hosted fields
  2. 2Buyer's browser → Checkout API: Pay (Idempotency-Key header); poll status
  3. 3Checkout API → Payment provider: Create payment with the attempt's key
  4. 4Checkout API → Postgres: Claim attempt; conditional transitions

What you need to know

0 of 2 checks done
  1. An idempotency key names an intent. Requests that are the same intent must share the key; a new intent must get a new one. Getting the scope wrong fails in one of two directions:

    • Too broad: different intents share a key, so a new attempt gets an old attempt's cached answer.
    • Too narrow: retries of one intent get different keys, so each retry is treated as new.
  2. Check

    The key is the order id. The buyer's card is declined and they enter a different card. What happens?