Skip to main content
x402 is a machine-native payment protocol built on HTTP 402 Payment Required. An agent makes a normal HTTP request to a paywalled endpoint, the server responds with payment instructions, the agent signs an on-chain authorization, and retries the request — the SDK handles the round-trip automatically. MoonPay Commerce exposes two x402-paywalled endpoints: checkout (fixed price payments) and deposit (recurring or balance-based payments).
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

Steps 2–5 are handled automatically by any x402-compatible client (the MoonPay CLI, @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.
MoonPay Commerce requires ?payerAddress=<wallet> on every request. The server pre-allocates a per-payer deposit wallet on the initial 402 response, so it must know the payer’s address before it can respond. Standard x402 clients do not send this automatically — append it to the URL manually.Without it, the server returns 400 with "x-payer-address header or ?payerAddress= query param required".

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 list should show your wallet
  • Wallet funded with mainnet USDC on the target chain
  • A MoonPay Commerce paylink URL (e.g. from moonpay.hel.io)
Check your balance before paying:

Step 1 — Discover the product

Before paying, fetch the public paylink metadata so you can confirm the product, price, and supported chains:
Returns: product name, description, price (in minimal USDC units), supported blockchains.

Step 2 — Get the payer address

Copy the address for the wallet you’ll pay from.

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 (paylink abc123), signed from wallet <name>. Proceed?”

Step 4 — Pay

Fixed-price paylink:
Dynamic-price paylink — append &amount=<minimalUnits>:
Deposit payment:

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

Make a Payment

Multi-Chain Support

Register multiple schemes to pay from any supported network:
The client picks the scheme that matches the chain offered in 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 returns HTTP 402 with a PAYMENT-REQUIRED header containing Base64-encoded JSON:
Key points:
  • amount is the total cost in minimal units — fees and gas are already included.
  • payTo is 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

Step 4 — Retry with the signed proof

Step 5 — Read the settlement receipt

The 200 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 on 429.

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 line

x402 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