Skip to content

Payment Flow

End-to-End Flow

Client                    Server                   Facilitator
  │                         │                          │
  │  GET /resource          │                          │
  │────────────────────────>│                          │
  │                         │                          │
  │  402 + X-Payment-Required                          │
  │<────────────────────────│                          │
  │                         │                          │
  │  (construct payment proof)                         │
  │                         │                          │
  │  GET /resource          │                          │
  │  + X-Payment header     │                          │
  │────────────────────────>│                          │
  │                         │  POST /verify            │
  │                         │─────────────────────────>│
  │                         │  { isValid: true }       │
  │                         │<─────────────────────────│
  │                         │                          │
  │                         │  POST /settle            │
  │                         │─────────────────────────>│
  │                         │  { success, txHash }     │
  │                         │<─────────────────────────│
  │                         │                          │
  │  200 + resource         │                          │
  │  + X-Payment-Response   │                          │
  │<────────────────────────│                          │

Step-by-Step Walkthrough

1. Initial Request

The client sends a standard HTTP request to a paid resource.

http
GET /api/data HTTP/1.1
Host: example.com

2. 402 Response

The server responds with HTTP 402 and includes payment requirements as a base64-encoded JSON in the X-Payment-Required header.

http
HTTP/1.1 402 Payment Required
X-Payment-Required: eyJ4NDAyVmVyc2lvbiI6MSwi...

Decoded, the header contains:

json
{
  "x402Version": 1,
  "accepts": [
    {
      "scheme": "exact",
      "network": "base",
      "maxAmountRequired": "10000",
      "payTo": "0x...",
      "asset": "0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913",
      "maxTimeoutSeconds": 60,
      "resource": "/api/data",
      "description": "API access fee"
    }
  ]
}

The accepts array may include multiple payment options (different schemes or networks).

3. Parse Requirements

The client decodes the X-Payment-Required header and selects a payment option from accepts[]. The client should prefer scheme: "exact".

4. Construct Payment Proof

The client builds a scheme-specific payment proof:

SchemeWhat the client signs
EVMEIP-712 TransferWithAuthorization (USDC EIP-3009)
CreditsEIP-712 CreditsMandateSpend authorization
XRPA signed XRPL Payment transaction

See the individual scheme pages for payload details:

5. Retry with X-Payment

The client retries the original request with the payment proof as a base64-encoded JSON in the X-Payment header.

http
GET /api/data HTTP/1.1
Host: example.com
X-Payment: eyJ4NDAyVmVyc2lvbiI6MSwi...

6. Server Verifies Payment

The server decodes the X-Payment header and sends it to the appropriate facilitator for verification and settlement:

  1. Verify — the facilitator checks the signature, amount, destination, and validity window
  2. Settle — the facilitator executes the payment (on-chain transfer or off-chain debit)

7. Resource Delivery

On successful settlement, the server returns the requested resource along with a payment receipt:

http
HTTP/1.1 200 OK
X-Payment-Response: eyJzdWNjZXNzIjp0cnVlLC...
Content-Type: application/json

{ "data": "..." }

The X-Payment-Response header contains:

json
{
  "success": true,
  "transaction": "0x..."
}

Scheme-Specific Differences

AspectEVMCreditsXRP
SigningEIP-712 via Privy wallet (auto)EIP-712 via Privy wallet (auto)Native XRPL signing (manual)
SettlementOn-chain USDC transferOff-chain balance debit (immediate)Submit to XRPL, async finality via chain parser
Status flowsignedusedsignedusedsignedpendingused
FacilitatorExternal (facilitator.xechoai.xyz)Internal (/api/facilitator/)Internal (/api/facilitator/, same as Credits)
Mandate supportV1 and V3V1 and V3V1 only
Validity window30–300 seconds20 minutes (nonce window)Transaction-level (tefMAX_LEDGER on expiry)

Released under the MIT License.