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)
Serves as the user interface in the customerβs browser. Securely collects credit card details and sends confirmation requests. In the demo, observe this component receiving the client secret in Step 2, collecting info, and updating to a success receipt state once the payment succeeds in Step 9.
Payment Service API (Merchant Server)
Serves as the trusted server-side entry point for the merchantβs business logic. Handles initial order logic, requests the payment intent, and securely processes order fulfillment. In the demo, watch how it attaches idempotency keys to prevent double-billing and updates order databases from webhooks.
PaymentIntent
Acts as the durable, server-side state machine tracking a single transactionβs lifecycle. Ensures that attempts, status changes, and failures are recorded under a single identifier. In the demo, note the intent status badges changing states from requires_payment_method to requires_confirmation, requires_action (if 3DS is needed), requires_capture (if manual capture), and finally succeeded.
Fraud Engine (Radar)
Screens transactions for fraud before sending requests to expensive external network rails. Asynchronously runs behavioral telemetry and card attributes through risk models to return a score. In the demo, you can see the risk evaluation path activate in Step 4, scoring the transaction as low risk (12/100) to clear it.
3DS / Auth
Authenticates cardholder identity under regulatory frameworks (like SCA in Europe). Presents challenges (like SMS codes or bank app prompts) to verify the customer. In the demo, look at Step 5 when a 3DS challenge is active, holding the PaymentIntent in requires_action.
Payment Gateway (Processor)
Bridges the merchant backend API with card networks. Formats payment instructions into bank network formats (such as ISO-8583) and submits authorization requests. In the demo, watch it communicate with card networks in Step 6, handle manual capture in Step 8, and dispatch settlement files in Step 12.
Card Network
Routes payment details globally between the acquiring processor and the issuing bank. Coordinates authorization and settlement messages across Visa, Mastercard, or Amex networks. In the demo, observe routing signals moving across the network in Step 6.
Issuing Bank
Manages the customerβs credit or bank account. Evaluates card validity, checks available funds, and places a temporary hold on the transaction amount. In the demo, observe the bank authorization hold increasing and returning an approval code in Step 7.
Webhook Handler
Ensures merchant servers process asynchronous state updates reliably. Listens for webhooks (e.g. payment_intent.succeeded) and triggers server-side fulfillment even if the client browser closed early. In the demo, you can see the webhook trigger Step 10 to safely notify the merchant server.
Ledger / Recon
Maintains financial integrity, bookkeeping transparency, and auditability. Records double-entry journal items and reconciles daily bank statement deposits against gateway records. In the demo, watch the ledger post balanced debits and credits in Step 11 and match files in Step 12.
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.