Ping Demo
The Ping demo is the most minimal implementation of an HTTP 402 paywall using the x402 protocol. It demonstrates how to protect a simple API endpoint with a payment requirement.Overview
This demo creates an Express server with a single protected endpoint/ping that requires a $0.001 USDC payment to access. Without payment, the server returns HTTP 402 Payment Required with payment details. With valid payment, it returns { "message": "pong" }.
Key Features:
- Minimal Express TypeScript server
- Single protected endpoint requiring USDC payment
- Default network:
base-sepolia(testnet) - Simple x402 payment middleware integration
- Returns JSON or HTML paywall based on Accept header
Setup
Installation
Environment Variables
Create a.env file with the following configuration:
.env
PAY_TO- Your EVM wallet address to receive paymentsPORT- Server port (default: 3000)PRIVATE_KEY- Private key for the payer wallet (used by header generator)TARGET_URL- URL of the protected endpoint
Server Implementation
The server implementation is minimal, using thex402-express middleware:
src/server.ts
Usage
Access the Endpoint
Open http://localhost:3000/ping in your browser or use curl:- JSON response (with
Accept: application/jsonheader) - HTML paywall page (browser-like Accept header)
Request Without Payment (JSON)
Request With Payment
After generating an x402 payment header (see below), include it in your request:X-PAYMENT-RESPONSE header confirming payment processing.
Generating Payment Headers
The demo includes a script to generate X-PAYMENT headers for testing.Configure Payer Credentials
Generate Header
Use Header with curl
- Script fetches
/pingto readacceptsfrom the 402 JSON response - Signs an
exactEVM payment usingPRIVATE_KEY - Encodes the payment data as Base64
- Outputs the header value
Testing Tips
Pretty-Print 402 Response
View HTML Paywall
Test Multiple Requests
Each payment can typically be used once due to nonce tracking. Generate a new header for each test request.Payment Flow
Network Configuration
The demo uses Base Sepolia testnet by default:- Network:
base-sepolia - USDC Contract:
0x036CbD53842c5426634e7929541eC2318f3dCF7e - Price: $0.001 USDC (1000 base units with 6 decimals)
Get Testnet Tokens
Base Sepolia ETH (for gas):- Visit: https://www.alchemy.com/faucets/base-sepolia
- Paste your wallet address
- Request ETH
- Visit: https://faucet.circle.com/
- Select “Base Sepolia” network
- Paste your wallet address
- Request USDC
Key Concepts
HTTP 402 Status Code
HTTP 402 “Payment Required” was reserved for future use in the HTTP specification. The x402 protocol gives it a practical implementation for API monetization.Content Negotiation
The middleware respects theAccept header:
Accept: application/json→ Returns 402 JSON with payment detailsAccept: text/html→ Returns HTML paywall pageAccept: application/vnd.x402+json→ Returns x402-specific JSON format
Payment Schemes
This demo uses theexact scheme, which requires:
- Exact payment amount (no overpayment)
- Specific recipient address
- EIP-712 signature from payer
- Single-use nonce for replay protection
Dependencies
package.json
Next Steps
Weather Demo
Learn how to protect dynamic API endpoints with query parameters
Ping Crossmint
Add smart wallet integration with UI
Solana Demo
Implement paywalls on Solana blockchain
x402 Protocol
Read the full x402 specification
Troubleshooting
Server won’t start
Error:Error: listen EADDRINUSE
Solution: Port 3000 is already in use. Either kill the process or change the port:
Payment verification fails
Error:402 Payment Required even with payment header
Solutions:
- Verify the signature was created for the correct network (base-sepolia)
- Check that the payer wallet has sufficient USDC balance
- Ensure the payment amount matches exactly ($0.001)
- Generate a fresh payment header (nonces can’t be reused)
USDC contract address not found
Error: Asset address doesn’t match expected USDC contract Solution: The middleware automatically looks up USDC forbase-sepolia. If using a different network, update the network parameter in the middleware configuration.