Back to System Design
System Design
Payment system
Senior level · full staged walkthrough
Senior
Architecture
SeniorClientEdgeDataAsyncService
Solution, step by step
- 1
Functional requirements
- Charge customers reliably
- Refunds and disputes
- Audit trail & reconciliation
- Multi-currency (optional)
- 2
Non-functional requirements
- Exactly-once financial effect (idempotency)
- Strong consistency for balances
- Full auditability/immutability
- PCI scope minimized
- 3
Capacity & estimation
- 10K payments/s peak → ledger writes must keep up
- Each charge = several ledger entries → ~50K writes/s
- Idempotency keys retained for days–weeks
- Reconciliation batches: millions of records/day
- 4
Preliminary design
- Idempotency key per charge
- Double-entry ledger
- Outbox + async provider calls; reconcile via webhooks
- 5
Final architecture
- Payment API enforces idempotency keys (dedup retries)
- Double-entry ledger as the source of truth; append-only
- Transactional outbox → provider calls (no dual-write race)
- Webhook handler confirms/settles; reconciliation job catches gaps
- Tokenize cards via a PCI-compliant vault to shrink scope
Interview Q&A (8)
Require an idempotency key per charge; the API dedupes retries against it so a network retry never double-charges.
Key components
- Payment API
- Ledger service
- Provider adapter
- Webhook handler
- Reconciliation job
Bottlenecks & how to address them
- Ledger write contention → partition by account, batch
- Provider latency → async capture
- Hot accounts → sharding
Tradeoffs to articulate
- Strong consistency for money vs throughput
- Sync vs async capture
- Storing PII/PCI scope
Where this content comes from
For full transparency, this content is curated and verified from these sources:
Published architecture case studiesCompany engineering blogsOppZen design rubric library