← Payment Reference GuidesInternet-Native Payments

The x402 Payment Protocol

How HTTP 402 Payment Required became a real payment rail: the request/quote/sign/settle handshake, the EIP-3009 stablecoin authorization underneath it, the facilitator model, and what it means for payment engineers coming from card rails.

Headers & schemas

All protocol data travels as base64-encoded JSON in three HTTP headers (v2). Protocol v1 — still widely deployed — used X-PAYMENT headers and put the payment requirements in the 402 response body:

Purposev2 (current)v1 (legacy)
Requirements (server → client)PAYMENT-REQUIRED header402 JSON body
Signed payment (client → server)PAYMENT-SIGNATUREX-PAYMENT
Settlement receipt (server → client)PAYMENT-RESPONSEX-PAYMENT-RESPONSE
Network identifiersCAIP-2 — eip155:8453strings — base
Amount fieldamountmaxAmountRequired

A 402 response, decoded

HTTP/1.1 402 Payment Required
PAYMENT-REQUIRED: eyJ4NDAyVmVyc2lvbiI6Miw…   (base64 of ↓)

{
  "x402Version": 2,
  "error": "PAYMENT-SIGNATURE header is required",
  "resource": {
    "url": "https://api.example.com/premium-data",
    "description": "Access to premium market data",
    "mimeType": "application/json"
  },
  "accepts": [{
    "scheme": "exact",
    "network": "eip155:8453",
    "amount": "10000",
    "asset": "0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913",
    "payTo": "0x209693Bc6afc0C5328bA36FaF03C514EF312287C",
    "maxTimeoutSeconds": 60,
    "extra": { "name": "USDC", "version": "2" }
  }]
}

Amounts are atomic token units: "10000" at USDC's 6 decimals is $0.01. The extra object carries the EIP-712 domain (token name and version) the wallet needs to build the signature.

The signed authorization

PAYMENT-SIGNATURE: eyJ4NDAyVmVyc2lvbiI6Miw…   (base64 of ↓)

{
  "x402Version": 2,
  "accepted": { …chosen entry from accepts… },
  "payload": {
    "signature": "0x2d6a7588d6acca50…af148b571c",
    "authorization": {
      "from":        "0x857b06519E91e3A54538791bDbb0E22373e36b66",
      "to":          "0x209693Bc6afc0C5328bA36FaF03C514EF312287C",
      "value":       "10000",
      "validAfter":  "1740672089",
      "validBefore": "1740672154",
      "nonce":       "0xf3746613c2d920b5…62f13480"
    }
  }
}

The authorization block is the exact EIP-3009 message the token contract will validate on-chain. The server or facilitator cannot alter the value or recipient without invalidating the signature — and the nonce is burned at the contract level on settlement, so the same authorization can never be settled twice.

Debugging tip: paste any of these headers into the x402 Header Decoder — it auto-detects the object type and protocol version, converts atomic amounts, resolves the asset contract against the Stablecoin Reference, and flags expired validity windows.

Facilitator API

EndpointPurpose
POST /verifyValidate a PaymentPayload against PaymentRequirements without touching the chain — signature recovery, balance check, exact-amount match, time window, simulation. Returns { isValid, invalidReason?, payer }.
POST /settleBroadcast the transfer. Returns { success, transaction, network, payer }.
GET /supportedLists supported scheme/network pairs and the facilitator's signer addresses.
GET /discovery/resourcesThe Bazaar: browse x402-enabled resources with pricing upfront.