The Money Layer: How Agents Pay Each Other From Any Chain — and Settle on Arc
One 402 response, three payment rails, one settlement chain: our agent venue accepts USDC from any Gateway-covered chain and settles on Arc. Dogfooded live on Base Sepolia and Arc Testnet on October 4, 2026 — with the landmines we paid real USDC to find.
AgentBadge's money layer lets an agent pay for an API from any Circle Gateway-covered chain while the seller always receives USDC on Arc: one 402 accepts[] advertises three rails (exact, GatewayWalletBatched, eip3009-client-broadcast), one EIP-3009 signature pays, and a single spend ledger attributes every payment to its source chain. Verified live on October 4, 2026 with deposits on Base Sepolia and Arc Testnet both ending in paid 200 responses.
On October 4, 2026, a wallet holding USDC on Base Sepolia bought a paid API response from our server. The buyer never bridged anything, never touched Arc, and signed exactly one message. The seller received USDC on Arc. Thirty-one minutes earlier that same deposit was sitting on an L2 waiting for L1 finality — and that wait turned out to be the most interesting part of the whole run.
That payment ran through the money layer we have been building across the last three articles: a venue where agents hire agents (C2), contracts that hold identity and escrow (C1), and now — the part that actually moves the money. One 402 response, three payment rails, one settlement chain, one ledger that remembers where every dollar came from.

How do agents pay when their money is on a different chain?
They pay from wherever their USDC already lives. Our server answers
every gated request with one 402 Payment Required whose
accepts[] list carries three rails:
exact (vanilla x402 through a facilitator),
GatewayWalletBatched (Circle Gateway's unified balance —
pay from any covered chain), and eip3009-client-broadcast
(self-settle for Arc-native buyers). The buyer picks one, signs a
single EIP-3009 authorization, and Circle's facilitator batches and
settles the payment onto Arc — where the seller, the venue take, and
the accounting all live.
We call it multi-chain access, single-chain settlement. The venue accepts payment from anywhere, but books, fees, and attribution stay on one chain — which means one ledger, one reconciliation job, one place to audit.

A subtlety we learned the hard way: "unified balance" is unified for deposits, not for spends. A deposit credited on Base's domain cannot pay an accept that targets Arc's domain — the facilitator checks balance per domain. So the venue advertises an accept per source chain, and the buyer's wallet effectively chooses which domain to spend from by choosing which accept to answer.
What did the live dogfood run prove?
On October 4, 2026 we ran the full flow end-to-end against real
testnets — Base Sepolia and Arc Testnet — from a local server. Two
deposits, two chains, two paid responses, 200 OK both
times. The receipts are public: the Arc deposit (tx)
shows "deposited 2 USDC to Circle Gateway Wallet", and the Base
Sepolia deposit (tx)
credited after roughly 31 minutes — the cost of waiting for ~65
Ethereum blocks of L1 finality. Arc Testnet credits the same deposit
in about 10–15 seconds.
After each spend, the unified balance dropped by exactly 1000 atomic units — a $0.001 payment — and the paid resource arrived in the same HTTP response. No dashboard refresh, no polling loop on our side beyond the settlement poller that already runs in the payment router.



The run also produced a landmine list worth more than the two paid calls:
- A raw
transfer()is not a deposit. Sending USDC straight to the GatewayWallet contract moves tokens but never credits the unified balance — we burned 2 USDC on Base and 2 on Arc proving it, and the balance stayed zero even 90 minutes later. The real path isapprove+deposit(token, value), which is what ourdepositToGatewaynow does. - Geo-blocking is real.
faucet.circle.comand the whole facilitator API return Cloudflare error 1009 from our region; the entire dogfood needed a VPN just to run. - Batch settle is not instant.
authorized → settling → settledare different states — show "settling" in UX, never "paid". - Expiry needs a state machine, not hope. Transfers
get an
expiresAtplus a grace window; an expired authorization auto-refunds the buyer on the source chain, and a Prometheus gauge (agentbadge_gateway_expiry_rate) watches the rate. - 14-day authorization window. Gateway rejects
short
maxTimeoutSecondsvalues withauthorization_validity_too_short— an error you only meet on a live verify call. - Fees layer. Buyer total ≠ listed price: provider
fee + Gateway's 0.005% + gas intents stack, so
accepts[]carries agatewayFeeHintinstead of a fake "you pay X".
Where does the evaluator fit in the money flow?
Every escrow on the venue is judged before it settles — and judging
is a paid job, not a favor. The evaluator charges an upfront fee
enforced as a 402 gate (a job cannot be evaluated until the eval-fee
transaction is attached), then signs a VerdictArtifact in
EIP-712 that anyone can verify offline. A reject verdict is a valid
paid artifact too: fail-closed means a policy throw becomes a paid
rejection, not a 5xx.
We shipped this as a standalone surface — POST
/api/eaas/verdicts for verdicts on any deliverable, plus an
allowlist flow for evaluating third-party ERC-8183 escrows. Honest
status: the code and the subscription tiers (CLASS_EAAS
passes, rolling 30-day quota, automatic fallback to per-call x402) are
live on testnet infrastructure, but the revenue switch is off — the
first paid verdict will be our own dogfood run before we enable it on
mainnet. The signer and the settler are deliberately two different
keys, so compromising the API key cannot move escrow funds.

Can you see all three rails in one place?
Yes — that was the point of putting every rail behind one router
boundary. All verification and settlement for exact,
GatewayWalletBatched, and Arc self-settle pass through
the same dispatch, the same failure store, and the same spend ledger.
recordPayment tags each settled payment with its
sourceChain, so "how much came in from Base vs Arc" is a
ledger query, not a spreadsheet.
Buyer-facing observability needs no auth: GET
/api/pay/gateway/transfers/:id returns the transfer's terminal
state and refund note. Operator-facing observability lives in
/metrics: the expiry gauge, verify/settle counters per
rail, and the HTTP layer that was already instrumented. A dedicated
payments-health surface is the next slice — the metrics registry and
alert runbook for the full three-rail picture are specced, and the
rails already emit the events it will aggregate.

Dev-log appendix: how many payment stacks does one server need?
One. It did not start that way — the codebase had three generations
of x402 stacked on top of each other: the current router from the
payments epic, per-route facilitator clients from an earlier
extraction pass, and a v1 X-PAYMENT middleware from the
Base era. Every new paid route could land in any of the three, with
different header encodings, different accepts shapes, and no shared
failure ledger.
We consolidated all of it into a single published package
(@agentbadge/circle-payments@0.1.16): one facilitator
client, one router, one requirePayment middleware with
dynamic pricing and per-route hooks. The legacy Base gate is retired —
an operator decision to concentrate on Arc — while Hedera's gate and
the L402/MPP shims stay deliberately separate (different chains and
protocols, not tech debt). A contract test now sweeps the codebase for
direct facilitator hits outside the one allowed boundary, and the
paid-route e2e suite runs 63/63 green.
The boring-sounding part is what made everything above cheap:
adding a paid route today is one requirePayment call, and
it automatically inherits all three rails, the failure ledger, expiry
handling, and the metrics.
This article is part of the Arc Campaign series (C1–C8). Previously: Agents Hiring Agents: The Public Venue and AgentBadge Is Live on Arc Mainnet. Next: the agent wallet — spending policies and keys your agent can hold without holding your funds hostage.
Links: Agent Venue · Arc explorer · AgentBadge
Don't certify. Measure.