Payment System (Stripe)
Explore a Stripe-style PaymentIntent lifecycle, visualizing idempotency, client secrets, authentication, authorization, capture, webhooks, ledger posting, and reconciliation.
Continue with the guided workspace
Use the paired workspace to connect this guide's mental model with live component state, visible signals, and the outcome each step or scenario is meant to prove.
Mental Model
Modern online payment systems must operate reliably over unreliable networks, protecting against duplicate charging, minimizing fraud, and maintaining audit trails.
Instead of treating payment as a single API call, Stripe-style architectures use a PaymentIntent state machine. This state machine separates the payment intent creation, customer authentication, and payment capture into distinct, trackable stages. By keeping a durable state record on the server, the system can resume, retry, or compensate at any point during network failures or security checks.
graph TD
A[Customer Browser] -->|1. Create Intent| B[Merchant Server]
B -->|2. Check Idempotency| C[PaymentIntent State Machine]
C -->|3. Evaluate Risk| D[Fraud Engine]
C -->|4. Router Map| E[Payment Gateway]
E -->|5. Auth| F[Card Network]
F -->|6. Approve/Hold| G[Issuing Bank]
G -->|7. Success Webhook| H[Webhook Handler]
H -->|8. Update Order| B
B -->|9. Post Ledger| I[Ledger / Recon]
Components and Why They Exist
Customer (Client Checkout Portal)
The customer checkout portal serves as the user interface in the buyerβs browser. It receives the scoped client secret from the merchant backend, collects credit card details directly from the buyer, and transitions its status badge to a confirmed receipt once payment authorization and capture complete.
Payment Service API (Merchant Server)
The merchant server API is the trusted server-side entry point for the merchantβs order workflow. It creates the initial order record, attaches idempotency keys when requesting a PaymentIntent to prevent double-billing, and updates order fulfillment status when signed webhooks arrive.
PaymentIntent
The PaymentIntent acts as the durable, server-side state machine tracking a single transactionβs lifecycle. It records payment attempts, status transitions, and failures under one canonical identifier, advancing its status badge through requires_payment_method, requires_confirmation, requires_action (during 3DS challenges), requires_capture, and succeeded.
Fraud Engine (Radar)
The fraud engine screens transactions for suspicious activity before sending requests to external card rails. Behavioral telemetry and card attributes pass through risk models here to compute a fraud score (such as 12/100 low risk) before authorization is allowed to proceed.
3DS / Auth
The 3D Secure (3DS) authentication module verifies cardholder identity under regulatory frameworks such as Strong Customer Authentication (SCA). While an interactive SMS or banking-app challenge is active, this module holds the PaymentIntent state in requires_action until the buyer completes verification.
Payment Gateway (Processor)
The payment gateway bridges the merchant payment platform with external card networks. It translates payment instructions into banking network messages (such as ISO-8583), submits authorization and manual capture requests, and dispatches batch settlement files.
Card Network
The card network routes payment messages globally between the acquiring processor and the cardholderβs issuing bank. Networks such as Visa, Mastercard, and Amex coordinate authorization routing signals and clearing rules across member institutions.
Issuing Bank
The issuing bank manages the customerβs credit card or deposit account. Upon receiving an authorization request from the card network, the bank verifies card validity, checks available balance, places an authorization hold on the funds, and returns an approval code.
Webhook Handler
The webhook handler ensures merchant servers process asynchronous payment state updates reliably. It listens for signed webhook events (such as payment_intent.succeeded) and notifies the merchant server to trigger fulfillment even if the customer closed their browser tab early.
Ledger / Recon
The ledger and reconciliation subsystem maintains financial integrity, double-entry bookkeeping, and auditability. Every captured charge posts balanced debit and credit journal entries to the immutable ledger, which later cross-references daily settlement batches from the payment processor.
Edge Cases and Misconceptions
Idempotency Keys vs. Race Conditions
A common misconception is that sending an idempotency key solves all duplicate submission issues. If two identical requests hit two different API gateway nodes at the exact same millisecond, both might proceed if the caching layer is slow. Gateway nodes must use distributed locking (like Redis SETNX or Redlock) to atomically acquire lock ownership on the key before beginning database writes.
Separating Authorization and Capture
For physical goods, merchants often authorize a charge at checkout but do not capture the funds until shipping. If shipping is delayed, the authorization hold might expire (typically in 7-30 days depending on the bank), causing a βchargebackβ or lost collection. The payment system must track authorization expiration timers and either capture early or re-authorize before fulfillment.
Asynchronous Checkout Failures
If a user closes their tab immediately after clicking βPayβ, the browser confirmation request may be terminated. Without Webhooks, the merchant server remains unaware that the issuing bank successfully completed the payment. Webhooks must be used as the source of truth for payment success, decoupled from browser navigation events.
Common Questions
Why is idempotency critical in payment systems?
Without idempotency, network timeouts or customer double-clicks can cause duplicate API requests to process, leading to double-charging the customer's account.
What is the difference between authorization and capture?
Authorization checks if the buyer has sufficient funds and reserves them at the issuing bank. Capture actually collects the reserved funds and initiates the settlement process to the merchant's account.
How does the Saga pattern handle distributed failures in payments?
It executes a sequence of local transactions across services. If any step fails (like a gateway timeout), the Saga orchestrator triggers compensating transactions (like a refund or hold release) to roll back state.
Why is a double-entry accounting ledger used instead of simple state updates?
A double-entry ledger is immutable and ensures mathematical balance (Debits = Credits). It prevents money from being created or lost in code bugs, providing an audit trail.
What is nightly batch reconciliation?
It is the process of cross-referencing daily settlement logs from processors, bank accounts, and internal ledgers to verify all transactions match exactly and resolve any discrepancies.
Why is 3D Secure (3DS) handled via redirects or modals?
3D Secure requires the cardholder to prove their identity directly to their issuing bank. To prevent merchants from stealing these authentication credentials, the gateway redirects the user to the bank's portal or opens a secure iframe, returning control to the merchant page only after the bank issues an authentication token.