Guide · Solana · 2026
How to build an x402-paid API on Solana
This is the seller path: your API stays locked until payment clears, then returns the data. Always re-check docs.x402.org before production. Package APIs can change.
The flow
- Client hits your route.
- You return HTTP 402 with price and payment details.
- Client pays on Solana.
- Client retries with payment proof.
- You verify and return 200.
Step 1: Get a receiving wallet
Create a Solana wallet. Put only the public address on your server. Never put a private key in your API.
Practice on devnet first. Devnet money is fake on purpose.
- Devnet network ID:
solana:EtWTRABZaYq6iMfeYKouRu166VU2xqa1 - Mainnet network ID:
solana:5eykt4UsFv8P8NJdTREpY1vzqKqZKvdp
Step 2: Install packages
npm install @x402/express @x402/core @x402/svm
Use @x402/hono or @x402/next if that is your framework.
Step 3: Protect a route (v2 shape)
Current docs use a routes-first config and an x402ResourceServer, not the old payTo-first signature.
import express from "express";
import { paymentMiddleware, x402ResourceServer } from "@x402/express";
import { HTTPFacilitatorClient } from "@x402/core/server";
import { ExactSvmScheme } from "@x402/svm/exact/server";
const app = express();
const payTo = process.env.X402_PAY_TO!; // Solana address
const facilitator = new HTTPFacilitatorClient({
url: "https://x402.org/facilitator", // testnet only
});
app.use(
paymentMiddleware(
{
"GET /api/premium": {
accepts: [
{
scheme: "exact",
price: "$0.01",
network: "solana:EtWTRABZaYq6iMfeYKouRu166VU2xqa1",
payTo,
},
],
description: "Premium data",
mimeType: "application/json",
},
},
new x402ResourceServer(facilitator).register(
"solana:EtWTRABZaYq6iMfeYKouRu166VU2xqa1",
new ExactSvmScheme(),
),
),
);
app.get("/api/premium", (_req, res) => {
res.json({ ok: true, message: "Paid access granted" });
});
app.listen(3000);Step 4: Test the 402
curl -i http://localhost:3000/api/premium
You should see status 402, not 200. When the endpoint is public, paste it into the 402 Checker.
Step 5: Go live carefully
- Switch to the mainnet network ID.
- Switch to a production facilitator (for example Coinbase CDP or PayAI at
https://facilitator.payai.network). - Use your real receiving address.
- Test with a tiny amount first.
The public test facilitator (https://x402.org/facilitator) is for testnets only. Do not point mainnet traffic at it.
Common mistakes
- Using the test facilitator on mainnet
- Putting an Ethereum-style
0xaddress in a Solana field - Forgetting to register the Solana payment scheme
- Leaving the route unprotected by accident