Skip to main content
The Express middleware adds x402 payment walls to individual routes or your entire application.
pnpm add @faremeter/middleware @faremeter/info express

Route-level middleware

Apply the middleware to specific routes:
import express from "express"
import { createMiddleware } from "@faremeter/middleware/express"
import { xSolanaSettlement } from "@faremeter/info/solana"

const app = express()

const paymentWall = await createMiddleware({
  facilitatorURL: "https://facilitator.corbits.dev",
  accepts: [
    xSolanaSettlement({
      network: "devnet",
      payTo: "7xKXwxRPMo2sUAT5...",
      asset: "USDC",
      amount: "10000",
    }),
  ],
})

app.get("/protected", paymentWall, (req, res) => {
  res.json({ data: "paid content" })
})

app.get("/free", (req, res) => {
  res.json({ data: "free content" })
})

app.listen(3000)

App-level middleware

Apply to all routes:
app.use(paymentWall)

app.get("/resource-a", (req, res) => {
  res.json({ data: "a" })
})

app.get("/resource-b", (req, res) => {
  res.json({ data: "b" })
})

Multiple payment methods

Accept payments on different chains from the same endpoint:
import { xSolanaSettlement } from "@faremeter/info/solana"
import { x402Exact } from "@faremeter/info/evm"

const paymentWall = await createMiddleware({
  facilitatorURL: "https://facilitator.corbits.dev",
  accepts: [
    xSolanaSettlement({
      network: "devnet",
      payTo: "7xKXwxRPMo2sUAT5...",
      asset: "USDC",
      amount: "10000",
    }),
    x402Exact({
      network: "base-sepolia",
      payTo: "0x1234...",
      asset: "USDC",
      amount: "10000",
    }),
  ],
})

Different prices per route

Create separate middleware instances for different routes:
const cheapRoute = await createMiddleware({
  facilitatorURL: "https://facilitator.corbits.dev",
  accepts: [
    xSolanaSettlement({ network: "devnet", payTo: "7xKX...", asset: "USDC", amount: "1000" }),
  ],
})

const expensiveRoute = await createMiddleware({
  facilitatorURL: "https://facilitator.corbits.dev",
  accepts: [
    xSolanaSettlement({ network: "devnet", payTo: "7xKX...", asset: "USDC", amount: "100000" }),
  ],
})

app.get("/basic", cheapRoute, (req, res) => res.json({ tier: "basic" }))
app.get("/premium", expensiveRoute, (req, res) => res.json({ tier: "premium" }))

Error handling

The middleware returns appropriate HTTP responses for payment errors:
  • 402 — No payment provided, returns requirements.
  • 400 — Malformed payment payload.
  • 402 — Payment verification or settlement failed, returns requirements again.
Errors from the facilitator are logged and translated into HTTP responses. Your route handler is only called after successful payment.

Further reading