Skip to main content

Getting started with Express

Start accepting x402 payments in your Express server in 2 minutes.
You can find the full code for this example here.

Step 1: Create a new server from the starter template

Use your favorite package manager:
npm (npx)
npx @payai/x402-express-starter@latest my-server
pnpm
pnpm dlx @payai/x402-express-starter@latest my-server
bun
bunx @payai/x402-express-starter@latest my-server
The starter mirrors the upstream example and bootstraps a ready-to-run Express server.

Step 2: Set your environment variables

Open your generated project’s .env and set:
EVM_ADDRESS=0x...   # EVM wallet address to receive payments
SVM_ADDRESS=...    # Solana wallet address to receive payments
The starter uses @payai/facilitator which automatically connects to the PayAI facilitator — no URL configuration needed.

Step 3: Preview the server code

This is the index.ts the starter generates. It loads your env, applies the x402 payment middleware, defines example routes, and logs the server URL.
import { config } from "dotenv";
import express from "express";
import { paymentMiddleware, x402ResourceServer } from "@x402/express";
import { ExactEvmScheme } from "@x402/evm/exact/server";
import { ExactSvmScheme } from "@x402/svm/exact/server";
import { HTTPFacilitatorClient } from "@x402/core/server";
import { facilitator } from "@payai/facilitator";

config();

const evmAddress = process.env.EVM_ADDRESS as `0x${string}`;
const svmAddress = process.env.SVM_ADDRESS;
if (!evmAddress || !svmAddress) {
  console.error("Missing required environment variables");
  process.exit(1);
}

const facilitatorClient = new HTTPFacilitatorClient(facilitator);

const app = express();

app.use(
  paymentMiddleware(
    {
      "GET /weather": {
        accepts: [
          {
            scheme: "exact",
            price: "$0.001",
            network: "eip155:84532",
            payTo: evmAddress,
          },
          {
            scheme: "exact",
            price: "$0.001",
            network: "solana:EtWTRABZaYq6iMfeYKouRu166VU2xqa1",
            payTo: svmAddress,
          },
        ],
        description: "Weather data",
        mimeType: "application/json",
      },
    },
    new x402ResourceServer(facilitatorClient)
      .register("eip155:84532", new ExactEvmScheme())
      .register("solana:EtWTRABZaYq6iMfeYKouRu166VU2xqa1", new ExactSvmScheme()),
  ),
);

app.get("/weather", (req, res) => {
  res.send({
    report: {
      weather: "sunny",
      temperature: 70,
    },
  });
});

app.listen(4021, () => {
  console.log(`Server listening at http://localhost:${4021}`);
});

Step 4: Run the server

npm run dev
Your server is now accepting 402 payments!

Step 5: Test the server

You can test payments against your server locally by following the fetch example or the axios example.

Going to production

The starter works on the free tier out of the box — no API keys required. When you’re ready for production, create a merchant account at merchant.payai.network, get your API keys, and add them to your .env:
PAYAI_API_KEY_ID=your-key-id
PAYAI_API_KEY_SECRET=your-key-secret
The @payai/facilitator package automatically detects these environment variables and authenticates your requests to the facilitator. See Facilitator Pricing for tier details and Facilitator Authentication for the full protocol reference.

x402 reference

For a deeper dive into message shapes, headers, verification and settlement responses, see the x402 Reference.

Need help?

Join our Community

Have questions or want to connect with other developers? Join our Discord server.