Start hereLive

Quickstart: sellers

Put a USDC price on a Next.js route, settled by Axonpay’s free facilitator. You need a Solana address to get paid and one Agent Shop listing; no API key, no fee.

On this page+

1. Install

Shell
npm install @x402/core @x402/next @x402/svm

These are the official x402 v2 libraries (this guide uses 2.28). “Axon Gate” is simply our name for this setup. Express and Hono apps use @x402/express or @x402/hono with the same route config.

2. Pick a payout address

Any Solana address works as payTo: your Phantom account, a hardware wallet, a fresh keypair. One detail matters: the address needs a USDC token account before the first payment arrives. The payment transaction carries only the transfer and never creates accounts. Receiving any amount of USDC once, or creating the associated token account yourself, takes care of it.

.env.local
AXON_PAY_TO=YourSolanaAddress

3. Create the resource server

lib/x402.ts
import { x402ResourceServer } from "@x402/next";
import { HTTPFacilitatorClient } from "@x402/core/server";
import { ExactSvmScheme } from "@x402/svm/exact/server";

// CAIP-2 ids for Solana (x402 v2)
export const SOLANA_MAINNET = "solana:5eykt4UsFv8P8NJdTREpY1vzqKqZKvdp";
export const SOLANA_DEVNET = "solana:EtWTRABZaYq6iMfeYKouRu166VU2xqa1";

// Axonpay's facilitator: mainnet and devnet, pays the network fee, charges nothing.
// It only settles to a payTo that has an Agent Shop listing on that network.
const facilitator = new HTTPFacilitatorClient({
  url: "https://axonpay.fun/api/facilitator",
});

export const server = new x402ResourceServer(facilitator)
  .register(SOLANA_MAINNET, new ExactSvmScheme())
  .register(SOLANA_DEVNET, new ExactSvmScheme());

The resource server knows which facilitator verifies and settles payments and which networks you accept. ExactSvmScheme turns a dollar price into a USDC amount on the chosen network and adds the facilitator’s fee-payer address to every offer. Axonpay’s facilitator pays the network fee, records a receipt for every settle and charges nothing. To use another one (x402.org, PayAI, Coinbase CDP, your own), change the URL; see facilitator choices.

4. Protect a route

app/api/forecast/route.ts
import { NextRequest, NextResponse } from "next/server";
import { withX402 } from "@x402/next";
import { server, SOLANA_DEVNET } from "@/lib/x402";

async function handler(req: NextRequest) {
  const city = req.nextUrl.searchParams.get("city") ?? "Lisbon";
  // Your real work goes here: a model call, a database query, a scrape...
  return NextResponse.json({ city, summary: "Clear, 21°C, wind 9 km/h" });
}

// Settlement only happens if the handler answers with a status below 400.
export const GET = withX402(
  handler,
  {
    accepts: {
      scheme: "exact",
      price: "$0.01", // paid in USDC
      network: SOLANA_DEVNET,
      payTo: process.env.AXON_PAY_TO!, // your Solana address
      maxTimeoutSeconds: 60,
    },
    description: "One-day weather summary for a city",
    mimeType: "application/json",
  },
  server,
);

withX402 wraps one route handler. The handler runs only after the payment is verified, and the payment is settled only if the handler answers with a status below 400. A crash or a validation error never charges the buyer.

5. Check the 402

Call it without paying. You should get a 402 and the price tag:

Shell
curl -i "http://localhost:3000/api/forecast?city=Lisbon"

Answering 402 doesn’t need a listing; settling does. Deploy the route somewhere public over https (a preview deployment works), then paste its URL into the 402 Inspector in the dApp to see the decoded offer: network, amount, asset and payTo.

6. List it in the Agent Shop first

Axonpay’s facilitator only settles to a payTo that has an Agent Shop listing on that network. Sign in with the payTo wallet, paste the public URL, sign the listing message, done. Until then every payment is refused with axon_payto_not_listed. Listings are per network: this devnet route needs a devnet listing.

Then pay it from a devnet agent with Quickstart: agents. The paid response carries a PAYMENT-RESPONSE header with the transaction signature (open it on Solscan with ?cluster=devnet), and the settle shows up in the receipts ledger.

7. Move to mainnet

  • Use SOLANA_MAINNET (solana:5eykt4UsFv8P8NJdTREpY1vzqKqZKvdp) in the route; the server already registers both networks.
  • Price at $0.001 or more: Axonpay’s facilitator settles nothing smaller on mainnet.
  • Check that payTo has a mainnet USDC token account, and list the endpoint again on mainnet.
  • Look at https://axonpay.fun/api/facilitator/status before launch: it shows live whether mainnet is ready, or awaiting funding, and the exact policy numbers.