Getting Started with Next.js
Start accepting x402 payments in your Next.js application in 2 minutes.
You can find the full code for this example on GitHub.
Step 1: Install Dependencies
Install the required packages for your Next.js application:
npm install x402 next react react-dom
Or with other package managers:
# pnpm
pnpm add x402 next react react-dom
# yarn
yarn add x402 next react react-dom
# bun
bun add x402 next react react-dom
Step 2: Set Your Environment Variables
Create a .env.local file in your project root:
echo "ADDRESS=0x...\nFACILITATOR_URL=https://x402.blockeden.xyz\nNETWORK=sui\nBLOCKEDEN_API_KEY=your_api_key_here" > .env.local
Your .env.local file should look like this:
ADDRESS=0x... # wallet public address you want to receive payments to
FACILITATOR_URL=https://x402.blockeden.xyz
NETWORK=sui # recommended for fastest settlement
BLOCKEDEN_API_KEY=your_api_key_here # get from https://blockeden.xyz/dash/
BlockEden.xyz supports multiple networks:
sui(recommended for fastest settlement)ethereumbasepolygonavalanche
Step 3: Create Payment-Protected API Routes
Next.js uses a file-based routing system. Create API routes in the app/api directory (App Router) or pages/api directory (Pages Router).
Using App Router (Next.js 13+)
Create app/api/weather/route.ts:
import { NextRequest } from "next/server";
import { requirePayment } from "x402-nextjs";
const facilitatorUrl = process.env.FACILITATOR_URL!;
const payTo = process.env.ADDRESS! as `0x${string}`;
const network = process.env.NETWORK || "sui";
const apiKey = process.env.BLOCKEDEN_API_KEY!;
export const GET = requirePayment(
{
price: "$0.001",
network,
},
payTo,
{
url: facilitatorUrl,
apiKey,
},
async (request: NextRequest) => {
return Response.json({
report: {
weather: "sunny",
temperature: 70,
location: "San Francisco",
},
});
},
);
Create app/api/premium/content/route.ts:
import { NextRequest } from "next/server";
import { requirePayment } from "x402-nextjs";
const facilitatorUrl = process.env.FACILITATOR_URL!;
const payTo = process.env.ADDRESS! as `0x${string}`;
const network = process.env.NETWORK || "sui";
const apiKey = process.env.BLOCKEDEN_API_KEY!;
export const GET = requirePayment(
{
price: "$0.05",
network,
},
payTo,
{
url: facilitatorUrl,
apiKey,
},
async (request: NextRequest) => {
return Response.json({
content: "This is premium content",
type: "article",
timestamp: new Date().toISOString(),
});
},
);
Using Pages Router (Next.js 12 and below)
Create pages/api/weather.ts:
import type { NextApiRequest, NextApiResponse } from "next";
import { requirePayment } from "x402-nextjs/pages";
const facilitatorUrl = process.env.FACILITATOR_URL!;
const payTo = process.env.ADDRESS! as `0x${string}`;
const network = process.env.NETWORK || "sui";
const apiKey = process.env.BLOCKEDEN_API_KEY!;
async function handler(req: NextApiRequest, res: NextApiResponse) {
return res.status(200).json({
report: {
weather: "sunny",
temperature: 70,
location: "San Francisco",
},
});
}
export default requirePayment(
{
price: "$0.001",
network,
},
payTo,
{
url: facilitatorUrl,
apiKey,
},
handler,
);
Step 4: Run the Development Server
Start your Next.js development server:
npm run dev
Your API routes will be available at:
http://localhost:3000/api/weatherhttp://localhost:3000/api/premium/content
Step 5: Test the Server
You can test payments against your API routes using HTTP clients like curl, Postman, or by building a client application.
Client implementation guides for fetch API and axios will be available soon.
Manual Testing with curl
# This will return a 402 Payment Required response
curl http://localhost:3000/api/weather
# The response will include payment details in headers
Payment Configuration Options
The requirePayment wrapper accepts flexible payment configurations:
Simple Dollar Amount
export const GET = requirePayment(
{
price: "$0.001",
network: "sui",
},
payTo,
{
url: facilitatorUrl,
apiKey,
},
async (request: NextRequest) => {
return Response.json({ data: "Your data" });
},
);
Token Amount with Specific Asset
export const GET = requirePayment(
{
price: {
amount: "10000",
asset: {
address: "0x...", // Token contract address
decimals: 6,
name: "USDC",
},
},
network: "sui",
},
payTo,
{
url: facilitatorUrl,
apiKey,
},
async (request: NextRequest) => {
return Response.json({ data: "Premium data" });
},
);
Accessing Payment Information
export const GET = requirePayment(
{
price: "$0.001",
network: "sui",
},
payTo,
{
url: facilitatorUrl,
apiKey,
},
async (request: NextRequest) => {
// Payment information is attached to the request
const paymentData = (request as any).paymentData;
return Response.json({
data: "Your data",
payment: {
txHash: paymentData?.txHash,
network: paymentData?.network,
},
});
},
);
Advanced Features
Custom Payment Verification Callback
Add custom logic when payments are verified:
import { requirePayment } from "x402-nextjs";
export const GET = requirePayment(
{
price: "$0.001",
network: "sui",
},
payTo,
{
url: facilitatorUrl,
apiKey,
onPaymentVerified: (paymentData) => {
console.log("Payment verified:", paymentData.txHash);
// Custom logging, analytics, or business logic
},
},
async (request: NextRequest) => {
return Response.json({ data: "Your data" });
},
);
Error Handling
Create a custom error handler in app/api/error/route.ts:
import { NextRequest } from "next/server";
export async function GET(request: NextRequest) {
return Response.json(
{
error: "Internal server error",
timestamp: new Date().toISOString(),
},
{ status: 500 },
);
}
CORS Configuration
Enable CORS for your API routes using Next.js middleware.
Create middleware.ts in your project root:
import { NextResponse } from "next/server";
import type { NextRequest } from "next/server";
export function middleware(request: NextRequest) {
const response = NextResponse.next();
// Set CORS headers
response.headers.set("Access-Control-Allow-Origin", "*");
response.headers.set(
"Access-Control-Allow-Methods",
"GET, POST, PUT, DELETE, OPTIONS",
);
response.headers.set(
"Access-Control-Allow-Headers",
"Content-Type, Authorization",
);
// Handle preflight requests
if (request.method === "OPTIONS") {
return new NextResponse(null, { status: 200, headers: response.headers });
}
return response;
}
export const config = {
matcher: "/api/:path*",
};
Environment-Specific Configuration
Create different configurations for development and production:
// lib/x402-config.ts
export const x402Config = {
facilitator: {
url: process.env.FACILITATOR_URL || "https://x402.blockeden.xyz",
apiKey: process.env.BLOCKEDEN_API_KEY!,
},
network: process.env.NETWORK || "sui",
payTo: process.env.ADDRESS! as `0x${string}`,
};
// Validate configuration
if (!x402Config.facilitator.apiKey || !x402Config.payTo) {
throw new Error("Missing required x402 environment variables");
}
Then use it in your routes:
import { requirePayment } from "x402-nextjs";
import { x402Config } from "@/lib/x402-config";
export const GET = requirePayment(
{
price: "$0.001",
network: x402Config.network,
},
x402Config.payTo,
x402Config.facilitator,
async (request: NextRequest) => {
return Response.json({ data: "Your data" });
},
);
Production Deployment
Before deploying to production:
- Switch to production network (e.g.,
suiinstead ofsui-testnet) - Use environment variables for all sensitive data
- Enable HTTPS (handled by most hosting platforms)
- Set up proper error logging
- Configure CORS for your production domains
- Add rate limiting to prevent abuse