All payments use real mainnet USDC. There is no testnet x402 endpoint. Confirm the amount, chain, and recipient with the user before every payment.
What is x402?
x402 is a “pay-to-play” standard for HTTP APIs. Instead of an account, API key, or subscription, the client pays per request directly in stablecoins. Key properties:- No subscription — pay only for what you use
- Permissionless — no account creation, KYC, or merchant approval
- Crypto-native — USDC settled on Base, Ethereum, Polygon, Arbitrum, BSC, or Solana
- Agent-friendly — every step is a single HTTP exchange; no UI, redirects, or sessions
How the Flow Works
@x402/fetch, x402 Python, etc.) — application code only sees a single POST and the final response.
API Endpoints
Base URL:https://api.hel.io
Both
POST endpoints return HTTP 402 until a valid PAYMENT-SIGNATURE is presented.
Supported Chains
When multiple chains appear in
accepts[], prefer Base unless the agent’s wallet is funded elsewhere. If gas spikes beyond the per-chain threshold, that chain is excluded from accepts[]; if all chains are excluded, the server returns 400 instead of 402 — retry later.
Pay with the MoonPay CLI
The fastest way to make an x402 payment is the MoonPay CLI (mp). It manages the wallet, signs the on-chain authorization, and handles the 402 round-trip.
Prerequisites
- MoonPay CLI installed and authenticated —
mp wallet listshould show your wallet - Wallet funded with mainnet USDC on the target chain
- A MoonPay Commerce paylink URL (e.g. from moonpay.hel.io)
Step 1 — Discover the product
Before paying, fetch the public paylink metadata so you can confirm the product, price, and supported chains:Step 2 — Get the payer address
Step 3 — Confirm with the user
Restate the amount, chain, and recipient before spending real funds. For an agent integration, this is a hard requirement — never auto-execute.“About to send $10.00 USDC on Base mainnet for DEX Screener Token Boost (paylinkabc123), signed from wallet<name>. Proceed?”
Step 4 — Pay
Fixed-price paylink:&amount=<minimalUnits>:
Step 5 — Confirm settlement
The CLI prints the settlement transaction hash on success. Surface it to the user:
“Paid $10.00 USDC on Base mainnet (settle tx 0x…). Wallet balance: $X → $X-10.”
Settlement is asynchronous — the HTTP 200 returns as soon as the signature is verified, but the on-chain sweep from the per-payer deposit wallet to the merchant takes ~30–120s on mainnet.
Pay with an x402 SDK
Any x402-compatible client works against MoonPay Commerce — just remember to append?payerAddress=<wallet> to the URL.
Prerequisites
- Node.js, Python, or Go
- Wallet private key (loaded from environment variable — never commit)
- USDC balance on the target chain
Install
- Node.js / TypeScript
- Python
- Go
Make a Payment
- Node.js (fetch)
- Python (httpx)
- Go
Multi-Chain Support
Register multiple schemes to pay from any supported network:accepts[]. If the wallet is funded on Base only, ensure your client preference selects Base when multiple chains are offered.
Manual Payment Flow (No SDK)
If an SDK isn’t an option, you can drive the protocol with raw HTTP calls.Step 1 — Initial request
Step 2 — Decode the 402 response
The server returnsHTTP 402 with a PAYMENT-REQUIRED header containing Base64-encoded JSON:
amountis the total cost in minimal units — fees and gas are already included.payTois a per-payer deposit wallet, not the merchant’s address. Funds sweep to the merchant after settlement.- Each entry in
accepts[]is one supported chain — pick the one your wallet is funded on.
Step 3 — Sign the on-chain authorization
- EVM chains — sign an EIP-3009
transferWithAuthorizationforamountUSDC topayTo. - Solana — build an SPL token transfer of
amountUSDC topayTo.
Step 4 — Retry with the signed proof
Step 5 — Read the settlement receipt
The200 OK response includes a PAYMENT-RESPONSE header with the on-chain settlement transaction hash:
Error Handling
Rate Limits
x402 endpoints are rate-limited per IP at 10 requests / 60 seconds. Agents that batch payments should serialize requests and back off on429.
Troubleshooting
x-payer-address header or ?payerAddress= query param required (400) The payerAddress query parameter is missing. This is required by MoonPay Commerce and is non-standard for x402 — most SDKs do not send it. Always include ?payerAddress=<wallet> in the URL.
Payment verification failed / on-chain revert The payer wallet has no USDC on the network the server allocated the deposit wallet for. Check mp token balance list --wallet <name> --chain <chain> — accepts[].network in the 402 response tells you which chain to fund.
All chains return 400 instead of 402 Gas spiked across all supported chains and the circuit breaker excluded them all from accepts[]. Wait for gas to settle (typically minutes) and retry.
409 Conflict — settlement in progress A previous submission for this transaction is still being processed. Do not re-submit; wait 30–60s for settlement to resolve.
Pre-Payment Checklist
Before executing any payment, verify:- Wallet has sufficient USDC balance on the target chain
- Paylink ID is valid (confirmed via
GET /v1/paylink/{id}/public) ?payerAddress=<wallet>is included in the URL- Amount is correct — in minimal units (6 decimals), matches the product price
- User has explicitly confirmed: product name, amount, chain, and wallet
Resources
x402 Protocol
Official protocol specification and ecosystem
x402 Quickstart for Buyers
Coinbase’s getting-started guide for x402 clients
MoonPay CLI
mp — sign and submit x402 payments from the command linex402 GitHub
Reference clients in TypeScript, Python, and Go
Agent Payments Overview
Other agent-payable protocols and the merchant integration model
Webhooks
React to settled agent payments via paylink and deposit webhooks
