The x402 Buyer Stack: How Agents Actually Pay
Every x402 post in this series so far covered the side that gets paid: schemes, facilitators, discovery, settlement. This one walks the other half — the client that receives a 402, decides whether to pay, signs, and retries. That code path is where an agent's money actually leaves the wallet.
The buyer stack is deceptively small. The canonical integration is one wrapper around fetch. But hidden behind that one line is the entire decision surface of an autonomous buyer: which chain to pay on, which key signs, what limits apply, and what happens when payment creation fails. As of version 2.19.0, published on 2026-07-17, the official SDKs expose all of it — and most teams are only using the wrapper.
The buyer's half of the handshake
The protocol flow, seen from the client, is four steps. The wrapped fetch makes the initial request. If the server answers 402 Payment Required, the SDK parses the accepts array of payment requirements, creates and signs a payment payload for one of them, and retries the request with the PAYMENT-SIGNATURE header. The buyer quickstart describes exactly this sequence, and it is the same v2 transport we mapped from the server side in the facilitator deep dive.
The receipt comes back the same way it went out: as a header. @x402/fetch ships a decodePaymentResponseHeader helper, and the higher-level x402HTTPClient wraps the whole round trip — processResponse returns the decoded settlement response alongside the body. If the previous posts taught anything, it is that clients should keep those receipts: the transaction hash inside is the only artifact that lets you audit a facilitator's claims against an independent RPC.
One client, every rail
The v2 SDK re-architecture split the buyer stack into orthogonal packages inside the x402-foundation monorepo: @x402/core for protocol types, mechanism packages like @x402/evm and @x402/svm for scheme implementations, and HTTP bindings — fetch, axios, plus server-side express, fastify, hono and next — versioned in lockstep. The composition happens in the x402Client builder, keyed by CAIP-2 network patterns:
import { x402Client, wrapFetchWithPayment, x402HTTPClient } from '@x402/fetch';
import { ExactEvmScheme } from '@x402/evm/exact/client';
import { UptoEvmScheme } from '@x402/evm/upto/client';
import { ExactSvmScheme } from '@x402/svm/exact/client';
const client = new x402Client()
.register('eip155:*', new ExactEvmScheme(evmSigner)) // all EVM chains
.register('eip155:1', new ExactEvmScheme(mainnetSigner)) // mainnet override
.register('eip155:*', new UptoEvmScheme(evmSigner))
.register('solana:*', new ExactSvmScheme(svmSigner));
const fetchWithPayment = wrapFetchWithPayment(fetch, client);
const response = await fetchWithPayment('https://api.example.com/paid');
const result = await new x402HTTPClient(client).processResponse(response);
Two details matter here. First, specific patterns take precedence over wildcards — eip155:1 with a dedicated mainnet signer overrides the eip155:* catch-all. That is how you keep a low-value hot key for testnets and a separately controlled key for mainnet in the same process. Second, schemes stack: registering UptoEvmScheme alongside ExactEvmScheme means the client can answer sellers that quote metered upto prices as well as fixed exact ones. The buyer side of upto is deliberately boring — the SDK signs the max authorization and the buyer is charged the actual settled amount.
The breadth is larger than most people assume. Beyond EVM and Solana, the official client examples register scheme implementations for Stellar, Keeta, Aptos, Concordium, Hedera and XRPL — each behind the same register(pattern, scheme) call. The buyer does not pick a rail at integration time; it declares which rails it can sign for, and the seller's accepts array decides the intersection at request time.
The policy surface: hooks and selectors
This is the part of the buyer stack that matters for autonomous agents, and the part almost nobody writes about. x402Client exposes three payment lifecycle hooks, chainable on the builder:
const client = new x402Client()
.register('eip155:*', new ExactEvmScheme(signer))
.onBeforePaymentCreation(async ctx => {
if (exceedsBudget(ctx.selectedRequirements)) {
return { abort: true, reason: 'daily budget exhausted' };
}
})
.onAfterPaymentCreation(async ctx => {
audit.log(ctx.paymentPayload); // receipts, metrics, alerts
})
.onPaymentCreationFailure(async ctx => {
// return { recovered: true, payload: alternative } to retry
});
onBeforePaymentCreation runs before anything is signed and can abort by returning { abort: true, reason }. That makes it the natural seat for spend policy: per-request price caps, daily budgets, allowlists of payees. onAfterPaymentCreation is the observability tap — every signed payload flows through it, which is exactly where an agent operator should be recording receipts. onPaymentCreationFailure can recover by returning an alternative payload, which enables fallback logic across networks or tokens — the payments analog of the model fallback chains we use on the inference side.
Network choice is a separate, cleaner extension point. The x402Client constructor accepts a selector function that receives the full list of payment requirements from the 402 and returns the one to pay. The official example implements ordered preferences — try EVM first, then Solana, then Stellar — with a fallback to the first mutually supported option. For a fleet operator this is a cost lever: when a seller accepts both an L2 and Solana at the same nominal price, the selector is where you encode which rail is cheaper for you to top up, custody and reconcile.
Custody: three ways to hold the key
The examples all start from privateKeyToAccount(process.env.EVM_PRIVATE_KEY), and that is fine for a testnet demo and dangerous for production, for the reasons we detailed in the account abstraction deep dive: a raw key in an agent's environment is a permanent, unlimited spend mandate. The buyer stack currently offers three custody postures. Raw keys via viem or @solana/kit signers. Managed wallets — Coinbase's CdpX402Client plugs a CDP-managed wallet into wrapFetchWithPayment so the process never handles a private key at all. And scoped delegation — session keys and spend permissions — which the SDK meets through its signer abstraction: anything that can produce the scheme's signature can be registered, including a session key whose limits are enforced on-chain rather than in a hook.
One more buyer-side convenience is easy to miss: passing an EVM_RPC_URL enables gas sponsoring extensions (EIP-2612 permits and ERC-20 approvals), letting the client handle tokens beyond the native EIP-3009 path without the agent pre-funding gas. The RPC is used for on-chain reads; the signing model stays the same.
Beyond fetch: axios, Python, MCP
The same client core rides other transports. @x402/axios (also 2.19.0) does the intercept-and-retry dance for axios users. Python buyers get pip install "x402[httpx]" and an x402HttpxClient that wraps httpx the way wrapFetchWithPayment wraps fetch. And @x402/mcp closes the loop for tool-calling agents: createX402MCPClient takes the same scheme registrations plus an autoPayment flag and an onPaymentRequested callback that returns true or false — a per-tool-call payment gate, so an MCP tool that costs $0.10 is approved or denied by policy before any signature exists. For agents whose entire interface to the world is MCP, that callback is the buyer stack.
What it means for LLM4Agents
LLM4Agents sits on both sides of this handshake. As a seller, the gateway prices inference behind Bearer deposits and x402 walk-up, per the decision tree we published. But the agents our operators run are buyers: they call external paid APIs, x402-priced MCP tools, and data services discovered through Bazaar. The buyer stack is the last mile between an agent runtime and every settlement rail this series has covered — and its policy surface (hooks, selectors, payment gates) is exactly the shape of the spend controls our operators keep asking for, but enforced client-side, per agent, rather than platform-side, per account.
That is both an opportunity and a threat. Opportunity: a platform that ships a pre-configured buyer client — budget hooks wired to platform billing, receipts wired to platform observability — removes the sharpest edge of agent autonomy for its users. Threat: if spend policy standardizes inside the open-source client, the platform's own billing layer must interoperate with it rather than replace it, or operators will route around the platform for outbound payments.
Staying on the frontier
Concrete sequence for the platform, in priority order:
- Ship a buyer preset. A thin package that returns a pre-wired
x402Client: budget enforcement inonBeforePaymentCreation, receipt capture inonAfterPaymentCreation, cross-network recovery inonPaymentCreationFailure, defaults for Base and Solana. - Feed hooks into observability. Every signed payload and every abort reason should land in the same dashboard that tracks token spend — outbound payments are a cost stream like inference.
- Adopt upto on the buy side. Register
UptoEvmSchemeby default so platform agents can consume metered sellers like Apify without integration work. - Offer managed custody tiers. Raw key for sandbox, managed wallet or session-key signer for production — aligned with the on-chain limits from the account abstraction post, so the hard boundary never lives in a callback.
- Wire
@x402/mcpinto the tool layer. TheonPaymentRequestedgate should consult the same budget as the HTTP hooks, so one policy governs both transports.
The x402 arc on this blog now covers schemes, settlement, facilitators, discovery — and, with this post, the client that pays. What remains is the part no SDK ships: deciding, per agent and per dollar, when paying is worth it. That is an economics problem, and it is where agent platforms will actually compete.
Give your agents a wallet with limits
Fund agents in stablecoins, meter usage per call, and keep spend policy out of the prompt.
Register your agent