Learning lens
Start with judgment, not a universal prescription.
This page is a learning model for understanding the capability. It does not claim exact production internals, exact costs, or an infinite-scale architecture.
Evidence
Conceptual pattern
0->1 default
Start with explicit trust boundaries, auditable decisions, and managed primitives where correctness matters more than novelty.
Cost drivers
Watch for breakpoints
- -authorization logic spreads across services
- -audit queries become operationally important
- -customers require stronger controls
Learn first
Concepts behind this architecture
Idempotency
Make repeated requests safe so retries do not create duplicate side effects.
Retry with Exponential Backoff
Retry transient failures slowly enough that recovery is possible.
Strong Consistency
Make reads reflect the latest committed write for correctness-critical data.
The Problem
Accepting online payments is one of the highest-stakes features in software. A bug can charge customers twice, lose money, or create compliance violations. Payment processing requires integrating with payment gateways (Stripe, Adyen, Braintree), handling asynchronous payment flows (3D Secure, bank transfers), ensuring idempotency (never charge twice for the same operation), reconciling payments via webhooks, managing subscriptions and refunds, and maintaining PCI DSS compliance to protect card data. The system must be auditable, resilient to failures at any point in the flow, and eventually consistent between your database and the payment provider.
Architectural Approaches
Payment Gateway Integration (Stripe, Adyen)
Integrate directly with a payment gateway API. Your server creates payment intents, the client collects card details via the gateway’s embedded UI (Stripe Elements, Adyen Drop-in), and the gateway handles the actual charge. You never see raw card numbers, simplifying PCI compliance to SAQ-A level.
Pros
- +PCI scope is minimized — card data never touches your servers
- +Mature SDKs handle edge cases (3D Secure, retries, currency conversion)
- +Built-in fraud detection and risk scoring
- +Comprehensive dashboard for payment operations
Cons
- −Per-transaction fees (2.9% + $0.30 typical for Stripe)
- −Vendor dependency for a critical business function
- −Complex webhook integration for async payment events
- −Each gateway has its own API patterns and quirks
Payment Orchestration Layer
Build an abstraction layer that routes payments to multiple gateways based on rules (lowest fee, highest success rate, currency, region). Services like Primer or custom-built orchestrators provide gateway-agnostic payment processing with automatic failover.
Pros
- +Multi-gateway redundancy — failover if one gateway is down
- +Optimize for lowest fees per transaction
- +A/B test gateways for conversion rate optimization
- +Single API for your application regardless of gateway
Cons
- −Additional complexity layer
- −Must maintain integrations with multiple gateways
- −Reconciliation across gateways is harder
- −Adds latency from the orchestration hop
Ledger-Based Architecture
Model all financial operations as double-entry ledger entries. Every payment, refund, fee, and payout is recorded as a pair of debit/credit entries in an immutable ledger. The ledger is the source of truth; the payment gateway is an external system reconciled against the ledger.
Pros
- +Complete audit trail — every cent is accounted for
- +Easy reconciliation — compare ledger with gateway reports
- +Supports complex financial operations (partial refunds, credits, splits)
- +Foundation for financial reporting and compliance
Cons
- −More complex to implement than simple payment tracking
- −Requires understanding of double-entry bookkeeping
- −Ledger entries are immutable — corrections require compensating entries
- −Overkill for simple e-commerce (single product, no marketplace)
Architecture
Key Components
Payment API
REST endpoints for creating payments, processing refunds, and managing subscriptions. Accepts tokenized payment methods (never raw card numbers). Validates amounts, currencies, and business rules before calling the gateway. Returns payment status and handles async confirmations.
Idempotency Layer
Ensures that retrying a payment request doesn’t create duplicate charges. Uses an idempotency key (client-generated UUID) stored in Redis/database. If the same key is seen again, return the cached result instead of processing a new payment. Critical for handling network failures and retries.
Ledger Service
Maintains a double-entry ledger recording every financial transaction. Each payment creates entries: debit customer account, credit revenue account. Refunds reverse the entries. The ledger balance must always equal zero (balanced books). Provides the source of truth for financial reporting.
Webhook Handler
Receives and processes payment events from the gateway (payment_intent.succeeded, charge.refunded, invoice.paid). Verifies webhook signatures, deduplicates events, and updates the ledger and order status. Must be idempotent — the same event may be delivered multiple times.
Reconciliation Service
Periodically compares your ledger with the gateway’s records (via API or settlement reports). Identifies discrepancies (missing payments, unmatched refunds, fee differences). Alerts on mismatches for manual investigation. Runs daily for operational reconciliation and monthly for accounting close.
Fraud Detection
Evaluates payment risk before processing. Checks velocity (too many attempts from one IP), amount anomalies, device fingerprinting, and address verification (AVS). Can block suspicious payments or require additional verification (3D Secure step-up). Integrates with Stripe Radar or custom ML models.
Data Model
Idempotency in Payment Processing
Double-charging a customer is the worst bug in payment processing. Idempotency prevents it.
How it works:
- Client generates a unique idempotency key (UUID v4) for each payment attempt
- Client sends: POST /payments with header
Idempotency-Key: abc-123 - Server checks if key exists in the idempotency store
- If found: return the cached response (same status, same payment ID)
- If not found: process the payment, store the result keyed by the idempotency key
Storage: Redis with 24-48 hour TTL is ideal. Store the full response (status code + body) so retries return identical responses.
Race condition: Two requests with the same key arrive simultaneously. Use Redis SETNX (set-if-not-exists) as a distributed lock. The first request wins and processes; the second waits and returns the cached result.
Stripe’s approach: Stripe accepts an Idempotency-Key header on all POST requests. Results are cached for 24 hours. If the same key is sent with different parameters, Stripe returns a 400 error — the key is tied to the original request parameters.
Critical rule: The idempotency key must be generated by the client, not the server. If the server generates it, a network failure between server and client means the client can’t retry with the same key.
Webhook-Driven Payment State Machine
Payments are inherently asynchronous. A credit card charge may go through 3D Secure, bank verification, and fraud checks before succeeding or failing. Model payments as a state machine driven by gateway webhooks.
Payment states: created → processing → requires_action → succeeded → (refunded)
Webhook events (Stripe example):
payment_intent.created→ set status to “processing”payment_intent.requires_action→ redirect user to 3D Securepayment_intent.succeeded→ fulfill order, update ledgerpayment_intent.payment_failed→ notify customer, allow retrycharge.refunded→ update ledger, notify customer
Reliability rules:
- Process webhooks idempotently — Stripe may send the same event multiple times. Use the event ID for deduplication.
- Verify webhook signatures — Stripe signs webhooks with HMAC. Verify before processing.
- Return 200 quickly — Process the webhook asynchronously (enqueue and ack). Stripe retries if you don’t respond within 20 seconds.
- Don’t rely solely on webhooks — Use webhooks as the primary signal but also poll the payment status API as a backup. Belt and suspenders.
- Handle out-of-order events — A “succeeded” event may arrive before a “processing” event. Check the current state before applying transitions.
PCI Compliance Strategy
PCI DSS (Payment Card Industry Data Security Standard) has strict requirements for handling card data. Minimizing your PCI scope saves months of compliance work.
SAQ-A (minimal scope): Use hosted payment fields (Stripe Elements, Adyen Drop-in). Card numbers are entered in an iframe served by the gateway. Your servers never see card data. Easiest compliance — a self-assessment questionnaire.
SAQ A-EP: Your server serves the payment page but card data is submitted directly to the gateway (JavaScript tokenization). More scope than SAQ-A but less than full PCI.
Full PCI DSS: If you handle raw card numbers (e.g., call center, legacy integration), you need full compliance: network segmentation, encryption, access controls, penetration testing, annual audits. Extremely expensive and time-consuming.
Best practice: Always use SAQ-A. Never let card data touch your infrastructure.
Token vault: If you need to store payment methods for recurring billing, use the gateway’s token vault. Stripe stores the card and gives you a payment method ID (pm_xxx). You store only the ID, not the card number.
Logging: Never log card numbers, CVVs, or full card details. If you accidentally log them (stack traces, request logging), you’ve expanded your PCI scope. Use middleware to redact sensitive fields from logs.
Real-World Examples
Stripe
The most developer-friendly payment gateway. Payment Intents API handles the full payment lifecycle including 3D Secure. Idempotency keys on all endpoints. Comprehensive webhook system. Stripe Elements for PCI-compliant card collection. Stripe Radar for ML-based fraud detection.
Shopify
Payment orchestration supporting 100+ payment providers via Shopify Payments (powered by Stripe) and third-party gateways. Double-entry ledger for merchant balances. Handles multi-currency, tax calculation, and marketplace payouts.
Uber
Real-time payment processing for millions of rides daily. Pre-authorization at ride start, final charge at ride end. Supports multiple payment methods per user with fallback ordering. Custom fraud detection for rider and driver accounts.
Square
Unified commerce platform handling in-person (POS terminals) and online payments. Card-present transactions use EMV chip for security. Online payments use a hosted payment form. Provides hardware (readers) and software (SDK) for omnichannel payment processing.
Architectural Tradeoffs
Single gateway vs multi-gateway orchestration
Pros
- +Single: simpler integration, one dashboard, one set of webhooks
- +Multi: redundancy, lower fees through smart routing
- +Single: faster to implement, easier reconciliation
Cons
- −Single: vendor dependency, no failover
- −Multi: complex reconciliation, more code to maintain
- −Multi: split data across dashboards, harder to debug issues
Synchronous payment confirmation vs webhook-driven
Pros
- +Synchronous: simpler code, immediate result
- +Webhook: handles async flows (3D Secure, bank transfers)
- +Webhook: more reliable — server-to-server, retried on failure
Cons
- −Synchronous: doesn't work for all payment methods
- −Webhook: eventual consistency, more complex state management
- −Both: use synchronous for instant payments, webhooks as confirmation
Simple payment tracking vs double-entry ledger
Pros
- +Simple: faster to build, sufficient for basic e-commerce
- +Ledger: complete audit trail, easy reconciliation
- +Ledger: supports complex operations (marketplace splits, credits)
Cons
- −Simple: hard to reconcile, no formal audit trail
- −Ledger: more complex, requires accounting knowledge
- −Ledger: overkill for simple single-product stores
Learn Payment Processing
Copy a learning context prompt for an AI assistant. It keeps assumptions visible and asks for tradeoffs, cost drivers, failure modes, and what to measure before adding complexity.
Explore More Capabilities
API Versioning
Backward-compatible API evolution with URL, header, and content negotiation strategies
Audit Logging
Append-only event stores, tamper-proof records, and compliance-ready activity trails
Caching Strategies
Cache-aside, write-through, invalidation patterns, and distributed caching with Redis