System Design: A Payment Gateway
Design a payment gateway with idempotency, double-entry ledgers, retries, and PCI considerations, balancing safety and throughput.
What you'll learn
- ✓Why payment systems are different
- ✓Designing a double-entry ledger
- ✓Idempotency and exactly-once charges
- ✓Retries, webhooks, and reconciliation
- ✓PCI scope reduction strategies
Prerequisites
- •Familiar with HTTP and databases
What and Why
Payments are unusual because mistakes cost money and trust. A duplicate charge is a customer service nightmare. A missing charge is lost revenue. The system must be correct under retries, network failures, and partial outages.
The job is not “talk to a card network.” That part is mostly delegated to a processor. The job is to model money movements safely and to expose a clean API to your product.
Mental Model
Two ideas drive every good payment design:
- Every state change is a journal entry. Money moves between accounts in pairs of debit and credit so the books always balance.
- Every external call carries an idempotency key so retries do not create duplicates.
Once these two ideas are internalized, the rest is structure.
Architecture
The API receives a charge request with an idempotency key. The orchestrator records an intent in the ledger as “pending,” calls the processor, and on response moves the intent to “succeeded” or “failed.”
Client -> API (idempotency key)
|
Orchestrator
|
+-------+-------+
v v
Ledger Processor
(pending) -> (charge) -> webhook
|
Orchestrator
|
Ledger (succeeded) The ledger is append-only. To compute a balance, sum entries up to a point in time. Snapshots speed this up; they are recomputable from the journal.
Webhooks from the processor confirm async state changes. They arrive duplicated, out of order, and sometimes never. A reconciliation job compares processor reports against the ledger nightly.
Trade-offs
A real-time view of balances costs more than a daily one. Most platforms expose an “available” balance that lags slightly and a “pending” balance that is best-effort.
Strong consistency in the ledger forces a single-writer per account. For very high-volume accounts (large merchants) you partition by sub-account to scale writes at the cost of more complex reporting.
PCI compliance is largely about scope. Forward card data straight to the processor via tokenization. Never let it touch your application servers and the scope shrinks dramatically.
Practical Tips
Persist the idempotency key with the request fingerprint. If the same key arrives with a different body, reject it. If the same key arrives with the same body, return the prior response.
Use a state machine for each payment with explicit transitions: created, authorized, captured, refunded, failed. Forbid backward transitions in code, not just in policy.
Build a reconciliation tool from day one. It will save you the first time the processor’s view and yours disagree, which will happen.
Log money amounts as integers in the smallest currency unit (cents, paise). Floating-point math has no place in a ledger.
Wrap-up
A payment gateway rewards discipline. Idempotency, double-entry ledger, state machines, and reconciliation are the four pillars. Get them right and the system stays correct even as the surface area grows. Get any one wrong and you will spend years cleaning up.
Related articles
- System Design System Design: Design a Payment System (Stripe-like)
Design a payment system like Stripe. Covers ledgers, idempotency, double-entry accounting, PCI scope, retries, and surviving downstream processor failures without double-charging.
- System Design CAP Theorem in Practice: What It Actually Means for Your System
A pragmatic look at the CAP theorem: what consistency and availability mean for real workloads, and how PACELC describes the trade-offs better.
- System Design Consistent Hashing Explained for Engineers Who Operate Real Systems
How consistent hashing actually works in production: virtual nodes, rebalancing, hot keys, and why naive modulo hashing fails at scale.
- System Design Designing Rate Limiters: A System Design Deep Dive
A senior-engineer guide to designing rate limiters: algorithms, distributed coordination, trade-offs, and production patterns that actually scale.