@x402x/express
v0.3.0
Published
Express middleware for x402x settlement framework
Maintainers
Readme
@x402x/express
Express middleware for the x402x settlement framework. Provides full x402 payment protocol support with x402x settlement extensions.
Features
- ✅ Full x402 Payment Flow: Automatic payment verification and settlement
- ✅ X402Context Extension: Access payment details in route handlers
- ✅ Multi-Network Support: Accept payments on multiple networks
- ✅ Custom Settlement Hooks: Configure hook contracts for programmable settlement
- ✅ Dollar-Denominated Pricing: Simple USD-based price configuration
- ✅ Facilitator Integration: Built-in facilitator support for payment processing
- ✅ Dynamic Fee Calculation: Automatically queries current gas prices for facilitator fees
- ✅ Built-in Caching: Caches fee calculations for better performance
Installation
npm install @x402x/express
# or
pnpm add @x402x/express
# or
yarn add @x402x/expressQuick Start
import express from "express";
import { paymentMiddleware } from "@x402x/express";
const app = express();
// Single route with automatic fee calculation (recommended)
app.post(
"/api/premium",
paymentMiddleware(
"0xYourRecipientAddress", // Final payment recipient
{
price: "$0.10", // Your business price (0.10 USD)
network: "base-sepolia", // Payment network
// facilitatorFee auto-calculated based on gas prices
config: {
description: "Access to premium content",
},
},
{
url: "https://facilitator.x402x.dev", // Facilitator for verify/settle/fee
},
),
(req, res) => {
// Access verified payment context (x402x extension)
const { payer, amount, network } = req.x402!;
console.log(`Received payment from ${payer}: ${amount} on ${network}`);
res.json({
success: true,
message: "Payment received and settled",
});
},
);
app.listen(3000);Key Concepts
When using dynamic fee calculation (recommended):
price: Your business/API price (what you charge for the service)- Facilitator fee: Automatically calculated based on current gas prices
- Total price:
price + facilitator fee(shown to users in 402 response)
For static fee (legacy mode), explicitly set facilitatorFee:
{
price: "$0.10",
facilitatorFee: "$0.02", // Fixed fee
}Multi-Network Support
// Accept payments on multiple networks
app.post(
"/api/multi-network",
paymentMiddleware("0xYourAddress", {
price: "$1.00",
network: ["base-sepolia", "base"], // Multiple networks
facilitatorFee: "$0.01",
}),
(req, res) => {
const { network } = req.x402!;
res.json({ message: `Paid on ${network}` });
},
);Multiple Routes Configuration
// Protect multiple routes with different prices
app.use(
paymentMiddleware(
"0xYourAddress",
{
"/api/basic": {
price: "$0.01",
network: "base-sepolia",
},
"/api/premium": {
price: "$1.00",
network: ["base-sepolia", "base"],
},
"/api/enterprise": {
price: "$10.00",
network: "base",
facilitatorFee: "$0.50",
},
},
facilitatorConfig,
),
);
// Route handlers can access req.x402
app.get("/api/basic", (req, res) => {
const { payer } = req.x402!;
res.json({ message: "Basic access", payer });
});Custom Settlement Hooks
// Use TransferHook for revenue split (built-in)
import { TransferHook } from "@x402x/core";
app.post(
"/api/referral",
paymentMiddleware("0xMerchantAddress", {
price: "$0.10",
network: "base-sepolia",
hook: TransferHook.getAddress("base-sepolia"),
hookData: TransferHook.encode([
{ recipient: "0xReferrerAddress", bips: 2000 }, // 20% to referrer
{ recipient: "0xPlatformAddress", bips: 1000 }, // 10% to platform
// Merchant gets remaining 70%
]),
}),
(req, res) => {
res.json({ message: "Revenue split executed" });
},
);
// Dynamic hook configuration
app.post(
"/api/nft-mint",
paymentMiddleware("0xMerchantAddress", {
price: "$1.00",
network: "base-sepolia",
hook: (network) => getNFTMintHookAddress(network),
hookData: (network) =>
encodeNFTMintData({
nftContract: getNFTContract(network),
tokenId: generateTokenId(),
merchant: "0xMerchantAddress",
}),
}),
(req, res) => {
const { payer } = req.x402!;
res.json({
message: "NFT minted",
recipient: payer,
});
},
);X402Context Access
The middleware extends Express Request with an x402 property containing payment details:
import type { X402Request } from '@x402x/express';
app.post('/api/payment',
paymentMiddleware(...),
(req: X402Request, res) => {
const x402 = req.x402!;
// Access verified payment information
console.log("Payer:", x402.payer); // Address of payer
console.log("Amount:", x402.amount); // Amount in atomic units
console.log("Network:", x402.network); // Network used
console.log("Payment:", x402.payment); // Full payment payload
console.log("Requirements:", x402.requirements); // Payment requirements
// Settlement information (x402x specific)
if (x402.settlement) {
console.log("Router:", x402.settlement.router);
console.log("Hook:", x402.settlement.hook);
console.log("Hook Data:", x402.settlement.hookData);
console.log("Facilitator Fee:", x402.settlement.facilitatorFee);
}
res.json({ success: true });
}
);API Reference
paymentMiddleware(payTo, routes, facilitator?)
Creates Express middleware for x402x payment processing.
Parameters:
payTo: string- Final recipient address for paymentsroutes: X402xRoutesConfig- Route configuration(s)facilitator?: FacilitatorConfig- Optional facilitator configuration
Returns: Express middleware function
X402xRouteConfig
interface X402xRouteConfig {
price: string | Money; // USD or Money object
network: Network | Network[]; // Single or multiple networks
hook?: string | ((network) => string);
hookData?: string | ((network) => string);
facilitatorFee?: string | Money | ((network) => string | Money);
config?: {
description?: string;
mimeType?: string;
maxTimeoutSeconds?: number;
resource?: Resource;
errorMessages?: {
paymentRequired?: string;
invalidPayment?: string;
noMatchingRequirements?: string;
verificationFailed?: string;
settlementFailed?: string;
};
};
}X402Context
interface X402Context {
payer: Address | SolanaAddress; // Verified payer address
amount: string; // Payment amount (atomic units)
network: Network; // Payment network
payment: PaymentPayload; // Decoded payment
requirements: PaymentRequirements; // Matched requirements
settlement?: {
// x402x settlement info
router: Address;
hook: Address;
hookData: string;
facilitatorFee: string;
};
}Payment Flow
The middleware handles the complete payment lifecycle:
- 402 Response: Returns payment requirements when no payment is provided
- Payment Decode: Decodes
X-PAYMENTheader from client - Verification: Verifies payment signature via facilitator
- Context Setup: Attaches payment details to
req.x402 - Handler Execution: Runs your route handler (business logic)
- Settlement: Settles payment via facilitator (if response status < 400)
- Response: Returns
X-PAYMENT-RESPONSEheader to client
Compatibility with x402
This middleware is fully compatible with the official x402 Express middleware API. To migrate from x402 to x402x:
// Before (x402)
import { paymentMiddleware } from "x402-express";
// After (x402x)
import { paymentMiddleware } from "@x402x/express";
// Same API! 🎉The only difference is the addition of req.x402 context and support for x402x settlement extensions.
Examples
See the showcase server for complete examples including:
- Revenue split (referral payments)
- NFT minting with payment
- Reward points distribution
- Multi-network support
Related Packages
@x402x/core- Core utilities and types@x402x/hono- Hono middleware (alternative to Express)@x402x/fetch- Client-side fetch wrapper@x402x/react- React hooks for payments
License
Apache-2.0
