How to keep receipts for x402 agent payments
A practical guide · 10 minutes · updated 27 September 2026
Agents that pay over x402 buy data, model calls and tools a fraction of a cent at a time, thousands of times a day. Each payment settles on-chain in USDC, which is excellent evidence of money moving and useless evidence of what was bought. This guide shows how to turn that stream into records a finance team can close a month with: what to capture, how to reconcile it against the chain, and how to make it verifiable by an auditor who doesn't trust you.
1. What a receipt for an x402 purchase needs to contain
The x402 flow gives you everything at the moment of purchase, if you capture it before it's gone:
- The resource — the URL that was bought, and the HTTP method.
- The price and the counterparty — from the
PAYMENT-REQUIREDchallenge: amount, asset, network (CAIP-2),payTo. - The settlement reference — the transaction hash or signature from the
PAYMENT-RESPONSEheader once the facilitator settles. - Fingerprints of the request and the response — sha256 of what was sent and what came back. Not the content: a hash is enough to prove later that nothing changed, and it keeps the content private.
- Delivery status — did the seller answer 200, or did the money leave for nothing?
- The seller's own signed receipt, when the seller implements the x402
offer-receiptextension. That is the only piece of evidence that comes from the other side.
2. Capture it where the payment happens
The cleanest place is the fetch the agent already pays with. Wrap it once; every paid call is recorded in the background, and the agent's code doesn't change:
import { wrapFetchWithPayment } from "@x402/fetch";
import { withRegister } from "x402receipts-sdk";
const register = withRegister(fetch, { endpoint: "https://app.x402receipts.com", payWith: () => pay });
const pay = wrapFetchWithPayment(register, wallet);
// use `pay` exactly as before
Two rules worth copying even if you build your own: the recorder must never throw and never delay a request (an accounting hiccup should not break an agent), and it must skip its own uploads (otherwise it records itself forever).
3. Reconcile against the chain, not against your own logs
A log written by the agent is a record the agent produced. What finance needs is a comparison with an independent source: the payments that actually left the wallet. Read the wallet's outgoing USDC transfers on Base and Solana, and match each one to a receipt — first by transaction reference, then by counterparty, amount and time. What's left over is the interesting part:
- Payment with no receipt — money left, nothing recorded. An agent running without the recorder, or a transfer that wasn't a purchase (funding a wallet, moving funds).
- Receipt with no delivery — paid, the seller returned an error or nothing.
Read the chain from two independent sources if you can. Public explorers occasionally skip a block; a payment that fell through the gap would otherwise be missed for good.
4. Funding is not the expense
The transfer from the company's bank (or treasury wallet) into the agent's wallet is a funding movement. The economic transactions are the wallet-to-seller payments after it. Book the funding as a transfer between accounts; book the purchases from the receipts. This is the distinction most agent-spend reports get wrong, and it's why "USDC left the treasury" is not an expense line.
5. Make the record verifiable without you
Fingerprint every receipt, group them (a day is a good unit), build a Merkle tree and write the root to a public ledger whose timestamps you don't control. From that moment any receipt can be checked by anyone with the receipt and the path: recompute the hash, fold it to the root, read the root on the ledger. If a single character changed, it fails. Keep the contents private — only the root goes public.
x402receipts does this nightly on the Hedera Consensus Service and gives every receipt a public verification page that redoes the maths in the reader's browser.
6. What month end looks like
Total spent, spend by supplier, the number of purchases and how many are verified, and the exceptions that need a human. Every line traceable: month total → supplier → payment → receipt → transaction hash → anchored proof. Export it as CSV for the books and keep the signed JSON for the auditor.
The format, written down
Everything above — the receipt fields, the canonical form, the fingerprint, the Merkle batching, the anchor record and the verification algorithm — is published as ARR-1, a public-domain specification with JSON Schemas. If you build your own, build it against that; if you use ours, you can check it against that.
Doing it with x402receipts
One wrapper around the paying fetch (above), or the REST endpoint, or the MCP server. No API key: the agent's wallet is the account, and it pays USD 1 per calendar month over x402. The owner signs in with the same wallet and gets the statement. The integration prompt does the wiring for you in Claude Code or Cursor.