Quick answer: on Express, wrap routes with paymentMiddleware from @x402/express. On Next.js, use paymentProxy for page routes (or many routes at once) and withX402 for API route handlers — withX402 settles only after a successful response (status < 400). Start on Base Sepolia with the x402.org facilitator; for mainnet switch to eip155:8453 and a production facilitator. Full walkthrough: Quickstart for Sellers.
Minimal Express (Base Sepolia)
// npm i express @x402/express@2.28.0 @x402/core@2.28.0 @x402/evm@2.28.0
import express from "express";
import { paymentMiddleware, x402ResourceServer } from "@x402/express";
import { ExactEvmScheme } from "@x402/evm/exact/server";
import { HTTPFacilitatorClient } from "@x402/core/server";
const app = express();
const facilitatorClient = new HTTPFacilitatorClient({
url: "https://x402.org/facilitator", // testnet only
});
app.use(
paymentMiddleware(
{
"GET /weather": {
accepts: [{
scheme: "exact",
price: "$0.001",
network: "eip155:84532",
payTo: "0xYourEvmAddress",
}],
description: "Weather data",
mimeType: "application/json",
},
},
new x402ResourceServer(facilitatorClient)
.register("eip155:*", new ExactEvmScheme()), // covers Sepolia + mainnet
),
);
app.get("/weather", (req, res) => {
res.send({ report: { weather: "sunny", temperature: 70 } });
});
app.listen(4021);
On 15 Oct 2026, with @x402/express 2.28.0, an unpaid curl http://localhost:4021/weather returned HTTP 402 with a PAYMENT-REQUIRED header (x402Version 2, exact on eip155:84532, amount 1000 atomic USDC). We did not complete a paid retry in that smoke test.
Next.js: paymentProxy vs withX402
Per the official quickstart: withX402 only settles after status < 400 (recommended for API routes). paymentProxy is better for page routes; on API routes it can charge failed responses. The RoutesConfig path key for withX402 must match the served path exactly (including any basePath) or protection is skipped with a warning.
Mainnet: three edits, not two
Do not reuse https://x402.org/facilitator on mainnet; the quickstart says it is for testnet only. On @x402/core 2.28.0 you need three edits. If the server still has .register("eip155:84532", …), as the official Express quickstart shows, changing only the facilitator URL and network makes paymentMiddleware fail at startup and the process exits:
RouteConfigurationError: x402 Route Configuration Errors:
- Route "GET /weather": No scheme implementation registered for "exact" on network "eip155:8453"
- Facilitator → a production facilitator (list).
-
Network →
network: "eip155:8453"(Base mainnet). -
Register →
.register("eip155:8453", new ExactEvmScheme())or.register("eip155:*", new ExactEvmScheme()). The snippet above already useseip155:*, so if you copied it you only need steps 1 and 2.
Canonical guide (with Next.js snippets, FAQ, checker links): https://x402-seller-kit.soloearn.workers.dev/guides/add-x402-express-nextjs
Top comments (0)