Skip to content
Back to blog
developer-guide14 min

Building Agentic Commerce #4: x402 Stablecoin Payments — When Agents Pay in USDC

How AI agents make on-chain USDC payments using the x402 protocol — multi-chain settlement, EIP-712 signatures, and production-ready stablecoin checkout.

Executive summary

Part 4 of 'Building Agentic Commerce' explains the x402 stablecoin payment protocol — how AI agents discover x402-enabled merchants, sign EIP-712 authorizations, settle on-chain via facilitators, and handle retries with exponential backoff. Covers 5 supported chains, USDC amount conversion, SSRF protection, and 197 tests.

Published

2026-04-06

14 min

Author

Trusteed Engineering

Core Protocol Team

Category

developer-guide

x402stablecoinUSDCcrypto paymentsEIP-712Baseagentic commerceMCPsettlementmulti-chain

In the first three parts of this series, we covered <a href='/en/blog/building-agentic-commerce-multi-protocol-checkout'>multi-protocol checkout</a>, <a href='/en/blog/building-agentic-commerce-agent-discovery-nlweb'>agent discovery via NLWeb</a>, and <a href='/en/blog/building-agentic-commerce-trust-scores'>trust scores</a>. Now we tackle the protocol that makes agents truly autonomous: <strong>x402 — stablecoin payments where agents pay directly on-chain in USDC</strong>.

Why Stablecoin Payments Matter for Agents

Traditional payment protocols (card networks, PayPal) require human identity — a cardholder, a PayPal account, a billing address. AI agents don't have these. The x402 protocol solves this by using wallet-based authentication: an agent proves it can pay by signing a cryptographic authorization, and settlement happens on-chain without any human identity requirement.

The HTTP 402 status code ("Payment Required") was reserved in the original HTTP specification but never standardized. The x402 protocol finally gives it a concrete implementation: when a server returns HTTP 402, it includes a machine-readable payment requirement that an agent can fulfill autonomously.

How x402 Works: The Complete Flow

The x402 payment flow involves three parties: the <strong>agent</strong> (buyer with a crypto wallet), the <strong>merchant</strong> (seller with a receiving wallet), and the <strong>facilitator</strong> (signature verifier and on-chain settler). Here's the step-by-step flow:

Step 1: Agent Requests a Resource

The agent sends an HTTP request to the merchant's checkout endpoint. The protocol detector identifies x402 via headers — <code>PAYMENT-SIGNATURE</code> (V2 format, confidence 0.95) or <code>X-PAYMENT</code> (V1 legacy, confidence 0.90). An explicit <code>X-Protocol: X402</code> header yields confidence 1.0. <pre><code>POST /api/v1/agent/checkout HTTP/1.1 Host: api.trusteed.xyz Content-Type: application/json PAYMENT-SIGNATURE: eyJzaWduYXR1cmUiOiIweGFiYy4uLiIsImF1dGhvcml6YXRpb24iOnsiZnJvbSI6IjB4MTExMSIsInRvIjoiMHgyMjIyIiwidmFsdWUiOiI1MDAwMDAwIiwidmFsaWRBZnRlciI6IjE3MTI1MDAwMDAiLCJ2YWxpZEJlZm9yZSI6IjE3MTI1MDM2MDAiLCJub25jZSI6IjB4ZGVhZGJlZWYifSwic2NoZW1lIjoiZXhhY3QiLCJuZXR3b3JrIjoiYmFzZSJ9 {"items": [{"productId": "prod_001", "quantity": 1}]}</code></pre>

Step 2: Server Returns HTTP 402

If the merchant has x402 enabled, the outbound adapter builds a <code>PaymentRequired</code> object with the merchant's wallet, network, and USDC token address. This is base64-encoded into the <code>PAYMENT-REQUIRED</code> header: <pre><code>HTTP/1.1 402 Payment Required PAYMENT-REQUIRED: eyJzY2hlbWUiOiJleGFjdCIsIm5ldHdvcmsiOiJiYXNlIi4uLn0= { "paymentRequired": { "scheme": "exact", "network": "base", "maxAmountRequired": "5000000", "payTo": "0x2222...merchant_wallet", "maxTimeoutSeconds": 1800, "extra": { "tokenAddress": "0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913", "name": "USDC", "version": "2" } }, "facilitator": { "verifyUrl": "https://x402.org/facilitator/verify", "settleUrl": "https://x402.org/facilitator/settle" } }</code></pre>

The amount <code>5000000</code> represents 5 USDC. USDC uses 6 decimal places, so 1 USDC = 1,000,000 smallest units. The conversion: USD cents × 10,000 = USDC smallest units.

Essential insight

Step 3: Agent Signs and Settles

The agent reads the <code>PaymentRequired</code>, signs an EIP-712 typed data authorization with its private key, and submits to the settlement endpoint. The V2 authorization includes replay protection (<code>nonce</code>), time bounds (<code>validAfter</code>, <code>validBefore</code>), and the exact amount:
<pre><code>// V2 PAYMENT-SIGNATURE payload (base64-decoded) { "signature": "0xabc123...eip712_sig", "authorization": { "from": "0x1111...agent_wallet", "to": "0x2222...merchant_wallet", "value": "5000000", "validAfter": "1712500000", "validBefore": "1712503600", "nonce": "0xdeadbeef" }, "scheme": "exact", "network": "base" }</code></pre>

Step 4: Settlement with Exponential Backoff

The settlement service orchestrates a multi-phase process: (1) mark the order as <code>x402_pending_payment</code>, (2) verify the signature via the facilitator's <code>/verify</code> endpoint — if invalid, the order fails immediately with no retry, (3) attempt settlement via <code>/settle</code> with up to 5 retries using exponential backoff (5s → 10s → 20s → 40s), and (4) update the order to <code>completed</code> with the on-chain transaction hash, or <code>x402_failed</code> if all retries are exhausted.
<pre><code>// Settlement retry logic (simplified) for (let attempt = 0; attempt < 5; attempt++) { if (attempt > 0) { await sleep(5000 * Math.pow(2, attempt - 1)); // 5s, 10s, 20s, 40s } const result = await fetch(facilitator.settleUrl, { method: "POST", body: JSON.stringify({ paymentPayload, paymentRequired }), signal: AbortSignal.timeout(15_000) // 15s per-request timeout }); if (result.success) { return { status: "COMPLETED", txHash: result.txHash }; } } return { status: "FAILED" };</code></pre>

Supported Chains and Tokens

Trusteed supports x402 payments across 5 blockchain networks, all using USDC as the settlement token:

  • 1
    <strong>Base</strong> — USDC at <code>0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913</code> (recommended: lowest fees)
  • 2
    <strong>Ethereum</strong> — USDC at <code>0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48</code>
  • 3
    <strong>Polygon</strong> — USDC at <code>0x3c499c542cEF5E3811e1192ce70d8cC03d5c3359</code>
  • 4
    <strong>Arbitrum</strong> — USDC at <code>0xaf88d065e77c8cC2239327C5EDb3A432268e5831</code>
  • 5
    <strong>Solana</strong> — USDC at <code>EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v</code>

Merchants can override the default USDC address with a custom <code>tokenAddress</code> in their protocol configuration. A <code>maxTransactionAmount</code> safety cap is also supported.

Essential insight

Amount Conversion: USDC ↔ USD Cents

The bridge converts between USD cents (used internally for multi-protocol compatibility) and USDC smallest units (on-chain representation). The math is straightforward: <pre><code>// Inbound: USDC smallest units → USD cents // 1 USDC (1,000,000 units) = 100 cents → divide by 10,000 const cents = parseInt(usdcSmallestUnit) / 10_000; // Example: "5000000" (5 USDC) → 500 cents ($5.00) // Outbound: USD cents → USDC smallest units const usdc = String(Math.round(cents * 10_000)); // Example: 500 cents → "5000000" (5 USDC)</code></pre>

Safety checks prevent sub-cent precision errors (values must be divisible by 10,000), reject negative amounts, and enforce IEEE-754 safe integer bounds (~$9 billion max).

Protocol Detection: How x402 Is Identified

x402 is one of 8 payment protocols in the Trusteed detection system. The multi-protocol detector assigns confidence scores to determine which adapter handles each request:

  • 1
    <code>X-Protocol: X402</code> header → confidence <strong>1.0</strong> (explicit declaration)
  • 2
    <code>PAYMENT-SIGNATURE</code> header (V2) → confidence <strong>0.95</strong>
  • 3
    <code>X-PAYMENT</code> header (V1 legacy) → confidence <strong>0.90</strong>
  • 4
    Body shape match (<code>paymentPayload</code>, <code>x402</code>, or <code>paymentRequired</code> fields) → confidence <strong>0.85</strong>
  • 5
    No match → falls back to ACP at confidence 0.5

This means x402 coexists with ACP, UCP, PayPal, Visa VIC, Mastercard Agent Pay, and other protocols. The highest-confidence adapter wins, and the protocol bridge routes the payment to the correct settlement path.

Merchant Configuration

Merchants enable x402 by adding a protocol configuration with their wallet address and preferred network: <pre><code>// Stored in MerchantProtocol.config (database) { "protocol": "X402", "enabled": true, "priority": 100, "config": { "walletAddress": "0xAbCd...merchant_wallet", "network": "base", "facilitatorUrl": "https://x402.org/facilitator", "supportedTokens": ["USDC"], "maxTransactionAmount": 100000000 // 100 USDC safety cap } }</code></pre>
The configuration validator enforces SSRF protection — private/internal URLs (127.0.0.1, 10.x.x.x, localhost) are rejected for the <code>facilitatorUrl</code>. Wallet addresses are validated for both EVM (0x + 40 hex chars) and Solana formats.

Security Model

  • 1
    <strong>No sensitive data in audit logs</strong> — wallet addresses, signatures, and nonces are never stored in OrderEvent records. Only protocol name, network, and transaction hash references are logged.
  • 2
    <strong>Facilitator-delegated verification</strong> — the bridge never validates EIP-712 signatures locally (no key material on the server). Verification is delegated to the facilitator's <code>/verify</code> endpoint.
  • 3
    <strong>Atomic state transitions</strong> — order status updates use database-level atomicity. The expiration job double-checks status before updating to prevent race conditions.
  • 4
    <strong>SSRF protection</strong> — merchant-provided facilitator URLs are validated against private IP ranges and internal hostnames.
  • 5
    <strong>15-second fetch timeout</strong> — all facilitator requests have a hard timeout to prevent hanging connections.

Order Status State Machine

x402 orders follow a strict state machine: <pre><code>┌──────────┐ verify ┌──────────────────────┐ │ PENDING │ ──────────────→ │ x402_pending_payment │ └──────────┘ └──────────┬───────────┘ │ ┌─────────────┼─────────────┐ ↓ ↓ ↓ ┌───────────┐ ┌───────────┐ ┌─────────┐ │ completed │ │ x402_failed│ │ expired │ └───────────┘ └───────────┘ └─────────┘ Terminal states cannot be overwritten. Expiration: 30-minute background job catches stuck payments.</code></pre>

V1 vs V2 Header Format

The x402 implementation supports two header formats. <strong>V2 (PAYMENT-SIGNATURE)</strong> is the current standard with full security: replay protection via <code>nonce</code>, time-bounded validity (<code>validAfter</code>/<code>validBefore</code>), and structured EIP-712 typed data. <strong>V1 (X-PAYMENT)</strong> is maintained for backward compatibility but lacks nonce and time bounds, making it less secure. New integrations should always use V2.

Production Tips

  • 1
    <strong>Choose Base for lowest fees</strong> — L2 transaction costs are a fraction of Ethereum mainnet. Most agent-to-merchant payments are small (<$100), making Base the optimal default.
  • 2
    <strong>Set maxTransactionAmount</strong> — a per-merchant safety cap prevents accidental large settlements. Start conservative (e.g., 100 USDC) and increase as trust builds.
  • 3
    <strong>Monitor the expiration job</strong> — orders stuck in <code>x402_pending_payment</code> for >30 minutes indicate facilitator issues or network congestion. Set up alerts on the <code>x402_payment_expired</code> OrderEvent.
  • 4
    <strong>Use V2 headers exclusively</strong> — V1 lacks replay protection. Disable V1 support in production if your agent ecosystem supports V2.
  • 5
    <strong>Handle 402 responses gracefully</strong> — when building agent clients, parse the <code>PAYMENT-REQUIRED</code> header, extract the facilitator URLs, and implement the sign-and-settle flow. The facilitator handles all on-chain complexity.

Test Coverage

The x402 implementation is backed by 197 test cases across 6 test files (~2,554 lines of test code). Coverage includes: detection (8 tests), normalization (12 tests), settlement with backoff (45+ tests), configuration validation with SSRF (18 tests), end-to-end integration (22 tests), and 92+ edge cases covering precision errors, timeouts, network failures, and concurrent state updates.

What's Next

In <strong>Part 5</strong>, we'll explore <strong>UCP — Shopify's Universal Commerce Protocol</strong> and how it enables agent-driven commerce across the Shopify ecosystem. Stay tuned.

Frequently asked questions

What is x402 and how does it relate to HTTP 402?

x402 is a payment protocol that implements the long-reserved HTTP 402 (Payment Required) status code. When a server returns 402, it includes a machine-readable PaymentRequired object that AI agents can fulfill autonomously using USDC stablecoin payments on-chain.

Which blockchains does x402 support?

Trusteed supports x402 on 5 networks: Base (recommended for lowest fees), Ethereum, Polygon, Arbitrum, and Solana. All use USDC as the settlement token with well-known contract addresses per chain.

How does x402 handle failed settlements?

The settlement service uses exponential backoff with up to 5 retry attempts (delays of 5s, 10s, 20s, 40s). Each facilitator request has a 15-second timeout. If all retries fail, the order is marked x402_failed. A background job expires stuck orders after 30 minutes.

Is x402 secure? How are signatures verified?

Yes. x402 V2 uses EIP-712 typed data signatures with replay protection (nonce) and time bounds. Signature verification is delegated to the facilitator — no private key material exists on the server. Wallet addresses and signatures are never stored in audit logs.

Can x402 work alongside other payment protocols?

Absolutely. x402 is one of 8 payment protocols in the Trusteed detection system. The multi-protocol detector assigns confidence scores, and the highest-confidence adapter wins. If a merchant doesn't have x402 enabled, the bridge falls back to their preferred protocol (ACP, PayPal, etc.).

Sources and references

Related articles

x402 Stablecoin Payments for AI Agents | Building Agentic Commerce #4 | Trusteed