Merchants 8 min read

Hono / Express / Next.js

TypeScript integration examples for popular frameworks

Hono

Hono is a lightweight, fast web framework that works great with x402.

Installation

npm install hono @hono/node-server @x402/hono @x402/core @x402/evm

Basic Setup

import { Hono } from "hono";
import { serve } from "@hono/node-server";
import { paymentMiddleware } from "@x402/hono";
import { x402ResourceServer, HTTPFacilitatorClient } from "@x402/core/server";
import { registerExactEvmScheme } from "@x402/evm/exact/server";

const app = new Hono();

// Your receiving wallet address
const payTo = "0xYourAddress";

// Configure Facilitator Client
const facilitatorClient = new HTTPFacilitatorClient({
  url: "https://facilitator.fareside.com/YOUR_API_KEY",
});

// Create Resource Server & Register Schemes
const server = new x402ResourceServer(facilitatorClient);
registerExactEvmScheme(server);

// Configure Middleware
app.use(paymentMiddleware(
  {
    "GET /weather": {
      accepts: [{
        scheme: "exact",
        price: "$0.01",
        network: "eip155:84532", // Base Sepolia
        payTo,
      }],
      description: "Access to weather data",
      mimeType: "application/json",
    },
  },
  server,
));

// Implement your route
app.get("/weather", (c) => c.json({
  report: {
    weather: "sunny",
    temperature: 70,
  },
}));

serve({ fetch: app.fetch, port: 3000 });

Express

For existing Express applications, use the @x402/express middleware.

Installation

npm install express @x402/express @x402/core @x402/evm

Basic Setup

import express from "express";
import { paymentMiddleware } from "@x402/express";
import { x402ResourceServer, HTTPFacilitatorClient } from "@x402/core/server";
import { registerExactEvmScheme } from "@x402/evm/exact/server";

const app = express();

// Your receiving wallet address
const payTo = "0xYourAddress";

// Configure Facilitator Client
const facilitatorClient = new HTTPFacilitatorClient({
  url: "https://facilitator.fareside.com/YOUR_API_KEY",
});

// Create Resource Server & Register Schemes
const server = new x402ResourceServer(facilitatorClient);
registerExactEvmScheme(server);

// Configure Middleware
app.use(paymentMiddleware(
  {
    "GET /weather": {
      accepts: [{
        scheme: "exact",
        price: "$0.01",
        network: "eip155:84532", // Base Sepolia
        payTo,
      }],
      description: "Access to weather data",
      mimeType: "application/json",
    },
  },
  server,
));

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

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

Next.js

For Next.js applications, use the @x402/next middleware package.

Installation

npm install @x402/next @x402/core @x402/evm

Middleware Setup

Create a middleware.ts file in your project root:

// middleware.ts
import { paymentProxy } from "@x402/next";
import { x402ResourceServer, HTTPFacilitatorClient } from "@x402/core/server";
import { registerExactEvmScheme } from "@x402/evm/exact/server";

// Your receiving wallet address
const payTo = "0xYourAddress";

// Configure Facilitator Client
const facilitatorClient = new HTTPFacilitatorClient({
  url: "https://facilitator.fareside.com/YOUR_API_KEY",
});

// Create Resource Server & Register Schemes
const server = new x402ResourceServer(facilitatorClient);
registerExactEvmScheme(server);

export const middleware = paymentProxy(
  {
    "/api/protected": {
      accepts: [{
        scheme: "exact",
        price: "$0.01",
        network: "eip155:84532", // Base Sepolia
        payTo,
      }],
      description: "Access to protected content",
      mimeType: "application/json",
    },
  },
  server,
);

export const config = {
  matcher: ["/api/protected/:path*"],
};

Route Handler

// app/api/protected/route.ts
import { NextResponse } from "next/server";

export async function GET() {
  // This route is protected by the middleware
  // Payment verification happens automatically
  return NextResponse.json({
    data: "Protected content",
    timestamp: new Date().toISOString(),
  });
}

Configuration Options

The route configuration object accepts the following options:

interface RouteConfig {
  accepts: Array<{
    scheme: string;           // Payment scheme (e.g., "exact")
    price: string;            // Price in dollars (e.g., "$0.01")
    network: string;          // Network in CAIP-2 format (e.g., "eip155:84532")
    payTo: string;            // Your wallet address
  }>;
  description?: string;       // Description of the resource
  mimeType?: string;          // MIME type of the response
  extensions?: object;        // Optional extensions (e.g., Bazaar)
}

Dynamic Pricing

Instead of a constant value for price, you can provide a function that calculates it based on request parameters:

app.use(paymentMiddleware(
  {
    "GET /api/data": {
      accepts: [{
        price: ctx => {
          const isDiscount = !!ctx.adapter.getQueryParam?.("discount");
          return isDiscount ? "$0.05" : "$0.10";
        },
        /* ... */
      }],
    },
  },
  /* ... */
));

Testing Your Integration

  1. Make a request to your endpoint (e.g., curl -i http://localhost:3000/weather)
  2. The server responds with a 402 Payment Required, including payment instructions in the base64 encoded Payment-Required header, which you can decode and inspect with:
    echo "<Payment-Required header>" | base64 -d | jq
  3. Complete the payment using a compatible client, wallet, or automated agent
  4. Retry the request with the Payment-Signature header containing the payment payload
  5. The server verifies the payment via the facilitator and returns your API response

Next Steps