Skip to content

Payment Flow (Detailed)

Complete Lifecycle

Step 1: Initial Request

Client sends standard HTTP GET to a paid endpoint:

GET /price/ETH HTTP/1.1
Host: api.foursec.xyz

Step 2: 402 Payment Required Response

Server responds with payment details:

HTTP/1.1 402 Payment Required
X-PAYMENT-REQUIRED: base64_encoded_payment_details

{
  "error": "payment_required",
  "version": "1.0",
  "amount": "10000",
  "token": "0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913",
  "network": "base",
  "recipient": "0x4SEC_RECEIVER_ADDRESS",
  "nonce": "abc123",
  "expires_at": "2026-07-04T15:35:00Z"
}

Amount: 10000 base units = $0.01 USDC (6 decimals)

Step 3: Client Signs Payment

The x402 client creates an EIP-712 typed data signature:

{
  "domain": {
    "name": "USDC",
    "version": "2",
    "chainId": 8453,
    "verifyingContract": "0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913"
  },
  "types": {
    "TransferWithAuthorization": [
      {"name": "from", "type": "address"},
      {"name": "to", "type": "address"},
      {"name": "value", "type": "uint256"},
      {"name": "validAfter", "type": "uint256"},
      {"name": "validBefore", "type": "uint256"},
      {"name": "nonce", "type": "bytes32"}
    ]
  },
  "message": {
    "from": "0x_your_wallet",
    "to": "0x4SEC_RECEIVER",
    "value": "10000",
    "validAfter": "0",
    "validBefore": "1688501700",
    "nonce": "abc123"
  }
}

Step 4: Retry with Payment Proof

GET /price/ETH HTTP/1.1
Host: api.foursec.xyz
X-PAYMENT: base64_encoded_signed_payment

Step 5: Server Verification

Server calls the facilitator to verify:

  1. Decode the payment proof
  2. Verify the EIP-712 signature
  3. Check nonce has not been used
  4. Verify amount matches requirement
  5. Submit the signed authorization to the USDC contract on Base
  6. Confirm payment received

Step 6: Serve Data

HTTP/1.1 200 OK
X-Cache: MISS
X-Payment-Verified: true

{
  "symbol": "ETH",
  "price_usd": 2450.32,
  ...
}

Timing

StepDuration
Initial request~50ms
402 response~50ms
Client signing~10ms
Retry with proof~50ms
Facilitator verification~100ms
Data serving~50ms
Total~300ms

Caching Behavior

After successful payment:

  • 0-30 seconds: Same request served from cache (FREE, X-Cache: HIT)
  • 30+ seconds: New payment required (X-Cache: MISS)
  • Cache is per-wallet, per-endpoint, per-parameters

Failure Scenarios

FailureHTTP CodeClient Action
Insufficient USDC402Add USDC to wallet
Invalid signature402Check wallet key
Nonce already used402Request new nonce
Payment expired402Retry with fresh signature
Wrong network402Switch to Base (8453)
Rate limited429Wait and retry

Released under the MIT License.