x402 Quickstart for Sellers
How to use x402 as a seller
Integrate x402 into your API or service to accept on-chain payments in USDC. Buyers or AI agents can automatically pay when accessing your protected endpoints.
You will achieve:
- Protect endpoints behind a 402 paywall
- Receive USDC payments on Polygon
- Publish discoverable, pay-per-use APIs
Security notice
These snippets are for demonstration only.
Store private keys and facilitator URLs in a secure vault — never hardcode secrets.
Overview
x402 brings native crypto payments to APIs using the HTTP 402 Payment Required status. When a buyer hits a protected route, the x402 middleware:
- Returns a 402 response describing price and network metadata
- Waits for payment through a facilitator (e.g. https://facilitator.x402.rs)
- Confirms payment and releases the response automatically
Prerequisites
| Requirement | Example / Notes |
|---|---|
| Wallet to receive USDC | Any EVM-compatible wallet (Metamask, Rabby, Safe, etc.) |
| JS end | Node.js ≥18 with npm, or something of better quality, like Bun |
| Existing API / server | Express, Next.js, Hono, or any web framework |
| Polygon network | Amoy testnet or mainnet |
For reference examples:
Install dependencies
Wherever
bunis used, replace it withnpmor your preferred package manager.
Pick your middleware:
bun install x402-expressor
bun install x402-nextor
bun install x402-honoConfigure the payment middleware
Each middleware protects your API routes and routes payments to your receiving wallet.
You must specify:
- Wallet address: where you receive USDC
- Network: e.g. "polygon-amoy" or "polygon"
- Facilitator URL: default for Polygon Amoy — https://facilitator.x402.rs
- Route config: endpoint price and optional metadata
For Amoy testnet onboarding, contact Polygon DevRel in our telegram.
Example - Express
import express from "express";
import { paymentMiddleware } from "x402-express";
const app = express();
app.use(paymentMiddleware(
"0xCA3953e536bDA86D1F152eEfA8aC7b0C82b6eC00", // receiver wallet
{
"GET /weather": {
price: "$0.001",
network: "polygon-amoy",
config: {
description: "Get current weather data for any location",
inputSchema: {
type: "object",
properties: { location: { type: "string" } }
},
outputSchema: {
type: "object",
properties: {
weather: { type: "string" },
temperature: { type: "number" }
}
}
}
}
},
{
url: process.env.FACILITATOR_URL || "https://facilitator.x402.rs"
}
));
app.get("/weather", (req, res) => {
res.send({
report: { weather: "sunny", temperature: 70 }
});
});
app.listen(4021, () => {
console.log("Server running at http://localhost:4021");
});Buyers calling /weather will automatically receive a 402 challenge, pay, and then receive the weather data.
Example - Next.js
import { paymentMiddleware } from "x402-next";
export const middleware = paymentMiddleware(
"0xYourAddress", // receiving wallet
{
"/protected": {
price: "$0.01",
network: "polygon-amoy",
config: { description: "Access to protected content" }
}
},
{
url: "https://facilitator.x402.rs"
}
);
export const config = {
matcher: ["/protected/:path*"]
};Buyers calling /protected will automatically receive a 402 challenge, pay, and then receive the protected content.
Example - Hono
import { paymentMiddleware } from "x402-next";
export const middleware = paymentMiddleware(
"0xYourAddress", // receiving wallet
{
"/protected": {
price: "$0.01",
network: "polygon-amoy",
config: { description: "Access to protected content" }
}
},
{
url: "https://facilitator.x402.rs"
}
);
export const config = {
matcher: ["/protected/:path*"]
};Buyers calling /protected will automatically receive a 402 challenge, pay, and then receive the protected content.
Extras
Debugging, sanity checks, and guardrails.
Schema
| name | type | required | example | description |
|---|---|---|---|---|
| walletAddress | string | ✅ | 0xYourAddress | Address that receives USDC payments |
| network | string | ✅ | polygon-amoy | Network Identifier |
| price | string | ✅ | "$0.001" | Cost per request in USDC |
| FACILITATOR_URL | string | optional | "https://facilitator.x402.rs" | Payment facilitator endpoint |
| config | object | optional | JSON schema | Used for discoverability in x402 Bazaar |
Do / Don't Do Guardrails
| ✅ Do | ❌ Don't |
|---|---|
Use https://facilitator.x402.rs for Polygon testnet | Expose private keys in middleware |
| Include schema metadata for AI discoverability | Hardcode facilitator URLs in code |
| Test with Amoy before mainnet deployment | Skip setting network/price — buyers will fail to pay |
References
- x402-express npm docs
- x402-next npm docs
- x402-hono npm docs
- x402 Developer Docs
- Coinbase x402 examples
- Polygon quickstart repo
Errors
| case / code | meaning | fix |
|---|---|---|
| 402_LOOP | Client can't fulfill payment | Check facilitator URL and wallet |
| INVALID_NETWORK | Wrong network label | Use "polygon-amoy" or "polygon" |
| BAD_CONFIG | Missing route schema | Define price and network per route |