{"type":"article","schemaVersion":"1","slug":"payment-infrastructure-foundation","title":"The Money Layer Is Not the Money Rail: Building a Payment Foundation That an Adversarial Audit Couldn't Break","description":"@agentbadge/payments — a payment domain model that separates Payment/Attempt/Receipt/Event entities from whatever rail moves the money. Guarded state transitions, a 9-check verification verdict as the only door to CONFIRMED, two-level idempotency, decimal-string money — stress-tested by two adversarial AI audits and a live Stripe test-mode dogfood: CONFIRMED → REFUNDED, concurrent refunds → exactly one rail refund. 114/114 tests green.","status":"EXPERIMENT","topics":["payments","agent-economy","engineering","adversarial-audit","reliability"],"concepts":["domain-rail-split","evidence-vs-verdict","guarded-state-transitions","nine-check-verdict","two-level-idempotency","claim-first-side-effects","decimal-string-money","dispute-as-refund-lock","self-healing-completion","honest-scope"],"rules":[],"capabilities":["guarded-state-transitions","nine-check-verdict","request-fingerprint-dedupe","claim-first-refund","decimal-string-money","rail-consulted-expiry","provider-capability-guard"],"actions":[{"type":"read","label":"Read article (Markdown)","url":"https://agentbadge.xyz/blog/payment-infrastructure-foundation.md"},{"type":"view-demo","label":"Run Agent Readiness scan","url":"https://agentbadge.xyz/scan?src=article:payment-infrastructure-foundation"}],"qa":[{"question":"What is The Money Layer Is Not the Money Rail: Building a Payment Foundation That an Adversarial Audit Couldn't Break?","answer":"We built @agentbadge/payments — a payment domain model that treats Payment, PaymentAttempt, PaymentReceipt and PaymentEvent as durable entities separate from whatever rail actually moves the money. All state changes flow through two transition maps with guarded writes, every CONFIRMED requires a 9-…"}],"claims":[{"id":"c45-guarded-transitions","status":"VERIFIED","text":"Every payment/attempt status change flows through two transition maps with guarded applyStatus(expectedFrom, to) writes; a concurrent loser re-reads and reports persisted state instead of overwriting it.","evidence":[{"type":"github","url":"https://github.com/spreadzp/agentbadge/tree/main/packages/payments/src"}]},{"id":"c45-nine-check-verdict","status":"VERIFIED","text":"CONFIRMED is reachable only through the 9-check verification pipeline (reference, amount, currency, provider, recipient, network, finality, tx-reuse, status) — a rail cannot self-confirm at create or via callback.","evidence":[{"type":"github","url":"https://github.com/spreadzp/agentbadge/tree/main/packages/payments/src"}]},{"id":"c45-stripe-live-dogfood","status":"VERIFIED","text":"Live Stripe test-mode run: create → pay → CONFIRMED → REFUNDED with two concurrent refund calls producing exactly one rail refund (railRefundCount:1). The run caught a fiat-rail network-expectation bug (220-10-F1) that prompted a second audit.","evidence":[{"type":"github","url":"https://github.com/spreadzp/agentbadge/tree/main/docs/EPICS/220-payment-infrastructure-foundation/evidence"}]},{"id":"c45-double-audit-resolved","status":"VERIFIED","text":"Two adversarial audit rounds — BLOCK (5 Critical, 6 High, 11 Medium) then REQUEST CHANGES (1 Critical, 6 High, 8 Medium) — all findings fixed and re-verified; 114/114 tests green.","evidence":[{"type":"github","url":"https://github.com/spreadzp/agentbadge/tree/main/docs/EPICS/220-payment-infrastructure-foundation/reviews"}]}],"canonical":"https://agentbadge.xyz/blog/payment-infrastructure-foundation","dates":{"published":"2026-11-10","modified":"2026-11-10"},"markdownUrl":"https://agentbadge.xyz/blog/payment-infrastructure-foundation.md","jsonUrl":"https://agentbadge.xyz/blog/payment-infrastructure-foundation.json","shortAnswer":"We built @agentbadge/payments — a payment domain model that treats Payment, PaymentAttempt, PaymentReceipt and PaymentEvent as durable entities separate from whatever rail actually moves the money. All state changes flow through two transition maps with guarded writes, every CONFIRMED requires a 9-check verification verdict, idempotency runs at two levels (request fingerprint + claim-first side effects), and money is a decimal string end-to-end. Two adversarial AI audits (5 Critical + 6 High + 11 Medium, then 1 Critical + 6 High + 8 Medium) and a live Stripe test-mode run later: CONFIRMED → REFUNDED, concurrent refunds → one rail refund, 114/114 tests green.","technologies":["TypeScript","Bun","Stripe","Prisma","Vitest","BigInt","Zod"],"entities":["agentbadge-payments-package","epic-220","payment-service","stripe-payment-provider","fake-provider","expiry-sweeper","economic-ledger-article","arc-c32-payment-forensics-article","keyless-signer-article"]}