Skip to content

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

bash
npm install x402-express express dotenv

Environment Setup

Create a .env file in your project root:

bash
ADDRESS=<your-solana-wallet-address>
FACILITATOR_URL=https://facilitator.svmacc.tech
NETWORK=solana-devnet
VariableDescription
ADDRESSThe Solana wallet address where you want to receive payments.
FACILITATOR_URLThe URL of the x402 facilitator service that verifies and settles payments.
NETWORKThe Solana network to use. Use solana-devnet for testing or solana-mainnet for production.

Server Code

Create a file called server.ts:

typescript
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

  1. facilitatorConfig() creates a facilitator configuration object pointing at the facilitator service URL.
  2. paymentMiddleware() intercepts incoming requests and checks them against the route-price map you provide. Any request to GET /weather without a valid payment header will receive a 402 Payment Required response.
  3. When a client includes a valid X-PAYMENT header, 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

bash
npx ts-node server.ts

Or if you are using plain JavaScript, rename the file to server.js and run:

bash
node server.js

The 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:

typescript
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.

Powered by SVM Facilitator