Architecture

Distributed payment ledger with idempotent settlement

A payment ledger that cannot double-charge, assembled one safety layer at a time. Arrow keys or click to advance.

01

The request path into the payment service

flowchart LR Client([Merchant client]) --> AG[API Gateway] AG --> PS[Payment Service - ECS Fargate]

A client authorization arrives over TLS at API Gateway, which authenticates the merchant and forwards to a stateless Payment Service on ECS Fargate. Nothing here is safe against retries yet - it is just the entry layer.

02

The idempotency gate

flowchart LR Client([Merchant client]) --> AG[API Gateway] AG --> PS[Payment Service - ECS Fargate] PS -->|conditional write PENDING| IK[(DynamoDB idempotency)] IK -->|on retry return cached| PS

Before any money moves, the service claims the client-supplied UUID with a conditional write to DynamoDB - attribute_not_exists, ConsistentRead true. First writer wins and proceeds; a retry reads the winner's stored response and returns it verbatim. The gate fails closed.

03

The double-entry ledger

flowchart LR Client([Merchant client]) --> AG[API Gateway] AG --> PS[Payment Service - ECS Fargate] PS -->|conditional write| IK[(DynamoDB idempotency)] PS -->|pooled txn| RP[RDS Proxy] RP -->|debit and credit pair| AU[(Aurora PostgreSQL Multi-AZ ledger)]

Past the gate, the service writes one DEBIT and one CREDIT in a single Aurora PostgreSQL ACID transaction, summing to zero, through RDS Proxy in transaction mode so pooled connections never leak tenant context. A UNIQUE constraint on idempotency_key is the second line of defense. Multi-AZ synchronous replication gives RPO zero.

04

Events without two-phase commit

flowchart LR Client([Merchant client]) --> AG[API Gateway] AG --> PS[Payment Service - ECS Fargate] PS -->|conditional write| IK[(DynamoDB idempotency)] PS -->|ledger and outbox in one txn| AU[(Aurora PostgreSQL ledger)] AU -->|poll unpublished| OL[Outbox Poller Lambda] OL --> SQS[SQS] SQS --> DC[Downstream consumers]

The outbox row is written in the same Aurora transaction as the ledger entries. A Lambda polls unpublished rows every 100 ms, publishes to SQS, and stamps published_at. Downstream consumers dedupe on the idempotency key - at-least-once, never lost, never phantom.

05

Saga orchestration for multi-step settlement

flowchart TD subgraph Edge[Edge] Client([Merchant client]) --> AG[API Gateway] end subgraph Compute[Compute] AG --> PS[Payment Service - ECS Fargate] SF[Step Functions saga] -->|hold release fee| PS OL[Outbox Poller Lambda] end subgraph Data[Data] PS -->|conditional write| IK[(DynamoDB idempotency)] PS -->|ledger and outbox| AU[(Aurora PostgreSQL ledger)] AU -->|poll| OL --> SQS[SQS] --> DC[Downstream consumers] end PS -->|start settlement| SF

Marketplace settlement spans hold, KYC verify, release, and fee collection - no single ACID transaction covers it. A Step Functions Standard Workflow persists each state, retries with backoff, and on failure runs a compensating state machine with derived idempotency keys.

06

The full system with reconciliation and audit

flowchart TD subgraph Edge[Edge] Client([Merchant client]) --> AG[API Gateway] end subgraph Compute[Compute] AG --> PS[Payment Service - ECS Fargate] PS -->|tokenize| PC[Payment Cryptography HSM] SF[Step Functions saga] -->|hold release fee| PS PS -->|start settlement| SF OL[Outbox Poller Lambda] RL[Reconciliation Lambda] end subgraph Data[Data] PS -->|conditional write| IK[(DynamoDB idempotency)] PS -->|ledger and outbox| AU[(Aurora PostgreSQL ledger)] AU -->|poll| OL --> SQS[SQS] --> DC[Downstream consumers] RL -->|scan nightly| AU end subgraph Control[Control and audit] SF -->|stuck compensation| EB[EventBridge] RL -->|discrepancy| EB EB --> SNS[SNS] --> IM([Incident Manager]) PS -.privileged access.-> CT[(CloudTrail audit log)] end

Every layer plus the safety net: a daily reconciliation Lambda scans the ledger for unbalanced or duplicate entries, a stuck compensation pages on-call via EventBridge to SNS to Incident Manager, CloudTrail records every privileged access, and Payment Cryptography keeps PANs out of the ledger entirely.