Getting Started with Express
Start accepting x402 payments in your Express server in 2 minutes.
You can find the full code for this example on GitHub.
Step 1: Create a New Server from the Starter Template
Use your favorite package manager.
npm (npx)
npx @blockeden/x402-express-starter my-first-server
pnpm
pnpm dlx @blockeden/x402-express-starter my-first-server
bun
bunx @blockeden/x402-express-starter my-first-server
The starter mirrors the upstream example and bootstraps a ready-to-run Express server.
Step 2: Set Your Environment Variables
Open your generated project's .env and set:
FACILITATOR_URL: Facilitator base URL (defaults to:https://x402.blockeden.xyz)NETWORK: Network to use for the facilitator (default:sui)ADDRESS: Wallet public address to receive payments toBLOCKEDEN_API_KEY: Your BlockEden.xyz API key from dashboard
FACILITATOR_URL=https://x402.blockeden.xyz
NETWORK=sui
ADDRESS=0x... # wallet public address you want to receive payments to
BLOCKEDEN_API_KEY=your_api_key_here
BlockEden.xyz supports multiple networks:
sui(recommended for fastest settlement)ethereumbasepolygonavalanche
Step 3: Preview the Server Code
This is the index.ts the starter generates. It loads your env, applies the x402 payment middleware, defines example routes, and logs the server URL.
import { config } from "dotenv";
import express from "express";
import { paymentMiddleware, Resource } from "@blockeden/x402-express";
config();
const facilitatorUrl = process.env.FACILITATOR_URL as Resource;
const payTo = process.env.ADDRESS as `0x${string}`;
const apiKey = process.env.BLOCKEDEN_API_KEY;
if (!facilitatorUrl || !payTo || !apiKey) {
console.error("Missing required environment variables");
process.exit(1);
}
const app = express();
app.use(
paymentMiddleware(
payTo,
{
"GET /weather": {
// USDC amount in dollars
price: "$0.001",
network: "sui",
},
"/premium/*": {
// Define atomic amounts in any supported token
price: {
amount: "100000",
asset: {
address: "0xabc",
decimals: 18,
name: "USDC",
},
},
network: "sui",
},
},
{
url: facilitatorUrl,
apiKey: apiKey,
},
),
);
app.get("/weather", (req, res) => {
res.send({
report: {
weather: "sunny",
temperature: 70,
},
});
});
app.get("/premium/content", (req, res) => {
res.send({
content: "This is premium content",
});
});
app.listen(4021, () => {
console.log(`Server listening at http://localhost:${4021}`);
});
Step 4: Run the Server
npm run dev
Step 5: Test the Server
You can test payments against your server locally using HTTP clients like curl, Postman, or by building a client application.
Client implementation guides for fetch API and axios will be available soon.
Payment Configuration Options
The paymentMiddleware accepts flexible payment configurations:
Simple Dollar Amount
"GET /weather": {
price: "$0.001",
network: "sui",
}
Atomic Token Amount
"/premium/*": {
price: {
amount: "100000",
asset: {
address: "0x...",
decimals: 6,
name: "USDC",
},
},
network: "sui",
}
Route Patterns
You can use wildcards and specific HTTP methods:
{
"GET /weather": { /* ... */ }, // Exact GET route
"/premium/*": { /* ... */ }, // Any method, wildcard path
"POST /api/analyze": { /* ... */ }, // Exact POST route
}
Advanced Features
Custom Payment Verification
app.use(
paymentMiddleware(
payTo,
paymentConfig,
{
url: facilitatorUrl,
apiKey: apiKey,
onPaymentVerified: (req, paymentData) => {
console.log('Payment verified:', paymentData.txHash);
// Custom logging or analytics
},
},
),
);
Error Handling
app.use((err, req, res, next) => {
if (err.name === 'X402PaymentError') {
res.status(402).json({
error: 'Payment required',
details: err.message,
});
} else {
next(err);
}
});
Production Deployment
Before deploying to production:
Switch to production facilitator endpoint Use production network (e.g., suiinstead ofsui-testnet)Enable HTTPS for your server Set up proper error logging Configure CORS if serving cross-origin clients
// Production configuration
const app = express();
// Enable CORS
app.use(cors({
origin: process.env.ALLOWED_ORIGINS?.split(','),
credentials: true,
}));
// Use production network
app.use(
paymentMiddleware(
payTo,
{
"GET /weather": {
price: "$0.01",
network: "sui", // Production Sui network
},
},
{
url: "https://x402.blockeden.xyz",
apiKey: process.env.BLOCKEDEN_API_KEY,
},
),
);
Troubleshooting
Common Issues
Payment verification fails
- Verify your
BLOCKEDEN_API_KEYis correct - Check that the wallet address format matches the network
- Ensure the facilitator URL is accessible
CORS errors
- Add CORS middleware before payment middleware
- Configure allowed origins properly
Network mismatch
- Ensure client and server use the same network
- Check that the token address is valid for the network