Getting Started
Quickstart
Accept your first x402 payment in under 5 minutes using the live x402 protocol on Base testnet. No account required. No wallet setup needed for testing.
Prerequisites
You'll need the following before starting:
- Node.js 18+ — the examples use the Coinbase CDP x402 facilitator package, which is the live open-source library.
- A receiving wallet address — any EVM-compatible address on Base. For testing, generate a throwaway address at Coinbase Wallet or use MetaMask.
- Base Sepolia testnet USDC — free from the Circle USDC faucet (select Base Sepolia).
@coinbase/x402 — the open-source facilitator built by Coinbase. The x402 Agentic middleware wrapper (@x402agentic/middleware) is coming Q2 2026 and will simplify this further. The underlying protocol is identical.
Step 1 — Install dependencies
Create a new project and install the x402 facilitator and Express:
# Create project
mkdir my-x402-api && cd my-x402-api
npm init -y
# Install dependencies
npm install express @coinbase/x402 viem
Step 2 — Create your server
Create server.js and add the x402 payment middleware to a single route:
import express from 'express'
import { paymentMiddleware, Network, Resource } from '@coinbase/x402/express'
const app = express()
// ── Your receiving wallet address ──────────────────────────────
const MY_WALLET = '0xYourWalletAddressHere'
// ── Attach x402 middleware ─────────────────────────────────────
// This intercepts requests and returns HTTP 402 if unpaid
app.use(paymentMiddleware(
MY_WALLET,
{
"/api/data": new Resource({
price: "$0.001",
network: Network.BaseSepolia, // testnet — use Network.Base for mainnet
})
},
{ network: Network.BaseSepolia }
))
// ── Your protected endpoint ────────────────────────────────────
app.get('/api/data', (req, res) => {
res.json({
message: '✓ Payment verified — here is your data',
timestamp: new Date().toISOString(),
paidBy: req.headers['x-payment-response'] ?? 'unknown',
})
})
app.listen(3000, () => {
console.log('x402 server running → http://localhost:3000')
console.log('Try: curl http://localhost:3000/api/data')
})
0xYourWalletAddressHere with your real Base Sepolia wallet address. This is where USDC payments will land.
Step 3 — Run the server
node server.js
# Output:
x402 server running → http://localhost:3000
Try: curl http://localhost:3000/api/data
If you curl the endpoint without payment, you'll get the expected 402 response:
curl -i http://localhost:3000/api/data
# Response (no payment sent):
HTTP/1.1 402 Payment Required
X-Payment-Required: true
X-Price: 0.001
X-Currency: USDC
X-Network: eip155:84532
X-Pay-To: 0xYourWalletAddressHere
{
"error": "Payment required",
"x402Version": 2,
"accepts": [{
"scheme": "exact",
"network": "eip155:84532",
"maxAmountRequired": "1000",
"asset": "0x036CbD...",
"payTo": "0xYourWallet..."
}]
}
Step 4 — Make a payment and test
Now test the full payment flow using the Coinbase CDP x402 client. Create a second file, client.js:
import { wrapFetchWithPayment } from '@coinbase/x402/client'
import { createWalletClient, http } from 'viem'
import { privateKeyToAccount } from 'viem/accounts'
import { baseSepolia } from 'viem/chains'
// ── Load your test wallet private key ──────────────────────────
// Never commit real private keys — use env vars in production
const account = privateKeyToAccount(process.env.PRIVATE_KEY)
const walletClient = createWalletClient({
account,
chain: baseSepolia,
transport: http()
})
// ── Wrap fetch — auto-pays any 402 response ────────────────────
const fetchWithPayment = wrapFetchWithPayment(fetch, walletClient)
// ── Call the endpoint — payment happens automatically ──────────
const res = await fetchWithPayment('http://localhost:3000/api/data')
const data = await res.json()
console.log('Status:', res.status) // 200
console.log('Data:', data)
# Set your test wallet private key
export PRIVATE_KEY=0xYourTestPrivateKeyHere
node client.js
# Output:
Status: 200
Data: {
message: '✓ Payment verified — here is your data',
timestamp: '2026-03-03T12:00:00.000Z',
paidBy: '0xYourTestWallet...'
}
X-Payment header, and retried the request — all in one call. No human clicked anything.
How the payment flow works
Here's exactly what happened under the hood in Step 4:
-
1
Client sends initial request
fetchWithPaymentmakes a normal HTTP GET to/api/data. The server has no payment proof, so it returns HTTP 402 with the payment terms in the body. -
2
Client parses the 402
The wrapped fetch reads the
acceptsarray from the 402 body — amount (0.001 USDC), network (Base Sepolia), and destination wallet. -
3
Client pays on-chain
The wallet client signs and submits a USDC transfer on Base Sepolia. Settlement typically takes 0.3–0.8 seconds. The transaction hash becomes the payment proof.
-
4
Client retries with payment header
The same request is retried with an
X-Paymentheader containing the signed payment payload. The facilitator verifies the on-chain transaction. -
5
Server returns HTTP 200
Payment verified. The server responds with the actual data and an
X-Payment-Responseheader confirming settlement.
Payment Headers Reference
Headers sent by the server in the 402 response and by the client in the retry:
| Header | Direction | Description |
|---|---|---|
X-Payment-Required |
Server → Client | Always true on a 402 response |
X-Price |
Server → Client | Amount required, e.g. 0.001 |
X-Currency |
Server → Client | Token symbol, e.g. USDC |
X-Network |
Server → Client | CAIP-2 chain ID, e.g. eip155:8453 (Base mainnet) |
X-Pay-To |
Server → Client | Destination wallet address |
X-Payment |
Client → Server | Base64-encoded signed payment payload |
X-Payment-Response |
Server → Client | Confirmation of verified settlement on 200 response |
Going to Mainnet
When you're ready to accept real USDC payments, swap the network from BaseSepolia to Base:
// Before (testnet)
network: Network.BaseSepolia
// After (mainnet)
network: Network.Base
// That's it. Same code, real USDC.
Next Steps
Now that you have a working x402 endpoint, here's where to go next:
- Set up an Agent Wallet — give your AI agent its own wallet with spend limits so it can pay x402 endpoints autonomously.
- Understand x402 V2 — learn about CAIP-2 multi-chain support, the extensions system, and how facilitators work.
- Middleware preview — see what the
@x402agentic/middlewarewrapper will look like when it ships in Q2 2026. - x402 GitHub ↗ — the open-source facilitator codebase by Coinbase.