Skip to main content
SDMastery
medium7 min readUpdated 2026-10-03

Design a Payment System

Design a payment system for interviews: payment flow, idempotency keys, ledger data model, retries, reconciliation, fraud checks, scaling, and tradeoffs.

Quick answer: Design a Payment System

Design a Payment System is covered here as a practical system design interview problem. Design a payment system for interviews: payment flow, idempotency keys, ledger data model, retries, reconciliation, fraud checks, scaling, and tradeoffs. Use it to practice requirements, APIs, storage choices, scaling bottlenecks, data consistency, observability, and failure handling for a medium interview round.

Focus on the problem being solved, the main design choice, the failure mode, and the tradeoff you would defend in front of a senior engineer. This page is part of the DosiBridge system design knowledge graph, so it links related concepts, interview problems, tradeoffs, and references instead of leaving the topic isolated.

Diagram showing the key components and data flow in a Design Payment System system design
High-level overview of Design Payment System

Problem Statement

Design a Payment System as a scarce or money-moving workflow where duplicate writes and race conditions are more dangerous than slow responses. For Design a Payment System, name the critical user action, the data that must remain correct, and the first bottleneck that appears when traffic grows.

Deep-Dive: Clarifying Questions for Payment System

  1. What payment methods? Credit/debit cards (Visa, Mastercard), bank transfers (ACH), digital wallets (Apple Pay, Google Pay), cryptocurrency? Each has different processing pipelines and settlement times.
  2. What is the transaction volume? Stripe processes billions of dollars per year. PayPal handles ~40 million transactions per day. Visa processes 65,000 transactions per second at peak.
  3. How do we prevent double-charging? Idempotency is non-negotiable. If a client retries a payment request (due to timeout), the system must guarantee the payment is processed exactly once.
  4. How do we handle refunds? Partial refunds, full refunds, and time-limited refund windows (e.g., 180 days for chargebacks).
  5. What compliance requirements? PCI DSS for card data, SOX for financial reporting, PSD2/SCA for European payments. These are not optional — they are legal requirements.
  6. How do we handle currency? Multi-currency support with real-time exchange rates. Never use floating-point for money — use integers (cents) or decimal types.

Specific Functional Requirements

  1. Payment Processing: Accept payments via multiple methods (card, bank transfer, wallet) with real-time authorization
  2. Idempotent Transactions: Every payment request includes an idempotency key to prevent duplicate charges
  3. Refunds: Support full and partial refunds with audit trail
  4. Ledger: Double-entry bookkeeping ledger recording every financial movement (debits and credits must always balance)
  5. Fraud Detection: Real-time scoring of transactions using ML models (velocity checks, geographic anomalies, device fingerprinting)
  6. Settlement: Batch settlement with payment processors and bank accounts on a daily/weekly schedule
  7. Webhooks: Notify merchants of payment events (succeeded, failed, refunded, disputed)

Specific API Endpoints

text
POST /api/v1/payments
  Headers: { "Idempotency-Key": "unique_request_id_abc123" }
  Body: { "amount": 2999, "currency": "usd", "payment_method_id": "pm_card_visa", "merchant_id": "m_456", "metadata": { "order_id": "ord_789" } }
  Response: { "payment_id": "pay_abc", "status": "succeeded", "amount": 2999, "currency": "usd", "created_at": "..." }

POST /api/v1/refunds
  Headers: { "Idempotency-Key": "refund_req_xyz" }
  Body: { "payment_id": "pay_abc", "amount": 1500, "reason": "customer_request" }
  Response: { "refund_id": "ref_def", "status": "pending", "amount": 1500 }

GET /api/v1/payments/:payment_id
  Response: { "payment_id": "pay_abc", "status": "succeeded", "amount": 2999, "refunds": [...], "timeline": [...] }

GET /api/v1/ledger/balance?merchant_id=m_456&currency=usd
  Response: { "available": 150000, "pending": 25000, "currency": "usd" }
Comparison table for Design Payment System contrasting approaches, tradeoffs, and when to use each
Comparing key aspects of Design Payment System

Specific Data Model

Payments (PostgreSQL — strong consistency required)

ColumnTypeNotes
payment_idUUIDPrimary key
idempotency_keyVARCHAR(255)UNIQUE — prevents duplicate processing
merchant_idVARCHAR
amountBIGINTIn smallest currency unit (cents) — NEVER use float
currencyVARCHAR(3)ISO 4217 code
statusENUMpending, authorized, captured, failed, refunded
payment_methodJSONBTokenized card/bank details (never store raw card numbers)
created_atTIMESTAMP
updated_atTIMESTAMP

Ledger Entries (PostgreSQL — append-only, double-entry)

ColumnTypeNotes
entry_idUUIDPrimary key
payment_idUUIDReference
account_idVARCHARWhich account (merchant, platform, reserve)
typeENUMdebit, credit
amountBIGINTAlways positive; direction determined by type
balance_afterBIGINTRunning balance for reconciliation
created_atTIMESTAMPImmutable — ledger entries are never updated or deleted

Idempotency Store (Redis + PostgreSQL): Redis for fast lookup (TTL: 24 hours), PostgreSQL for persistence. Key = idempotency_key, Value = payment_id + response. If a duplicate request arrives, return the stored response without reprocessing.

Specific Back-of-the-Envelope Numbers

Component diagram for Design Payment System showing each building block and its responsibility
Key components of Design Payment System

Traffic (Stripe-scale):

  • ~100M transactions/day = ~1,200 transactions/second average, 5,000/second peak
  • Each transaction: 1 write (payment record) + 2 ledger entries (debit + credit) + 1 webhook = 4 DB operations
  • Database write rate: ~5,000 writes/second at peak

Storage:

  • Payment records: 100M/day * 500 bytes = 50 GB/day = 18 TB/year
  • Ledger entries: 200M/day * 200 bytes = 40 GB/day = 14.5 TB/year
  • Must retain financial records for 7+ years (regulatory) = 100+ TB of historical data

Latency targets:

  • Payment authorization: under 2 seconds end-to-end (includes network call to card network)
  • Idempotency check: under 5ms (Redis lookup)
  • Webhook delivery: within 30 seconds of event

Availability:

  • Payment systems target 99.999% availability (5.26 min downtime/year)
  • Every second of downtime = lost revenue for merchants
  • Requires active-active deployment across multiple regions with automatic failover

Original DosiBridge notes for Design a Payment System

This section is written specifically for this page, not copied from a general system-design checklist. The useful way to study Design a Payment System is to connect the concept to a scarce or money-moving workflow where duplicate writes and race conditions are more dangerous than slow responses. That framing changes the design discussion from definitions to operating choices.

What makes this topic distinct

  • Core Entity: For Design a Payment System, decide the core entity before choosing tools; otherwise the design looks clean but fails when payment changes.
  • Read/Write Path: For Design a Payment System, decide the read/write path before choosing tools; otherwise the design looks clean but fails when system changes.
  • Contention Point: For Design a Payment System, decide the contention point before choosing tools; otherwise the design looks clean but fails when payment changes.
  • Abuse Path: For Design a Payment System, decide the abuse path before choosing tools; otherwise the design looks clean but fails when system changes.
  • Recovery Workflow: For Design a Payment System, decide the recovery workflow before choosing tools; otherwise the design looks clean but fails when payment changes.

Design a Payment System correctness boundary

For this problem, separate the user-visible action from background work. The correctness boundary is the smallest state transition that must not be duplicated, lost, or reordered. Naming that boundary makes the solution more original than a stock API/database/cache template.

Design a Payment System scaling bottleneck

The first bottleneck should be described in the language of this system: a hot timeline, a contested seat, a busy wallet ledger, a media-processing queue, or a search index update delay. That bottleneck decides which component deserves the deepest interview discussion.

Production review question

If Design a Payment System suddenly receives 10x traffic, which entity becomes contested first, and what queue, lock, shard, or cache protects that entity without hiding correctness bugs?

Practical metric to track

Track payment-system health as a named dashboard or review item: combine one user-facing metric, one saturation metric, and one correctness metric. For Design a Payment System, this keeps the discussion grounded in behavior that can be measured after deployment instead of generic advice that sounds good in an interview but never gets verified.

Sources