Payment Processing System Design Walkthrough
Complete design walkthrough with animated diagrams, capacity math, API design, schema, and failure modes.
Solution PathTarget: 30 min
We designed a credit card processing system for 50M merchants handling 10K TPS at peak. A PostgreSQL UNIQUE constraint on idempotency_key guarantees exactly-once charging in one ACID transaction. Each transaction flows through a 5-state machine with no backward transitions. A double-entry ledger records every state change at 864M rows/day. Card network timeouts are resolved by T+1 reconciliation against settlement files, never by retrying. Webhooks retry with exponential backoff and a dead letter queue. The system achieves 99.99% availability with zero double charges.
1/10
1.
What is Payment Processing?
Stripe processes 250 million API requests per day, routing credit card charges through a chain of acquirers, card networks (Visa, Mastercard), and issuing banks. We are designing a payment processing gateway handling 10K transactions per second at peak.
The system sounds simple: accept a card number, charge it, return success. But the real challenge is the gap between our system and the card network.
When we send an authorization request to Visa and the network times out after 2 seconds, we do not know if the card was charged. Retrying would risk a double charge.
Not retrying might mean a lost payment. This tension between exactly-once semantics and unreliable external APIs is what makes payment processing one of the hardest system design problems.
Every design decision flows from this constraint.
250M API requests/day at Stripe scale. Two hard problems: exactly-once charging across unreliable external APIs + double-entry accounting where every cent is tracked twice.
Stripe processes 250 million API requests per day, routing credit card charges through a network of acquirers, card networks, and issuing banks. We are designing a payment processing gateway that handles 10K transactions per second where a network timeout between our gateway and Visa must never result in a double charge or a lost payment. The system sounds simple, but the real challenge is maintaining exactly-once semantics across unreliable external APIs while keeping a double-entry ledger that reconciles to the penny.
- Each transaction flows through 5 states (pending, authorized, captured, settled, failed) with no backward transitions
- Idempotency keys stored in a PostgreSQL UNIQUE constraint guarantee exactly-once processing at 10K TPS
- A double-entry ledger records every state change so every cent is accounted for in reconciliation
- Network timeouts with card networks are resolved by automatic reversal within 30 seconds