Interview prep notes

linkjobai revised this gist 8 hours ago · a9ac6a8

1 file changed, 48 insertions

payment.md (file created)
@@ -0,0 +1,48 @@
1 + # System Design Interview: Designing a Payment System
2 +
3 + "Design a payment system like Stripe checkout" is less about scale and more about correctness: money must never be charged twice or lost.
4 +
5 + ## Requirements
6 +
7 + - A customer pays for an order with a card; the merchant sees a final status (succeeded, failed).
8 + - Exactly-once charging from the user's point of view, even with retries and timeouts.
9 + - An auditable record of every money movement.
10 + - Scale is modest (a few thousand payments per second at peak), so correctness dominates.
11 +
12 + ## Core components
13 +
14 + 1. **Payment service**: accepts a payment request, stores a `payment` row in `PENDING`, and calls the payment service provider (PSP).
15 + 2. **PSP adapter**: talks to the card processor; never stores raw card numbers (the PSP's hosted form tokenizes them, which keeps you out of most PCI scope).
16 + 3. **Ledger**: an append-only, double-entry table. Each payment writes balanced debit and credit entries, so the books always sum to zero.
17 + 4. **Wallet / balance service**: merchant balances derived from the ledger.
18 + 5. **Reconciliation job**: compares the PSP's daily settlement file against your ledger and flags mismatches.
19 +
20 + ## Idempotency is the key idea
21 +
22 + The client sends an **idempotency key** (for example the order ID) with every request. The payment service stores it with a unique constraint:
23 +
24 + - First request: insert the key, process the payment, store the result.
25 + - Retry with the same key: return the stored result instead of charging again.
26 +
27 + Pass the same key through to the PSP so its side is idempotent too.
28 +
29 + ## Handling timeouts
30 +
31 + If the PSP call times out you don't know whether the charge happened. Don't retry blindly:
32 +
33 + - Keep the payment in `PENDING`.
34 + - Query the PSP for the status, or wait for its webhook.
35 + - Only mark `FAILED` when the PSP confirms it.
36 +
37 + ## Consistency between services
38 +
39 + Writing the payment row and publishing an event to other services should use the **outbox pattern**: write the event into an outbox table in the same database transaction, then a relay publishes it. This avoids "charged but order never updated".
40 +
41 + ## Follow-ups interviewers like
42 +
43 + - **Refunds**: a new ledger entry that reverses the original, never an edit.
44 + - **Currency**: store amounts as integer minor units (cents) plus a currency code, never floats.
45 + - **Fraud checks**: a risk service before authorization, with rules plus a score.
46 +
47 + ---
48 + *Disclosure: I'm part of the team at [Linkjob AI](https://www.linkjob.ai/), an AI interview assistant.*