Skip to main content
Use NextJS with 4Mica when your app needs paid API routes, paid server actions, or server-side calls to paid APIs. For route protection, run NextJS behind a Node server entry and mount the 4Mica Express middleware before the Next handler.
This integration is not stable yet. For now, use the NodeJS quick start for the supported implementation.

Prerequisites

  • NextJS running in the Node runtime.
  • A custom server entry such as server.ts.
  • A seller wallet address for payTo.
  • A buyer wallet with deposited 4Mica collateral for paid requests.

Install

npm install next react react-dom express @4mica/x402 @x402/fetch viem

Create wallet

For wallet setup, see Wallet.
PRIVATE_KEY=0xYourPrivateKey
PAY_TO=0xYourSellerAddress
Use the private key only for buyer-side signing. Use PAY_TO as the seller address advertised by protected routes.

Deposit collateral

Deposit collateral for the buyer wallet on the same network your NextJS server advertises. Start with Base Sepolia (eip155:84532) and a small test price. To learn more about collateral setup, see Deposits and Withdrawals.

Protect a route

Create a Node server entry and mount the payment middleware before nextRequestHandler.
import express from "express";
import next from "next";
import { paymentMiddlewareFromConfig } from "@4mica/x402/server/express";

const dev = process.env.NODE_ENV !== "production";
const app = next({ dev });
const handle = app.getRequestHandler();

await app.prepare();

const server = express();
server.use(express.json());

server.use(
  paymentMiddlewareFromConfig(
    {
      "GET /api/premium-content": {
        accepts: {
          scheme: "4mica-credit",
          price: "$0.10",
          network: "eip155:84532",
          payTo: process.env.PAY_TO ?? "0xYourAddress",
        },
        description: "Access to premium content",
      },
    },
  ),
);

server.get("/api/premium-content", (req, res) => {
  res.json({ message: "Paid content from NextJS" });
});

server.all("*", (req, res) => handle(req, res));

server.listen(3000, () => {
  console.log("NextJS server running on http://localhost:3000");
});

Support payment

Use the wrapped client anywhere you run trusted server-side code, such as a route handler, server action, or background job.
import { wrapFetchWithPaymentFromConfig } from "@x402/fetch";
import { FourMicaEvmScheme } from "@4mica/x402/client";
import { privateKeyToAccount } from "viem/accounts";

const account = privateKeyToAccount(process.env.PRIVATE_KEY as `0x${string}`);
const scheme = await FourMicaEvmScheme.create(account);

export const fetchWithPayment = wrapFetchWithPaymentFromConfig(fetch, {
  schemes: [{ network: "eip155:84532", client: scheme }],
});
Then call the protected route from server code:
const response = await fetchWithPayment("http://localhost:3000/api/premium-content");
const data = await response.json();