x402 Payment

How the x402 Gateway handles on-chain USDC payment.

Overview

The x402 protocol extends HTTP with payment semantics using the 402 Payment Required status code. When the gateway requires payment, it returns a 402 response with a machine-readable payment quote. The client signs an on-chain USDC transfer and retries the request.

With the SDK (autoPayment: true), this entire flow is handled automatically. This document explains the protocol internals for advanced developers and debugging.

How x402 works

The x402 protocol relies on EIP-3009 (transferWithAuthorization), an extension of ERC-20 that enables gasless, off-chain authorized transfers:

  1. The payer (agent) signs a transfer authorization off-chain — specifying from, to, value, expiration time, and a random nonce.
  2. The signed payload is sent to the payee (gateway) via HTTP header.
  3. The payee forwards it to a Facilitator, which verifies the signature and broadcasts the transaction on-chain.
  4. The ERC-20 transfer executes — tokens move from payer to payee — and the Facilitator bears the gas cost.

This design means:

  • No prior token approval needed (unlike standard ERC-20 approve + transferFrom)
  • Payer never submits on-chain transactions — no gas costs for the agent
  • Single-use authorization — each signature is nonce-bound and can only be used once

Protocol flow

Protocol headers

HeaderDirectionDescription
PAYMENT-REQUIREDResponseBase64 JSON quote (amount, network, asset, payTo)
PAYMENT-SIGNATURERequestBase64 JSON payload with signed authorization
PAYMENT-RESPONSEResponseSettlement confirmation details

Two billing models

The gateway uses two distinct payment models depending on the service:

ServiceModelWhen payment happens
ZAN Node Service (RPC)Credit prepurchaseBuy credits upfront, deduct per call
ZAN AI Service (MaaS)Rolling settlementFirst call free, settle previous call's cost on next call

Model 1: Credit prepurchase (RPC)

Credits are purchased via x402 payment, then consumed per RPC call based on method weight.

How it works:

  1. Agent requests POST /credits/purchase/default → Gateway returns 402 + PAYMENT-REQUIRED quote
  2. SDK signs an EIP-3009 transferWithAuthorization for the quoted USDC amount
  3. Agent retries with PAYMENT-SIGNATURE header → Gateway calls Facilitator to verify and settle on-chain
  4. Credits are added to the agent's balance → Agent can now make RPC calls (credits deducted per method weight)

Credit bundles

Network TypePriceCreditsApprox. Calls
Mainnet0.015 USDC100,0005,000 – 20,000
Testnet1 USDC100,0005,000 – 20,000

PAYMENT-REQUIRED quote (decoded)

{
  "x402Version": "2",
  "error": "payment_required",
  "message": "Payment required to purchase default credits bundle",
  "accepts": [
    {
      "scheme": "exact",
      "network": "eip155:8453",
      "asset": "0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913",
      "payTo": "0xC26...",
      "maxAmountRequired": "15000"
    }
  ]
}

maxAmountRequired is in USDC atomic units (6 decimals). "15000" = 0.015000 USDC.

PAYMENT-SIGNATURE payload

{
  "x402Version": "2",
  "scheme": "exact",
  "network": "eip155:8453",
  "payload": {
    "signature": "<EIP-3009 TransferWithAuthorization signature>",
    "authorization": {
      "from": "<payer wallet address>",
      "to": "<payee address>",
      "value": "15000",
      "validAfter": "0",
      "validBefore": "<expiration timestamp>",
      "nonce": "<random nonce>"
    }
  },
  "domain": {}
}

Model 2: Rolling settlement (AI)

AI calls use a pay-after-use model. The actual token cost is known only after the upstream model responds.

How it works:

  1. First call: Agent sends POST /ai/{model} → Gateway forwards to upstream (no payment needed) → Response returned, token usage recorded as pending
  2. Subsequent calls: Agent sends POST /ai/{model} → Gateway checks previous record → Returns 402 requesting payment for previous call's token cost
  3. SDK signs USDC payment for the exact token cost → Agent retries with PAYMENT-SIGNATURE → Gateway verifies, settles, then forwards the new request
  4. New token usage is recorded as pending → cycle repeats

Billing formula

Cost (USDC) = input_tokens × input_price_per_token + output_tokens × output_price_per_token

Rounded to 6 decimal places.

Example: deepseek-v4-flash (input: 0.14 USDC/1M tokens, output: 0.28 USDC/1M tokens) with 500 input + 200 output tokens:

500 × 0.000000140 + 200 × 0.000000280 = 0.000070 + 0.000056 = 0.000126 USDC

Settlement states

StatusMeaningNext action
pendingToken cost recorded, not yet paidNext call triggers 402 → payment
settledPayment confirmed on-chain (terminal)Next call proceeds freely
failedSettlement attempt failedNext call triggers 402 again for re-payment

Transition: pendingsettled (success) or pendingfailed (failure) → settled (re-payment success)


Facilitator

The Facilitator is a service that processes x402 payments on behalf of the payee (gateway). It abstracts blockchain complexity so the gateway doesn't need to run its own nodes or develop custom payment validation.

Facilitator responsibilities

RoleDescription
Payment VerificationConfirms the payer's signed authorization is valid (correct signature, sufficient balance, valid nonce)
Payment SettlementBroadcasts the transferWithAuthorization transaction on-chain
Result ReportingReturns the transaction hash and settlement status to the gateway

Facilitator API

The ZAN x402 Facilitator exposes three endpoints:

GET /supported

Returns the Facilitator's capabilities:

  • Supported x402 protocol version(s)
  • Accepted payment scheme (e.g., exact / transferWithAuthorization)
  • Supported blockchain networks and assets

POST /verify

Validates a payment without executing it on-chain.

  • Receives the x402 payment payload
  • Checks signature validity, nonce, value, and payer balance
  • Returns { isValid: true/false }

The gateway calls /verify before processing the agent's request to ensure payment is valid.

POST /settle

Executes the payment on-chain after the request has been processed.

  • Receives the same x402 payment payload
  • Signs and broadcasts the transferWithAuthorization transaction
  • Returns the on-chain transaction hash as proof of settlement

The gateway calls /settle after successfully handling the agent's request, ensuring tokens are only transferred when the service is delivered.

Verify-then-settle pattern

Gateway receives PAYMENT-SIGNATURE
    │
    ▼
POST /verify → is payment valid?
    │
    ├── invalid → reject request (402)
    │
    └── valid → process request
                    │
                    ▼
              POST /settle → broadcast on-chain
                    │
                    ├── success → return response + txHash to agent
                    └── failure → retry settlement (async)

This two-phase approach ensures:

  • Invalid payments are rejected immediately (no wasted compute)
  • Funds are only transferred after service delivery
  • Settlement failures don't block the agent (gateway retries asynchronously)

Supported payment networks

TypeNetworkUSDC Contract
EVMBase Mainnet (eip155:8453)0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913
EVMBase Sepolia (eip155:84532)0x036CbD53842c5426634e7929541eC2318f3dCF7e
EVMeip155:6886890xcfC8330f4BCAB529c625D12781b1C19466A9Fc8B
EVMeip155:16720xC879C018dB60520F4355C26eD1a6D572cdAC1815
SolanaMainnet (solana:5eykt4UsFv8P8NJdTREpY1vzqKqZKvdp)EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v
SolanaDevnet (solana:EtWTRABZaYq6iMfeYKouRu166VU2xqa1)4zMMC9srt5Ri5X14GAgXhaHii3GnPAEERYPJgZJDncDU

The payment network is decoupled from the service network — you pay on Base but query Ethereum, Solana, or any other chain.

Payment signatures

EVM (EIP-3009 TransferWithAuthorization)

The SDK uses viem to sign an EIP-3009 transferWithAuthorization message. This function allows the payer to sign a transfer off-chain — the payload includes from, to, value, an expiration time, and a random nonce. The Facilitator then submits this to the blockchain, bearing all gas fees.

Key properties:

  • No prior token approval needed (unlike ERC-20 approve + transferFrom)
  • Single-use authorization (nonce-based, cannot be replayed)
  • Amount exactly matches the quote (cannot be altered)
  • Payer pays zero gas (Facilitator submits the transaction)

Solana (SPL Token TransferChecked)

The SDK builds a Solana VersionedTransaction containing:

  • SPL Token TransferChecked instruction (exact USDC amount)
  • Associated Token Account creation (if needed)
  • Fee payer set to the Facilitator's address (gas sponsored)

Security model

PropertyMechanism
Payment verificationFacilitator verifies signature validity before gateway processes the request
On-chain settlementActual token transfer is broadcast on-chain — fully auditable
IdempotencyEach payment has a unique nonce — no double charges
Cost capGateway enforces max-credits-per-request: 1000
Automatic refundIf upstream returns 5xx after credit deduction, credits are refunded
Untrusted quotesSDK only signs the exact amount in the gateway's quote
Single authorizationEach signature authorizes exactly one payment
Gas sponsorshipAgent never pays gas — Facilitator covers all on-chain fees

SDK auto-payment behavior

With autoPayment: true, the SDK transparently handles:

  1. 402 detection — Recognizes payment-required responses
  2. Quote parsing — Decodes PAYMENT-REQUIRED header
  3. Signature construction — Signs EIP-3009 (EVM) or SPL transfer (Solana)
  4. Retry — Resubmits the original request with PAYMENT-SIGNATURE
  5. JWT refresh — Re-authenticates if session expired during payment

The entire flow appears as a single await to your code.

// All of this happens inside one await:
const block = await client.call('eth', 'mainnet', 'eth_blockNumber');
// ↑ May internally: purchase credits → sign → settle → retry

Troubleshooting

SymptomCauseSolution
InsufficientFundsErrorWallet doesn't have enough USDCFund your wallet with USDC on the payment network
PaymentRejectedErrorFacilitator rejected the signatureCheck wallet has USDC, signature format is correct
Repeated 402 on AI callsPrevious settlement keeps failingCheck wallet balance; the pending amount may exceed available USDC
Payment succeeds but credits not updatedSettle transaction pending on-chainWait for block confirmation; gateway retries settlement

Roadmap

ZAN is building the next generation of agentic payment infrastructure:

  • Agent identity verification — A financial-grade identity framework powered by TEE and ZK, enabling secure and auditable identity anchoring for autonomous agents.
  • Cross-protocol compatibility — Native compatibility with A2A, AP2, and x402, providing enhanced communication protection and cross-chain trust assurance.
  • Developer-friendly integration — Lightweight options including ADK, APIs, and RESTful interfaces for scalable, low-latency, compliant agentic payments.

Next steps



Did this page help you?