Skip to content

Design a Payment System, stage 12 of 13: change it

100x volume and a second provider

The patterns hold. The question is what new pressure appears, and which tempting shortcuts would break the guarantees.

System so far· 8 parts
12345678910CLIENTBuyer's browserSERVICECheckout APIDATABASEPostgresEXTERNALPayment providerSERVICEWebhook receiverWORKERFulfillmentworkerEXTERNALEmail providerWORKERReconciler

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
  5. 5Payment provider → Webhook receiver: Signed events: at least once, unordered
  6. 6Webhook receiver → Postgres: Dedupe by event id; forward-only transition
  7. 7Fulfillment worker → Postgres: Claim outbox rows; record completion
  8. 8Fulfillment worker → Email provider: Send receipt with idempotency key
  9. 9Reconciler → Postgres: Attempts processing too long; ledger
  10. 10Reconciler → Payment provider: Look up by reference; settlement report
  • Request / response
  • Asynchronous

What you need to know

0 of 2 checks done
  1. Work it out

    Flash sales reach 5,000 orders a minute. About how many create-payment requests a second is that?
    per second