A standalone x402 payment server that handles URL-based micropayments using the HTTP 402 Payment Required protocol. Each URL has its own payment address and price determined by a smart contract.
- Dynamic URL Payments: Each URL has its own payment configuration
- Smart Contract Integration: Fetches payment info from WebsiteRegistry contract
- x402 Protocol: Standard HTTP 402 Payment Required implementation
- Caching: 5-minute cache for smart contract calls
- Batch Processing: Handle multiple URLs in one request
npm installcp .env.example .env
# Edit .env with your configuration# Development
npm run dev
# Production
npm run build
npm startGET /api/healthGET /api/payment-info/wikipedia.orgPOST /api/pay/wikipedia.orgPOST /api/batch-payment-info
Content-Type: application/json
{
"urls": ["wikipedia.org", "nytimes.com"]
}- URL Request: Client requests payment info for a URL
- Smart Contract Query: Server checks WebsiteRegistry contract for payment requirements
- Dynamic Configuration: If payment required, configures x402 middleware with specific price and recipient
- HTTP 402 Response: Returns 402 Payment Required with payment headers
- Payment Processing: x402 middleware handles payment via Coinbase CDP
- Access Granted: Returns success response after payment completion
# 1. Check if payment is required
curl http://localhost:3001/api/payment-info/wikipedia.org
# Response if payment required:
{
"url": "wikipedia.org",
"paymentRequired": true,
"payTo": "0x742d35Cc6634C0532925a3b844Bc454e4438f44e",
"price": "$0.001000",
"network": "base-sepolia",
"paymentEndpoint": "/api/pay/wikipedia.org"
}
# 2. Make payment (with x402-compatible client)
curl -X POST http://localhost:3001/api/pay/wikipedia.org
# Response after successful payment:
{
"success": true,
"message": "Payment completed successfully!",
"url": "wikipedia.org",
"paidAmount": "$0.001000",
"paidTo": "0x742d35Cc6634C0532925a3b844Bc454e4438f44e",
"network": "base-sepolia",
"accessGranted": true
}The server integrates with the WebsiteRegistry smart contract:
- Address:
0xA8832D3E571396F5F9990b0ABAC3e370e003a9A7(Base Sepolia) - Functions Used:
isWebsiteRegistered(string)- Check if URL requires paymentgetWebsite(string)- Get payment amount and recipient address
- Domain Normalization: Automatically handles subdomains (e.g.,
en.wikipedia.org→wikipedia.org)
# Network (testnet)
FACILITATOR_URL=https://x402.org/facilitator
NETWORK=base-sepolia
PORT=3001
# Production (mainnet)
FACILITATOR_URL=https://api.cdp.coinbase.com/platform/v2/x402
NETWORK=base# Test health
curl http://localhost:3001/api/health
# Test payment info
curl http://localhost:3001/api/payment-info/wikipedia.org
# Test batch request
curl -X POST http://localhost:3001/api/batch-payment-info \
-H "Content-Type: application/json" \
-d '{"urls": ["wikipedia.org", "github.com"]}'Use x402-fetch or x402-axios for automatic payment handling:
import { wrapFetchWithPayment } from "x402-fetch";
const fetchWithPayment = wrapFetchWithPayment(fetch, account);
const response = await fetchWithPayment("http://localhost:3001/api/pay/wikipedia.org", {
method: "POST"
});x402/
├── server.ts # Main server file
├── lib/
│ └── website-registry.ts # Smart contract integration
├── package.json
├── tsconfig.json
├── .env.example
└── README.md
- Dynamic Middleware: Payment middleware configured per URL
- Smart Contract Client: Reads payment requirements from blockchain
- Caching Layer: Reduces contract calls for better performance
- Error Handling: Graceful fallbacks for network issues
- Environment: Set production environment variables
- Network: Switch to Base mainnet
- Facilitator: Use official Coinbase CDP facilitator
- Caching: Consider Redis for distributed caching
- Monitoring: Add health checks and metrics
This server can be integrated with any application that needs URL-based payments:
// Check payment requirements
const response = await fetch(`${X402_SERVER}/api/payment-info/${encodeURIComponent(url)}`);
const paymentInfo = await response.json();
if (paymentInfo.paymentRequired) {
// Handle payment via x402 protocol
// Client will automatically get 402 response and handle payment
}