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:
- Decode the payment proof
- Verify the EIP-712 signature
- Check nonce has not been used
- Verify amount matches requirement
- Submit the signed authorization to the USDC contract on Base
- 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
| Step | Duration |
|---|---|
| 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
| Failure | HTTP Code | Client Action |
|---|---|---|
| Insufficient USDC | 402 | Add USDC to wallet |
| Invalid signature | 402 | Check wallet key |
| Nonce already used | 402 | Request new nonce |
| Payment expired | 402 | Retry with fresh signature |
| Wrong network | 402 | Switch to Base (8453) |
| Rate limited | 429 | Wait and retry |