Payments, an interactive architecture walkthrough

Stripe-style payments platform: how the architecture works

How a payments platform tokenises cards, authorises a payment through the card networks, records it in a ledger, and settles funds to merchants.

This is a learning explainer based on public engineering writing and general design practice. It is simplified, it is not the actual architecture of any company, and it may be inaccurate.

37 components, 42 connections, 15 steps. Updated 27 October 2026.

Interactive diagram

Overview

A payments platform keeps raw card data out of merchants' hands by tokenising it in an isolated, PCI-scoped vault. A payment is a state machine driven by an orchestration service: it is screened for fraud, routed to an acquirer, authorised by the card network and issuing bank, and recorded in a double-entry ledger. Idempotency keys are stored durably with the payment, and events leave through an outbox. Settlement, reconciliation and webhooks run asynchronously. This is a generic reference design, not Stripe's internal architecture.

Trade-offs and what changes at scale

Correctness beats speed here: idempotency keys and PaymentIntent state are written in one database transaction, so a retry with the same key returns the original result instead of repeating the work (keys are kept for a limited window, and a retry with changed parameters is rejected). The acquirer call cannot be part of that transaction, so the outcome of an in-flight authorisation is settled by idempotent acquirer requests, timeouts and reconciliation, and outbox events are at-least-once. Webhooks are at-least-once, so merchants must deduplicate on the event id. Keeping the vault in its own network zone narrows PCI scope but adds a hop and a service that must be extremely available. At scale, the ledger and payments database are sharded by merchant or account with hot merchants isolated, card authorisation is synchronous but capture, payouts and reconciliation are batched and asynchronous, and routing across several acquirers improves approval rates and resilience.

How it works, step by step

The walkthrough above, as text. Each step lights up the components named under it.

  1. The shopper types card details into SDK-hosted fields, so the merchant's page never handles raw card data. This typically keeps the merchant in the lightest PCI self-assessment (SAQ A); the merchant still owns the security of the page that hosts the fields.

    Components Client-side SDK, Cardholder, Merchant Website/App

  2. The SDK sends the card through a hardened public tokenisation endpoint (WAF, rate limiting, publishable-key check) to the vault, which encrypts it with keys from the HSM-backed KMS and returns a single-use token.

    Components Card Vault / Tokenisation, Encrypted Card Store, HSM-backed KMSVia HTTPS tokenise

  3. The merchant server creates the payment with its secret API key and an idempotency key. The gateway authenticates, rate-limits (counters live in a cache) and passes the idempotency key on, so a retry with the same key returns the original result instead of repeating the work.

    Components API Gateway, Merchant Server, Rate Limit Store, Merchant & Key StoreVia HTTPS + API key

  4. Orchestration writes the PaymentIntent and the idempotency key in the same Postgres transaction, so a retry with the same key returns the original result instead of repeating the work, and drives the state machine. Every transition is stored, so a crash can resume safely.

    Components Payments Orchestration, Payments DBVia create/confirm

  5. Risk scoring evaluates the payment before money moves and returns allow, review or block, or asks for 3-D Secure (strong customer authentication): the intent moves to requires_action while the cardholder confirms with their bank (the challenge runs between the cardholder and the issuer's authentication server), which many cards in the EU and India require and which often shifts fraud liability to the issuer. Blocking early is cheaper than a fraud chargeback.

    Components Risk & Fraud Scoring, Cardholder, Issuing BankVia score

  6. The routing service picks the acquirer using cost, success rate and availability, and can fail over when one degrades.

    Components Routing ServiceVia select acquirer

  7. The call goes out through the vault's proxy, which swaps the token for the real card number inside the PCI zone, so the card number never reaches the orchestration, routing or any other service outside the PCI zone. The vault does send it onward to the acquirer.

    Components Card Vault / TokenisationVia detokenise via proxy

  8. The authorisation goes through the vault proxy to the acquirer, then the card network, then the issuing bank, which approves or declines. The response flows back and the intent moves to its next state.

    Components Issuing Bank, Acquirer / Processor, Card Networks, Card Vault / TokenisationVia auth request

  9. The ledger writes balanced double-entry rows in one ACID transaction: entries always balance (debits equal credits) and it is the source of truth for balances. In this design authorisation posts hold entries and capture posts the money entries.

    Components Double-Entry Ledger, Ledger DBVia post entries

  10. Events are written to an outbox in the same transaction as the state change and relayed to Kafka, so a crash cannot silently drop one (relaying is at-least-once). Webhook delivery signs each payload and retries with backoff for a bounded period, then marks the delivery failed (the merchant can replay it); delivery is at-least-once, so merchants deduplicate by event id.

    Components Webhook Delivery, Event Bus, Merchant Server, Payments DBVia consumes

  11. By default capture happens automatically when the payment is confirmed. With manual capture the intent waits in requires_capture and the merchant calls the API again, either right away or after shipping; that capture also goes to the acquirer through the vault proxy. Orchestration then moves the intent to succeeded and posts the money ledger entries.

    Components Payments Orchestration, Double-Entry Ledger, Card Vault / Tokenisation, Acquirer / Processor

  12. Asynchronously, funds arrive from the acquirer in the platform's bank account, and settlement pays merchants by bank transfer from their available balance, recording payout entries in the ledger.

    Components Settlement & Payout, Bank Transfer Rails, Double-Entry LedgerVia captured events

  13. Reconciliation ingests acquirer settlement files and compares them with the ledger. Mismatches are flagged before payouts are trusted.

    Components Reconciliation, Acquirer Files, Acquirer / Processor, Double-Entry LedgerVia ingest

  14. Refunds enter as API calls from the merchant server or dashboard (they are separate objects from the PaymentIntent), and disputes (chargebacks) arrive through the acquirer's and card network's dispute feeds onto the event bus, which orchestration consumes. Both run through the orchestrator and ledger and notify the merchant, and the dashboard shows their status.

    Components Payments Orchestration, Acquirer / Processor, Dashboard, Merchant ServerVia dispute / refund events

  15. Every service emits metrics and traces, and sensitive services write to the append-only audit log. This supports incident response and PCI evidence.

    Components Metrics & Tracing, Audit Log, HSM-backed KMS, Card Vault / Tokenisation

Sequence diagram

The same walkthrough as a UML sequence diagram, one lane per layer or group (28 components in all), left to right in the order a request reaches them, numbered by step. A loop on a lane is a step that stays inside that group. Solid arrows are synchronous calls, dashed are asynchronous.

Stripe-style payments platform: sequence diagram of the walkthroughMerchant SidePublic API EdgePCI Zone(Isolated…Payments CoreExternalFinancial…Money MovementEventing &NotificationsObservability &Audithandles request1HTTPS tokenise2forward2encrypted write2encrypt/decrypt2HTTPS + API key3rate limits3key lookup3create/confirm4SQL4score53-D Secure challenge5select acquirer6detokenise via proxy7auth request8authorise via proxy8ISO 85838post entries9SQL tx9consumes10outbox relay10signed webhook10SQL10detokenise via proxy11authorise via proxy11post entries11captured events12bank transfer12payout entries12settlement funds arrive12ingest13settlement files13compare13confirmed totals13dispute / refund events14dispute notices14HTTPS14HTTPS + API key14create/confirm14metrics15audit logs15

Key components

Merchant Sideboundary

  • Cardholder: Pays on merchant site
  • Client-side SDK: Tokenises card in browser
  • Merchant Server: Creates payments, receives webhooks
  • Merchant Website/App: Checkout page with client SDK

PCI Zone (Isolated Network)boundary

  • Card Vault / Tokenisation: Stores PANs, issues tokens
  • Encrypted Card Store: Encrypted card data (postgresql)
  • HSM-backed KMS: Key management, encryption keys

Public API Edgelayer

  • API Gateway: Auth, rate limits, idempotency keys
  • Dashboard: Merchant payments & payouts UI
  • Merchant & Key Store: merchants, API keys, settings
  • Rate Limit Store: Rate counters (cache)
  • Tokenisation Gateway: WAF, rate limits, publishable-key check

Payments Coredomain

  • Payments DB: PaymentIntents, idempotency keys, outbox (postgresql)
  • Payments Orchestration: Owns PaymentIntent state machine
  • Risk & Fraud Scoring: Allow, review, block or require 3-D Secure
  • Routing Service: Chooses acquirer/processor

External Financial Networkboundary

  • Acquirer / Processor: Merchant's acquiring bank
  • Bank Transfer Rails: Merchant payouts
  • Card Networks: Visa / Mastercard
  • Issuing Bank: Approves or declines

Money Movementdomain

  • Acquirer Files: Settlement files
  • Double-Entry Ledger: Immutable balanced entries
  • Ledger DB: ACID ledger store (postgresql)
  • Reconciliation: Matches acquirer files to ledger
  • Settlement & Payout: Batches funds, pays merchants

Eventing & Notificationslayer

  • Event Bus: payment events (kafka)
  • Webhook Delivery: Signed, retried notifications

Observability & Auditlayer

  • Audit Log: Append-only audit trail
  • Metrics & Tracing: Monitoring, alerting

Sources

Public writing this explainer draws on. Read these for what the real systems actually do.

Make it yours

Copy this diagram and its walkthrough into your own workspace, then change anything: swap Postgres for DynamoDB, add a cache, rewrite the narration. Free, and it uses no AI credits.

This is a learning explainer based on public engineering writing and general design practice. It is simplified, it is not the actual architecture of any company, and it may be inaccurate. Real systems differ in the details. Browse the library.