Payments
0-day streakReview

Your progress

Level 1

0 XP100 XP to level 2
0day streak
0best streak
0topics started
0cards reviewed
    Review cards

    Progress is stored only in this browser. No account is required.

    Design a payment system: the 60-second story

    Design a payment system

    You tap Pay. The reply never comes. Were you charged?

    The network keeps lying: replies vanish, customers tap twice, and webhooks land forty minutes late.

    3,000

    customers charged twice a day at 0.01%

    30 million payments a day at about ₹1,200 each is ₹3,600 crore of other people’s money. Correctness comes before availability.

    Two Pay requests arrive 20 ms apart

    Bad: Check, then charge

    Both read “not paid yet”, and both charge.

    Good: Key + unique constraint

    One insert wins. A duplicate gets 409 while it runs, then the saved response.

    Two keys, one charge

    The caller’s key K1 dedupes retries to your API. Your attempt ID att_9, committed before the call, dedupes the charge at the PSP.

    Your charge times out after 8 seconds. Never arrived? Declined? Succeeded, reply lost? All three look identical.

    The trick

    A timeout is an unknown, not a failure. Never retry blindly: ask the PSP about att_9.

    Retry on PSP B, and one order costs ₹2,499

    PSP B has never heard of PSP A, so no key helps. Ask PSP A first and you charge once, about ten seconds later.

    UPI: the customer pays in another app

    1. Get a upi://pay link from the PSP
    2. The customer enters their UPI PIN
    3. A signed webhook, not the app, brings the answer
    4. Your app long-polls for the result

    You marked att_15 failed. The PSP’s file says it was paid.

    Each morning, match attempts to settlement rows and batch totals to bank credits. Rules reinstate the order or refund late successes; people get the rest.

    Remember

    Key every call with an ID you committed first. A timeout is an unknown: ask, never guess. Then reconcile against files you didn’t write.