A x402 Payment Protocol demo project implemented in Golang, consisting of a Server (Seller) and a Client (Buyer).
x402 is a micropayment protocol based on the HTTP 402 status code that allows APIs to require cryptocurrency payment before granting access. The flow is as follows:
Client Server Facilitator
| | |
| GET /weather | |
|------------------------->| |
| | |
| 402 Payment Required | |
| PAYMENT-REQUIRED: {...} | |
|<-------------------------| |
| | |
| Sign payment payload | |
| | |
| GET /weather | |
| PAYMENT-SIGNATURE: {...}| |
|------------------------->| |
| | Verify & settle payment |
| |------------------------->|
| 200 OK + data | |
|<-------------------------| |
x402-demo/
├── server/
│ └── main.go # Gin HTTP Server (Seller/payee)
├── client/
│ └── main.go # Go HTTP Client (Buyer/payer)
├── go.mod # Go module configuration
├── .env.example # Environment variable template
├── Makefile # Common commands
└── README.md
| Endpoint | Cost | Description |
|---|---|---|
GET /weather |
$0.001 USDC | Get weather data |
GET /analytics |
$0.01 USDC | Analytics report |
GET /news/:category |
$0.005 USDC | News by category |
GET /health |
Free | Health check |
GET / |
Free | API info page |
- Go 1.26+
- EVM-compatible wallet (for receiving payments)
- Testnet USDC (for making payments)
- Get Base Sepolia ETH and USDC from the CDP Faucet
cp .env.example .envEdit .env:
# Server (receive payments)
EVM_PAYEE_ADDRESS=0xYourWalletAddress # Your EVM wallet address
FACILITATOR_URL=https://x402.org/facilitator # Free testnet facilitator
# Client (make payments)
EVM_PRIVATE_KEY=0xYourPrivateKey # Use testnet keys only!make setup
# or
go mod tidymake server
# or
cd server && go run main.goExample output:
Starting x402 Server...
Payee address: 0xYourWalletAddress
Network: Base Sepolia (eip155:84532)
Facilitator: https://x402.org/facilitator
Port: 4021
Server listening at: http://localhost:4021
make client
# or
cd client && go run main.goExample output:
x402 Demo Client starting...
Server URL: http://localhost:4021
--- Test 1: Weather (0.001 USDC) ---
Requesting: http://localhost:4021/weather?city=Tokyo
Status: 200 | Time: 1.234s
Response [Weather]:
{
"city": "Tokyo",
"weather": "clear",
"temperature": "65 C",
"timestamp": "2024-04-30T12:00:00Z",
"powered_by": "x402 Payment Protocol"
}
Payment Details:
Success: true
Transaction: 0xabc123...
Network: eip155:84532
Payer: 0xYourAddress
Observe the 402 response without a payment:
make test-402
# or
curl -si http://localhost:4021/weather | grep -i "HTTP\|payment"| Variable | Required | Description |
|---|---|---|
EVM_PAYEE_ADDRESS |
Server required | EVM wallet address to receive payments |
FACILITATOR_URL |
Server required | Facilitator service URL |
PORT |
Optional | Server listen port (default 4021) |
EVM_PRIVATE_KEY |
Client required | EVM private key (testnet only!) |
EVM_RPC_URL |
Optional | EVM RPC URL (enables gas sponsoring) |
SERVER_URL |
Optional | Target server URL (default localhost:4021) |
| Facilitator | URL | Use Case | Requires |
|---|---|---|---|
| x402.org | https://x402.org/facilitator |
Testnet testing | No account needed |
| CDP | https://api.cdp.coinbase.com/platform/v2/x402 |
Testnet + Mainnet | CDP API Keys |
Update .env:
FACILITATOR_URL=https://api.cdp.coinbase.com/platform/v2/x402
CDP_API_KEY_ID=your-key-id
CDP_API_KEY_SECRET=your-key-secretUpdate the network in server/main.go and client/main.go:
// Testnet
Network: "eip155:84532" // Base Sepolia
// Mainnet
Network: "eip155:8453" // Base MainnetWarning: Mainnet transactions use real money! Always test thoroughly on testnet first.