Express.js Integration
This guide walks you through adding x402 payment requirements to an Express.js server. By the end, you will have a running API that charges $0.001 per request on a protected route, with payment verification and settlement handled by the facilitator.
Installation
npm install x402-express express dotenvEnvironment Setup
Create a .env file in your project root:
ADDRESS=<your-solana-wallet-address>
FACILITATOR_URL=https://facilitator.svmacc.tech
NETWORK=solana-devnet| Variable | Description |
|---|---|
ADDRESS | The Solana wallet address where you want to receive payments. |
FACILITATOR_URL | The URL of the x402 facilitator service that verifies and settles payments. |
NETWORK | The Solana network to use. Use solana-devnet for testing or solana-mainnet for production. |
Server Code
Create a file called server.ts:
import express from "express";
import { paymentMiddleware } from "x402-express";
import { facilitatorConfig } from "x402-express";
import dotenv from "dotenv";
dotenv.config();
const app = express();
const { ADDRESS, FACILITATOR_URL, NETWORK } = process.env;
const facilitator = facilitatorConfig(FACILITATOR_URL);
app.use(
paymentMiddleware(ADDRESS, facilitator, {
"GET /weather": {
price: "$0.001",
network: NETWORK,
description: "Get current weather data",
},
})
);
app.get("/weather", (req, res) => {
res.json({ report: { weather: "sunny", temperature: 70 } });
});
app.listen(4021, () => {
console.log("Server running on http://localhost:4021");
});How It Works
facilitatorConfig()creates a facilitator configuration object pointing at the facilitator service URL.paymentMiddleware()intercepts incoming requests and checks them against the route-price map you provide. Any request toGET /weatherwithout a valid payment header will receive a402 Payment Requiredresponse.- When a client includes a valid
X-PAYMENTheader, the middleware forwards the payment proof to the facilitator for verification and settlement. If the payment is valid, the request proceeds to your route handler.
Running the Server
npx ts-node server.tsOr if you are using plain JavaScript, rename the file to server.js and run:
node server.jsThe server will start on http://localhost:4021. Any unauthenticated GET /weather request will return a 402 response with payment instructions. Clients using an x402-compatible library will handle payment automatically.
Adding More Paid Routes
You can protect multiple routes by adding entries to the route-price map:
app.use(
paymentMiddleware(ADDRESS, facilitator, {
"GET /weather": {
price: "$0.001",
network: NETWORK,
description: "Get current weather data",
},
"GET /forecast": {
price: "$0.005",
network: NETWORK,
description: "Get 7-day forecast",
},
})
);Routes not listed in the map remain free and unaffected by the middleware.