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

# Nextjs

## Getting started with Next.js

Start accepting x402 payments in your Next.js app in 2 minutes.

<Note>You can find the full code for this example [here](https://github.com/x402-foundation/x402/tree/main/examples/typescript/fullstack/next).</Note>

### Step 1: Create a new app

Use your favorite package manager:

##### npm (npx)

```bash theme={null}
npx @payai/x402-next-starter@latest my-server
```

##### pnpm

```bash theme={null}
pnpm dlx @payai/x402-next-starter@latest my-server
```

##### bun

```bash theme={null}
bunx @payai/x402-next-starter@latest my-server
```

The starter mirrors the [upstream example](https://github.com/x402-foundation/x402/tree/main/examples/typescript/fullstack/next) and boostraps a ready-to-run NextJS app.

### Step 2: Set your environment variables

Copy the example env and fill in your values (e.g. `cp .env-local .env` or `cp env.example .env.local`).

```env theme={null}
EVM_ADDRESS=0x...   # EVM wallet address to receive payments
SVM_ADDRESS=...    # Solana wallet address to receive payments
```

<Tip>The starter uses `@payai/facilitator` which automatically connects to the PayAI facilitator — no URL configuration needed.</Tip>

### Step 3: Explore the app structure

The example uses a **proxy** for page routes and **withX402** for API routes:

```text theme={null}
├── app/
│   ├── api/           # API routes (use withX402 for payment)
│   ├── protected/     # Protected page route
│   ├── layout.tsx
│   └── page.tsx
├── proxy.ts           # x402 payment proxy (page routes)
├── next.config.ts
└── package.json
```

* **paymentProxy** (in `proxy.ts`) protects page routes and returns a paywall when payment is required.
* **withX402** wraps individual API route handlers so payment is settled only after a successful response.

### Step 4: Preview the example routes

#### Protected Page Route

The `/protected` page is protected using `paymentProxy`.

The proxy in `proxy.ts` configures the resource server, paywall, and protected routes:

```typescript theme={null}
// proxy.ts
import { paymentProxy } from "@x402/next";
import { x402ResourceServer, HTTPFacilitatorClient } from "@x402/core/server";
import { registerExactEvmScheme } from "@x402/evm/exact/server";
import { registerExactSvmScheme } from "@x402/svm/exact/server";
import { createPaywall } from "@x402/paywall";
import { evmPaywall } from "@x402/paywall/evm";
import { svmPaywall } from "@x402/paywall/svm";
import { facilitator } from "@payai/facilitator";

const facilitatorClient = new HTTPFacilitatorClient(facilitator);
const server = new x402ResourceServer(facilitatorClient);

// Register schemes
registerExactEvmScheme(server);
registerExactSvmScheme(server);

// Build paywall using builder pattern
const paywall = createPaywall()
  .withNetwork(evmPaywall)
  .withNetwork(svmPaywall)
  .withConfig({
    appName: "Next x402 Demo",
    appLogo: "/x402-icon-blue.png",
    testnet: true,
  })
  .build();

export const proxy = paymentProxy(
  {
    "/protected": {
      accepts: [
        {
          scheme: "exact",
          price: "$0.001",
          network: "eip155:84532",
          payTo: evmAddress,
        },
        {
          scheme: "exact",
          price: "$0.001",
          network: "solana:EtWTRABZaYq6iMfeYKouRu166VU2xqa1",
          payTo: svmAddress,
        },
      ],
      description: "Premium music: x402 Remix",
      mimeType: "text/html",
    },
  },
  server,
  undefined, // paywallConfig (using custom paywall instead)
  paywall,   // custom paywall provider
);

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

#### Weather API Route (using withX402)

The `/api/weather` route demonstrates the `withX402` wrapper for individual API routes:

```typescript theme={null}
// app/api/weather/route.ts
import { NextRequest, NextResponse } from "next/server";
import { withX402 } from "@x402/next";
import { server, paywall, evmAddress, svmAddress } from "../../../proxy";

const handler = async (_: NextRequest) => {
  return NextResponse.json({
    report: {
      weather: "sunny",
      temperature: 72,
    },
  });
};

export const GET = withX402(
  handler,
  {
    accepts: [
      {
        scheme: "exact",
        price: "$0.001",
        network: "eip155:84532",
        payTo: evmAddress,
      },
      {
        scheme: "exact",
        price: "$0.001",
        network: "solana:EtWTRABZaYq6iMfeYKouRu166VU2xqa1",
        payTo: svmAddress,
      },
    ],
    description: "Access to weather API",
    mimeType: "application/json",
  },
  server,
  undefined, // paywallConfig (using custom paywall from proxy.ts)
  paywall,
);
```

#### paymentProxy vs withX402

The `paymentProxy` function is used to protect page routes. It can also protect API routes, however this will charge clients for failed API responses.

The `withX402` function wraps API route handlers. This is the recommended approach to protect API routes as it guarantees payment settlement only AFTER successful API responses (status \< 400).

| Approach       | Use Case                                                                               |
| -------------- | -------------------------------------------------------------------------------------- |
| `paymentProxy` | Protecting page routes or multiple routes with a single configuration                  |
| `withX402`     | Protecting individual API routes where you need precise control over settlement timing |

### Step 5: Run the server

```bash theme={null}
npm run dev
```

<Check>
  Your Next.js app is now accepting x402 payments!
</Check>

### Step 6: Test the server

The starter includes a built-in paywall at the home page. Navigate to [http://localhost:3000](http://localhost:3000) to test payments directly.

You can also test programmatically by following the [fetch example](/x402/clients/typescript/fetch) or [axios example](/x402/clients/typescript/axios).

## Going to production

The starter works on the **free tier** out of the box — no API keys required.

When you're ready for production, create a merchant account at [merchant.payai.network](https://merchant.payai.network), get your API keys, and add them to your `.env`:

```env theme={null}
PAYAI_API_KEY_ID=your-key-id
PAYAI_API_KEY_SECRET=your-key-secret
```

The `@payai/facilitator` package automatically detects these environment variables and authenticates your requests to the facilitator. See [Facilitator Pricing](/x402/facilitators/pricing) for tier details and [Facilitator Authentication](/x402/facilitators/authentication) for the full protocol reference.

## x402 reference

For a deeper dive into message shapes, headers, verification and settlement responses, see the [x402 Reference](/x402/reference).

## Need help?

<Card title="Join our Community" icon="discord" href="https://discord.gg/eWJRwMpebQ">
  Have questions or want to connect with other developers? Join our Discord server.
</Card>
