</> MAANG.io

Expert

Design landmark systems in depth, from Dynamo, GFS, Bigtable and Kafka to payments and ads pipelines.

0 of 232 solved 0%

Section 3: The Contract Before the Boxes - API Design & High-Level Architecture

Executive Summary: Section 2 fixed the numbers: ~1,200 checkouts/s at peak, ~1,500 authorization calls/s to the PSP, 3,500 journal transactions/s at the ledger. This section writes the contract first, as resources (PaymentIntent, Capture, Refund, Payout, Balance, Statement) carrying integer minor-unit amounts, with an Idempotency-Key on every mutating call. Three interviewer pushbacks test it: one /pay call, client-supplied splits, and returning 200 when the PSP times out. Then we draw the services behind it and split them along one line. Anything that makes a claim about money is synchronous and strongly consistent. Anything that only shows money is asynchronous and fed from the outbox.

The interviewer caps the marker. "Numbers are fixed. Before you draw a box, what does a client actually call?" Starting with the API is the right instinct. Payments is a domain where the contract outlives every implementation behind it, and a wrong verb in v1 becomes a migration you're still running three years later.

Resources, Not Verbs

The API models the nouns of money movement, each with its own lifecycle and its own creator:

Resource Created by When What it represents
PaymentIntent Checkout (buyer's session) At checkout One cart, one card, one authorization; carries server-computed per-seller splits
Capture Fulfilment service When a seller sub-order ships Money actually taken, for one seller's portion
Refund Support / seller tools After a capture Money flowing back, against a specific capture
Payout Payout scheduler Daily batch A transfer of a seller's available funds to their bank
Balance Derived Read-only A seller's pending, available and reserved amounts
Statement Derived Read-only Line items explaining every balance change

Three conventions run through every endpoint. Amounts are int64 minor units plus an ISO currency (D6): Maya's cart is 12000 with usd, never 120.00 as a float. Every mutating call carries an Idempotency-Key, stored with a request fingerprint in the same database transaction as the effect (D10, the full mechanics are in Section 8). And no amount the server can compute is accepted from the client.

Here is Maya's checkout for ord_7Q2, Lantern & Loom's $80 lamp and Copperleaf Tea's $40 tea set:

POST /v1/payment_intents
Idempotency-Key: 9f1c…
{ "order_id": "ord_7Q2", "payment_method": "pm_tok_4b…" }

201 Created
{
  "id": "pi_7Q2",
  "status": "requires_confirmation",
  "amount": 12000, "currency": "usd",
  "splits": [
    { "seller_id": "lantern_loom",  "amount": 8000, "commission": 960 },
    { "seller_id": "copperleaf_tea", "amount": 4000, "commission": 480 }
  ]
}

The request names an order and a card token. That's all it carries. The 12000, the two splits and the 12% commissions ($9.60 and $4.80) come from the Order service's priced cart. The pm_tok_ value comes from the PSP's hosted fields, so a card number never reaches us (D15, Section 10). Maya then confirms with POST /v1/payment_intents/pi_7Q2/confirm, which triggers the authorization.

The rest of the surface is small:

Endpoint Caller Notes
POST /v1/payment_intents/{id}/confirm Buyer client Authorizes the full cart; returns authorized, requires_action (3-D Secure), processing or failed
POST /v1/payment_intents/{id}/captures Fulfilment (internal) {seller_id, amount}; one per seller sub-order at shipment
POST /v1/refunds Support, seller tools {capture_id, amount}; validated against what was captured
GET /v1/balance, GET /v1/statements, GET /v1/payouts Seller dashboard Scoped to the caller's seller id; served from projections

Quick check before moving on:


Sign in to continue reading

The rest of this lesson is available with a free account. Signing in with Google or Microsoft is free.

Sign in to read the full lesson

Sign in to MAANG.io

Use your Google or Microsoft account — no password to remember.

Continue with Google Continue with Microsoft

Please accept the terms above to continue.