The X402 payment middleware for Next.js provides seamless integration with your application’s routing system, allowing you to protect routes with micro-payments using the x402-next package.

Installation

First, install the required package:
npm install x402-next
# or
yarn add x402-next
# or
pnpm add x402-next

Basic Setup

Create a middleware.ts file in your project root (or src/ directory if using that structure):
import { Address } from "viem";
import { paymentMiddleware, Resource, Network } from "x402-next";

const contractAddress = process.env.CONTRACT_ADDRESS as Address;
const facilitatorUrl = process.env.NEXT_PUBLIC_FACILITATOR_URL as Resource;

export const middleware = paymentMiddleware(
  contractAddress,
  {
    "/protected": {
      price: "$0.01",
      config: {
        description: "Access to protected content Test",
      },
      network: "base",
    },
  },
  {
    url: facilitatorUrl,
    createAuthHeaders: async () => {
      return {
        verify: {
          Authorization: `Bearer ${process.env.NEXT_PUBLIC_MERIDIAN_PK}`,
        },
        settle: {
          Authorization: `Bearer ${process.env.NEXT_PUBLIC_MERIDIAN_PK}`,
        },
      };
    },
  },
  {
    appLogo: "https://via.placeholder.com/64x64.png?text=X402",
    appName: "x402 Demo",
  }
);

// Configure which paths the middleware should run on
export const config = {
  matcher: ["/protected/:path*"],
};

Configuration Parameters

Contract Configuration

  • contractAddress: The address of the Meridian deployed X402 contract
  • network: The blockchain network (e.g., “base”, “ethereum”, “polygon”)

Route Protection

The second parameter defines which routes should be protected and their pricing:
{
  "/protected": {
    price: "$0.01",           // Price in USD
    config: {
      description: "Access to protected content Test",
    },
    network: "base",                  // Network for this specific route
  },
  "/premium": {
    price: "$0.05",
    config: {
      description: "Premium content access",
    },
    network: "base",
  },
}

Facilitator Configuration

The third parameter configures the facilitator service:
{
  url: "https://api.mrdn.finance/v1",        // Your facilitator service URL
  createAuthHeaders: async () => {
    return {
      verify: {
        Authorization: `Bearer ${process.env.NEXT_PUBLIC_MERIDIAN_PK}`,
      },
      settle: {
        Authorization: `Bearer ${process.env.NEXT_PUBLIC_MERIDIAN_PK}`,
      },
    };
  },
}

Route Matching

Configure which routes the middleware should protect using the config export:
export const config = {
  matcher: [
    "/protected/:path*", // Protect all routes under /protected
    "/premium/:path*", // Protect all routes under /premium
    "/api/paid/:path*", // Protect API routes
  ],
};

Advanced Configuration

Multiple Networks

You can configure different networks for different routes:
export const middleware = paymentMiddleware(
  contractAddress,
  {
    "/protected": {
      price: "$0.01",
      config: {
        description: "Access to protected content",
      },
      network: "base",
    },
    "/premium": {
      price: "$0.05",
      config: {
        description: "Premium content access",
      },
      network: "avalanche",
    },
  }
  // ... rest of configuration
);

Dynamic Pricing

For dynamic pricing based on user or content, you can use functions:
{
  "/dynamic": {
    price: (request) => {
      // Calculate price based on request
      const url = new URL(request.url);
      const tier = url.searchParams.get('tier');
      return tier === 'premium' ? '$0.05' : '$0.01';
    },
    config: {
      description: "Dynamic pricing based on tier",
    },
    network,
  },
}

Meridian Auth Headers

Implement Meridian authentication logic:
createAuthHeaders: async (request) => {

  return {
    verify: {
      Authorization: `Bearer ${process.env.NEXT_PUBLIC_MERIDIAN_PK}`
    },
    settle: {
      Authorization: `Bearer ${process.env.NEXT_PUBLIC_MERIDIAN_PK}`
    },
  };
},

Error Handling

The middleware automatically handles common error scenarios:
  • Insufficient funds: Shows payment UI
  • Network errors: Displays appropriate error messages
  • Invalid configuration: Logs errors and falls back gracefully

Testing

To test your middleware integration:
  1. Start your development server: npm run dev
  2. Navigate to a protected route (e.g., /protected/test)
  3. The middleware should intercept the request and show the payment UI
  4. Complete a test payment to verify the flow

Production Considerations

  • Ensure all environment variables are properly set
  • Use HTTPS in production
  • Monitor facilitator service health
  • Implement proper error logging
  • Consider rate limiting for payment endpoints

Troubleshooting

Common Issues

Middleware not running:
  • Check that middleware.ts is in the correct location
  • Verify the matcher configuration includes your routes
Payment UI not showing:
  • Verify environment variables are set correctly
  • Check facilitator service connectivity
  • Ensure contract address is valid
Authentication errors:
  • Verify API keys are correct
  • Check facilitator service authentication requirements
For additional support, refer to the API Reference or contact our support team.