> ## Documentation Index
> Fetch the complete documentation index at: https://armory.sh/llms.txt
> Use this file to discover all available pages before exploring further.

# With Next.js

> Accept x402 payments in your Next.js App Router application

Accept x402 payments in your Next.js App Router application using the `@armory-sh/middleware-next` package.

## Installation

```bash theme={null}
# npm
npm install @armory-sh/middleware-next

# yarn
yarn add @armory-sh/middleware-next

# pnpm
pnpm add @armory-sh/middleware-next

# bun
bun add @armory-sh/middleware-next
```

## Basic Setup

Create a `middleware.ts` file in your Next.js app root:

```typescript theme={null}
// middleware.ts
import { paymentProxy, x402ResourceServer } from "@armory-sh/middleware-next";

// Create a verification client
const verificationClient = {
  async verify(headers: Headers) {
    const response = await fetch("https://your-verifier.com/verify", {
      method: "POST",
      headers: Object.fromEntries(headers.entries()),
    });
    return response.json();
  },
};

// Create the resource server
const resourceServer = new x402ResourceServer(verificationClient);

// Configure payment proxy with per-route settings
export const proxy = paymentProxy(
  {
    "/api/protected": {
      accepts: {
        scheme: "exact",
        price: "1000000",  // $1.00 in atomic units (6 decimals)
        network: "eip155:8453",
        payTo: "0xYourAddress...",
      },
      description: "Access to protected API",
    },
  },
  resourceServer
);

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

## Route Patterns

Next.js middleware uses the same `matcher` config as standard Next.js middleware:

```typescript theme={null}
// Single route
export const config = { matcher: ["/api/protected"] };

// Wildcard (matches all sub-paths)
export const config = { matcher: ["/api/protected/:path*"] };

// Multiple routes
export const config = {
  matcher: ["/api/users/:path*", "/api/posts/:path*"]
};
```

## Per-Route Configuration

Configure different payment requirements for different routes:

```typescript theme={null}
export const proxy = paymentProxy(
  {
    "/api/basic": {
      accepts: {
        scheme: "exact",
        price: "1000000",  // $1.00
        network: "eip155:8453",
        payTo: "0xYourAddress...",
      },
      description: "Basic tier access",
    },
    "/api/premium": {
      accepts: {
        scheme: "exact",
        price: "5000000",  // $5.00
        network: "eip155:8453",
        payTo: "0xYourAddress...",
      },
      description: "Premium tier access",
    },
    "/api/vip": {
      accepts: {
        scheme: "exact",
        price: "10000000",  // $10.00
        network: "eip155:8453",
        payTo: "0xYourAddress...",
      },
      description: "VIP tier access",
    },
  },
  resourceServer
);
```

## Wildcard Routes

Use wildcards to match multiple routes with a single configuration:

```typescript theme={null}
export const proxy = paymentProxy(
  {
    "/api/premium/*": {
      accepts: {
        scheme: "exact",
        price: "5000000",  // $5.00
        network: "eip155:8453",
        payTo: "0xYourAddress...",
      },
      description: "Premium API access",
    },
  },
  resourceServer
);

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

## Resource Server

The `x402ResourceServer` manages payment schemes and requirements:

```typescript theme={null}
import type { PaymentScheme } from "@armory-sh/middleware-next";
import type { PaymentRequirementsV2 } from "@armory-sh/base";

// Create custom payment schemes
const exactScheme: PaymentScheme = {
  name: "exact",
  getRequirements: (): PaymentRequirementsV2 => ({
    scheme: "exact",
    network: "eip155:8453",
    amount: "1000000",
    asset: "0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913" as `0x${string}`,
    payTo: "0xYourAddress..." as `0x${string}`,
    maxTimeoutSeconds: 300,
    extra: {},
  }),
};

// Register schemes for different chains
const resourceServer = new x402ResourceServer(verificationClient)
  .register("eip155:8453", exactScheme)  // Base
  .register("eip155:1", exactScheme);    // Ethereum
```

## Response Format

When payment is verified, the middleware returns a JSON response:

```json theme={null}
{
  "verified": true,
  "payerAddress": "0x..."
}
```

When payment is required, it returns a 402 response with payment requirements:

```json theme={null}
{
  "error": "Payment required",
  "accepts": [
    {
      "scheme": "exact",
      "network": "eip155:8453",
      "amount": "1000000",
      "asset": "0x8335...",
      "payTo": "0xYour..."
    }
  ]
}
```

## Complete Example

```typescript theme={null}
// middleware.ts
import { paymentProxy, x402ResourceServer } from "@armory-sh/middleware-next";

const verificationClient = {
  async verify(headers: Headers) {
    const response = await fetch("https://verifier.example.com/verify", {
      method: "POST",
      headers: {
        "Content-Type": "application/json",
        ...Object.fromEntries(headers.entries()),
      },
      body: JSON.stringify({
        headers: Object.fromEntries(headers.entries()),
      }),
    });
    return response.json();
  },
};

const resourceServer = new x402ResourceServer(verificationClient);

export const proxy = paymentProxy(
  {
    "/api/data/basic": {
      accepts: {
        scheme: "exact",
        price: "1000000",
        network: "eip155:8453",
        payTo: "0xYourAddress...",
      },
      description: "Basic data access",
    },
    "/api/data/premium": {
      accepts: {
        scheme: "exact",
        price: "5000000",
        network: "eip155:8453",
        payTo: "0xYourAddress...",
      },
      description: "Premium data access",
    },
    "/api/analytics/*": {
      accepts: {
        scheme: "exact",
        price: "10000000",
        network: "eip155:8453",
        payTo: "0xYourAddress...",
      },
      description: "Analytics access (all endpoints)",
    },
  },
  resourceServer
);

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

## API Routes

Your API routes can check for payment verification:

```typescript theme={null}
// app/api/data/premium/route.ts
import { NextRequest, NextResponse } from "next/server";

export async function GET(request: NextRequest) {
  // Payment verification is handled by middleware
  // If we reach here, payment was verified

  const payerAddress = request.headers.get("X-Payer-Address");

  return NextResponse.json({
    data: "premium data",
    accessedBy: payerAddress,
  });
}
```

## Error Handling

The middleware automatically handles common errors:

* **404**: Route not found (no matching payment configuration)
* **402**: Payment required (no payment header provided)
* **400**: Invalid payment payload
* **500**: Configuration error

## Types

```typescript theme={null}
import type {
  PaymentScheme,
  RoutePaymentConfig,
} from "@armory-sh/middleware-next";
```
