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:

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:

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.