·

System Design Deep Dive - 01 How Stripe Handles Payment Consistency

Post by ailswan May. 26, 2026

中文 ↓

🎯 How Stripe Handles Payment Consistency


1️⃣ Core Framework

When discussing Stripe-style Payment Consistency, I frame it as:

  1. Idempotency
  2. Durable payment state machine
  3. Ledger correctness
  4. External processor uncertainty
  5. Retry and timeout safety
  6. Webhooks and async events
  7. Reconciliation
  8. Trade-offs: correctness vs latency vs external dependency

2️⃣ The Core Problem

Payment systems cannot rely on perfect networks.

The same request may be retried, external processors may timeout, and webhooks may arrive late or multiple times.


Dangerous Scenario

Client creates charge

↓

Payment succeeds internally

↓

Network timeout before response

↓

Client retries

↓

Duplicate charge risk

👉 Interview Memorization

Payment consistency is hard because retries, timeouts, external processors, and asynchronous events can make it unclear whether money moved.


3️⃣ High-level Architecture


Stripe-like Payment Path

Client

↓

Payment API

↓

Idempotency Layer

↓

Payment State Machine

↓

Ledger

↓

Processor / Bank Network

↓

Webhook / Reconciliation

Key Services


👉 Interview Memorization

A Stripe-like system protects payment consistency with idempotency at the API layer, durable state transitions in the payment layer, ledger correctness underneath, and reconciliation against external processors.


4️⃣ Idempotency Keys

Idempotency prevents duplicate business execution.


Flow

POST /payments
Idempotency-Key: abc123

↓

First request executes

↓

Result stored under abc123

↓

Retry with abc123 returns same result

What Gets Stored


👉 Interview Memorization

Idempotency keys make client retries safe by ensuring the same logical payment request executes at most once.


5️⃣ Request Fingerprinting

The same idempotency key should not be reused for a different request.


Example

Key: abc123
Amount: $100

Retry:
Key: abc123
Amount: $200

This should be rejected because the request changed.


Why

Without request fingerprinting, a client bug could accidentally reuse a key for a different payment.


👉 Interview Memorization

Idempotency should compare request fingerprints so the same key cannot silently represent two different payment operations.


6️⃣ Durable Payment State Machine

Payment operations should move through explicit durable states.


Example State Machine

CREATED

↓

REQUIRES_PAYMENT_METHOD

↓

AUTHORIZED

↓

CAPTURED

↓

SETTLED

Failure States

FAILED

CANCELED

REFUNDED

DISPUTED

REVERSED

👉 Interview Memorization

A durable payment state machine makes money movement explicit, auditable, and protected from invalid transitions.


7️⃣ State Transition Rules

Not every transition is legal.


Valid

AUTHORIZED → CAPTURED

CAPTURED → REFUNDED

Invalid

FAILED → CAPTURED

REFUNDED → AUTHORIZED

Why This Matters

State transition rules prevent accidental money movement from retry bugs, duplicated events, or out-of-order callbacks.


👉 Interview Memorization

Payment consistency depends on strict state transition rules so duplicate or out-of-order events cannot move money into impossible states.


8️⃣ Ledger Correctness

The ledger is the source of truth for financial accounting.


Double-entry Ledger

Debit Customer Balance     -100

Credit Merchant Balance    +100

Every debit has a matching credit.


Why It Matters


👉 Interview Memorization

A payment system should use ledger-style accounting so every money movement is durable, balanced, and auditable.


9️⃣ External Processor Uncertainty

Payment processors and banks are external systems.

They can timeout, return ambiguous responses, or send delayed webhooks.


Ambiguous Case

Platform sends capture request

↓

Processor timeout

↓

Did capture happen?
Unknown

Handling


👉 Interview Memorization

External processor timeouts create ambiguous states, so payment systems need idempotent processor calls, pending states, webhooks, polling, and reconciliation.


🔟 Webhooks

External processors often notify status changes with webhooks.


Webhook Challenges


Webhook Processing

Receive webhook

↓

Verify signature

↓

Deduplicate event ID

↓

Load payment

↓

Apply valid state transition

👉 Interview Memorization

Webhook processing must be authenticated, deduplicated, and guarded by payment state transition rules.


1️⃣1️⃣ Retry Safety

Retries are necessary, but unsafe retries are dangerous.


Safe Retry Requirements


Rule

Retry transport failure.

Do not duplicate business action.

👉 Interview Memorization

Payment retries should retry delivery, not duplicate the financial operation.


1️⃣2️⃣ Outbox Pattern

Payment systems often need to update a database and publish an event.


Problem

Update payment state

↓

Process crashes before publishing event

Downstream services never learn about the change.


Outbox Solution

Database transaction:

1. Update payment state
2. Insert outbox event

↓

Async relay publishes event

👉 Interview Memorization

The outbox pattern prevents payment state changes and downstream events from diverging.


1️⃣3️⃣ Reconciliation

Reconciliation compares internal records with processor and bank records.


Flow

Internal Ledger

↓ compare

Processor Report

↓

Matched / Missing / Mismatch

Reconciliation Finds


👉 Interview Memorization

Reconciliation is the safety net that detects mismatches between the internal ledger and external payment processor records.


1️⃣4️⃣ Refunds and Disputes

Payments do not end after capture.


Follow-up Operations


Ledger Impact

Original charge:
Customer → Merchant

Refund:
Merchant → Customer

Do not delete the original transaction.

Append a new reversing entry.


👉 Interview Memorization

Refunds and disputes should be modeled as new ledger entries and state transitions, not by mutating history.


1️⃣5️⃣ Consistency Model

Payment consistency is not usually one global ACID transaction across all systems.


Strong Consistency Needed


Eventual Consistency Acceptable


👉 Interview Memorization

Payment systems use strong consistency for internal money state and eventual consistency for downstream views and notifications.


1️⃣6️⃣ Observability


Monitor


👉 Interview Memorization

Payment observability must track consistency risks, not only latency and error rate.


1️⃣7️⃣ Best Practices


Practical Rules


Design Principle

Never trust retries.

Never trust external callbacks blindly.

Never lose the ledger trail.

👉 Interview Memorization

Stripe-like consistency comes from layers: idempotency, state machines, ledger correctness, webhook deduplication, and reconciliation.


🧠 Staff-Level Answer Final


👉 Full Interview Answer

A Stripe-like payment system handles consistency by assuming that clients retry, networks timeout, processors return ambiguous responses, and webhooks may be duplicated or delayed.

At the API layer, it uses idempotency keys so the same logical payment request executes at most once and retries return the original result.

The system should also fingerprint the request so a reused idempotency key cannot silently represent a different payment.

Underneath, the payment moves through a durable state machine with strict transition rules, such as created, authorized, captured, settled, refunded, or disputed.

Money movement should be recorded in a double-entry ledger so every debit has a matching credit and all changes are auditable.

External processor calls must be treated carefully because a timeout does not prove failure.

The system should use processor-side idempotency where possible, pending states for ambiguous outcomes, authenticated and deduplicated webhooks, polling, and reconciliation.

The outbox pattern helps keep payment state changes and downstream events consistent.

The main idea is that payment consistency is achieved through layered defenses rather than trusting one distributed transaction across clients, servers, banks, and processors.


⭐ Final Insight

Stripe-style Payment Consistency 的核心不是:

“请求成功就扣钱”

而是:

Idempotency

  • State Machine
  • Ledger
  • Webhook Deduplication
  • Retry Safety
  • Reconciliation

最重要的一句话:

Retries must be safe.

Money history must be immutable.


中文部分

🎯 How Stripe Handles Payment Consistency(Stripe 风格支付一致性)


核心理解

支付系统最大的问题不是普通 API 延迟。

真正的问题是:

请求会重试

网络会超时

外部 processor 状态不确定

webhook 会重复或乱序

钱不能重复扣

高层架构

Client

↓

Payment API

↓

Idempotency Layer

↓

Payment State Machine

↓

Ledger

↓

Processor / Bank Network

↓

Webhook / Reconciliation

Idempotency Key

Idempotency key 用来防止重复支付。

POST /payments
Idempotency-Key: abc123

第一次请求执行支付。

后续相同 key 的重试返回同一个结果。


Request Fingerprint

同一个 idempotency key 不能对应不同请求。

Key: abc123
Amount: $100

Retry:
Key: abc123
Amount: $200

这种应该被拒绝。


Payment State Machine

支付应该是明确状态机:

CREATED

↓

AUTHORIZED

↓

CAPTURED

↓

SETTLED

失败或后续状态:

FAILED
CANCELED
REFUNDED
DISPUTED
REVERSED

Ledger

支付系统必须有账本。

推荐 double-entry ledger:

Debit Customer Balance     -100

Credit Merchant Balance    +100

每一笔钱的移动都要可审计。


External Processor Uncertainty

外部支付通道可能 timeout:

Capture request sent

↓

Processor timeout

↓

不知道是否真的成功

处理方式:


Webhook

Webhook 不能盲目信任。

必须:


Reconciliation

对账用于比较内部账本和外部 processor 记录:

Internal Ledger

↓ compare

Processor Report

↓

Matched / Missing / Mismatch

这是支付一致性的最后安全网。


面试回答模板

A Stripe-like payment system handles consistency with idempotency keys, durable payment state machines, ledger correctness, webhook deduplication, and reconciliation.

Idempotency ensures client retries do not create duplicate charges.

The payment state machine ensures money movement only follows valid transitions.

The ledger records every debit and credit immutably for audit and reconciliation.

External processors can timeout or send duplicate webhooks, so the system must use processor idempotency, pending states, verified webhooks, and reconciliation jobs.

The key principle is that retries must be safe and money history must be immutable.


最终总结

Retries must be safe.

Money history must be immutable.

核心原则:

Idempotency + State Machine + Ledger + Webhook Dedup + Reconciliation

Implement