Protocol
x402
Type
Example
Stars
94
License
MIT
Last push
May 2, 2026

x402 Gateway Template x402 example

by azep-ninja• 94•
x402ExampleJavaScript

Self-hosted payment gateway template implementing x402

About x402 Gateway Template

x402 Gateway Template is an open-source x402 example by azep-ninja, written mainly in JavaScript. Self-hosted payment gateway template implementing x402. It has 94 GitHub stars and uses the MIT license, and its code was last pushed on May 2, 2026.

New to x402? Our x402 Protocol guide explains how it works and lists other projects built on it.

At a glance

Protocol
x402
Type
Example
Language
JavaScript
License
MIT
GitHub stars
94
Last push
May 2, 2026

Listed from public GitHub data, checked 2026-11-08. Not scanned by AgenticMart.

Questions about x402 Gateway Template

What is x402 Gateway Template?

Self-hosted payment gateway template implementing x402 It is listed as a x402 example, maintained in the azep-ninja/x402-gateway-template repository on GitHub.

How do I install x402 Gateway Template?

The project's README gives this command: docker run -p 8080:8080 --env-file .env x402-gateway. Read the README for setup steps and requirements before running it.

Is x402 Gateway Template an official x402 project?

No. It is a community project built on x402, not published by the organisation that runs the protocol.

What license does x402 Gateway Template use?

It is published under the MIT license. Check the license file in the repository before using it commercially.

Is x402 Gateway Template still maintained?

Its code was last pushed on May 2, 2026, and it had 94 GitHub stars when we checked on 2026-11-08. Look at recent issues and releases in the repository for a fuller picture.

README

x402 Payment Gateway Template

A production-ready, self-hosted payment gateway that implements the x402 protocol — HTTP-native micropayments for APIs. Accept stablecoin payments (USDC) per-request with no API keys, no subscriptions, and no intermediaries.

Fork this repo, configure your backend, and start accepting crypto micropayments in minutes.

What is x402?

x402 uses the HTTP 402 Payment Required status code to create a machine-readable payment flow:

1. Agent/client calls your API
2. Gateway returns 402 with payment requirements (chain, amount, token)
3. Agent signs a USDC transfer authorization
4. Agent retries with signed payment in header
5. Gateway verifies signature, settles on-chain, proxies to your backend
6. Client gets the API response + payment receipt

No wallets to integrate. No payment pages. Just HTTP headers.

Features

  • Multi-chain support — Accept USDC on Base, Ethereum, Arbitrum, Optimism, Polygon, Avalanche, Unichain, Linea, Sonic, HyperEVM, Ink, Monad, Abstract, and Solana out of the box
  • MegaETH support — USDM (18 decimals) via Meridian facilitator
  • Hybrid settlement — Local on-chain settlement via viem + optional external facilitators
  • Solana support — SVM payments via @x402/svm facilitator pattern
  • Replay protection — Redis-backed nonce tracking prevents double-spending
  • Idempotency — payment-identifier extension for safe retries without double-charging
  • Agent discovery — /accepted endpoint with full pricing, schemas, and network info
  • x402 well-known — /.well-known/x402 discovery document
  • Zero lock-in — Your backend never knows about x402; it just gets authenticated requests
  • Deploy anywhere — Docker-based; works on GCP Cloud Run, AWS ECS/Fargate, Railway, Fly.io, or bare metal

Quick Start

# Clone the template
git clone https://github.com/YOUR_USERNAME/x402-gateway-template.git
cd x402-gateway-template

# Install dependencies
npm install

# Configure
cp .env.example .env
# Edit .env with your values (see Configuration section)

# Run locally
npm run dev

# Test
curl http://localhost:8080/health
curl http://localhost:8080/accepted

Architecture

Client/Agent request
  → x402 Gateway (this service)
    → Verify payment signature (EIP-712 / SVM)
    → Settle on-chain (USDC transfer)
    → Proxy to your backend API (with internal auth)
    → Return response + payment receipt header
┌─────────────────────────────────────────────────┐
│                  x402 Gateway                    │
│                                                  │
│  ┌──────────┐  ┌──────────┐  ┌───────────────┐ │
│  │ Payment  │→ │ On-chain │→ │ Backend Proxy │ │
│  │ Verify   │  │ Settle   │  │ (your API)    │ │
│  └──────────┘  └──────────┘  └───────────────┘ │
│       │              │                           │
│  ┌──────────┐  ┌──────────┐                     │
│  │  Redis   │  │  RPC     │                     │
│  │ (nonces) │  │ (chains) │                     │
│  └──────────┘  └──────────┘                     │
└─────────────────────────────────────────────────┘

Configuration

1. Define Your Routes

Edit src/config/routes.js to define your paid API endpoints:

export const ROUTE_CONFIG = {
  // Each key becomes a route prefix: /v1/{key}/*
  myapi: {
    path: '/v1/myapi/*',
    backendName: 'My API',
    get backendUrl() { return process.env.MY_BACKEND_URL; },
    backendApiKeyEnv: 'MY_BACKEND_API_KEY',
    backendApiKeyHeader: 'x-api-key',       // Header name your backend expects
    get price() { return process.env.MY_PRICE || '$0.01'; },
    get priceAtomic() { return process.env.MY_PRICE_ATOMIC || '10000'; }, // 0.01 USDC in 6-decimal units
    get payTo() { return process.env.MY_PAY_TO_ADDRESS || process.env.PAY_TO_ADDRESS; },
    get payToSol() { return process.env.MY_PAY_TO_ADDRESS_SOL; },
    description: 'Description of your API for agent discovery',
    mimeType: 'application/json',
  },
};

2. Environment Variables

Required

VariableDescription
SETTLEMENT_PRIVATE_KEYPrivate key (0x hex) for the gas-paying settlement wallet
PAY_TO_ADDRESSDefault EVM wallet that receives USDC payments
BASE_RPC_URLAt least one RPC URL (Base recommended for low fees)

Backend (per route)

VariableDescription
MY_BACKEND_URLYour backend API base URL
MY_BACKEND_API_KEYInternal API key for your backend

RPC URLs (only configured chains are advertised)

VariableChainRequired Gas Token
BASE_RPC_URLBaseETH (~$5)
ETHEREUM_RPC_URLEthereumETH (~$20-50)
ARBITRUM_RPC_URLArbitrumETH (~$5)
OPTIMISM_RPC_URLOptimismETH (~$5)
POLYGON_RPC_URLPolygonPOL (~$2)
AVALANCHE_RPC_URLAvalancheAVAX (~$2)
UNICHAIN_RPC_URLUnichainETH (~$2)
LINEA_RPC_URLLineaETH (~$2)
MEGAETH_RPC_URLMegaETHN/A (facilitator pays)
SONIC_RPC_URLSonicS (~$2)
HYPEREVM_RPC_URLHyperEVMHYPE (~$15-20)
INK_RPC_URLInkETH (~$2)
MONAD_RPC_URLMonadMON (~$2)
ABSTRACT_RPC_URLAbstractNone (gas sponsored via paymaster)
SOLANA_RPC_URLSolanaSOL (~$2)

Solana (optional)

VariableDescription
SOLANA_FACILITATOR_PRIVATE_KEYBase58 private key for Solana fee payer
MY_PAY_TO_ADDRESS_SOLSolana wallet to receive USDC payments

Redis (required for replay protection)

VariableDescription
UPSTASH_REDIS_REST_URLUpstash Redis REST URL
UPSTASH_REDIS_REST_TOKENUpstash Redis REST token

Tip: Upstash has a generous free tier. Any Redis with REST API works.

Optional Overrides

VariableDescription
PORTServer port (default: 8080)
MY_PRICEDisplay price (e.g., "$0.05")
MY_PRICE_ATOMICPrice in token atomic units (e.g., "50000" for $0.05 USDC)

3. Settlement Wallet

The settlement wallet only pays gas to submit transferWithAuthorization on-chain. It never holds or receives stablecoins — payments flow directly from the payer to your payTo address.

Payer → (USDC) → Your payTo wallet     ← receives payment
Settlement wallet → (gas) → on-chain    ← only pays gas fees

Fund it with small amounts of native gas tokens on each chain you enable.

Adding Routes

Basic Route

  1. Add route config in src/config/routes.js
  2. Register the route in src/index.js:
// Paid route
app.all('/v1/myapi/{*path}', x402PaymentMiddleware('myapi'), async (req, res) => {
  const subpath = getSubpath(req.params);
  const route = ROUTE_CONFIG.myapi;
  await proxyToBackend({
    req, res,
    targetBase: route.backendUrl,
    targetPath: '/api/' + subpath,
    apiKey: process.env[route.backendApiKeyEnv],
    apiKeyHeader: route.backendApiKeyHeader,
  });
});

// Free route (no middleware)
app.get('/v1/myapi/health', async (req, res) => {
  // Proxy directly without payment
});

Path Aliases

Map user-friendly paths to your backend's actual routes:

const PATH_ALIASES = {
  'analyze': 'internal-analyze-endpoint',
  'report':  'generate-full-report',
};
const resolvedSubpath = PATH_ALIASES[subpath] || subpath;

Adding Chains

New EVM Chain

  1. Verify the chain has native Circle USDC with EIP-3009 support
  2. Add to src/config/routes.js:
const MY_CHAIN = {
  vm: 'evm',
  caip2: 'eip155:CHAIN_ID',
  chainId: CHAIN_ID,
  rpcEnvVar: 'MY_CHAIN_RPC_URL',
  token: usdc('0xUSDC_CONTRACT_ADDRESS'),
};
  1. Register in ALL_NETWORKS
  2. Add RPC URL to .env
  3. Fund settlement wallet with gas on that chain
  4. Add the viem chain import in src/middleware/x402.js

New EVM Chain with Facilitator

For chains where USDC doesn't support EIP-3009 yet:

const MY_CHAIN = {
  vm: 'evm',
  caip2: 'eip155:CHAIN_ID',
  chainId: CHAIN_ID,
  rpcEnvVar: 'MY_CHAIN_RPC_URL',
  facilitator: {
    url: 'https://facilitator-api.example.com/v1',
    apiKeyEnv: 'FACILITATOR_API_KEY',
    networkName: 'mychain',              // If facilitator uses short names
    facilitatorContract: '0x...',        // Facilitator's contract address
    x402Version: 1,                      // Facilitator's x402 version
  },
  token: {
    address: '0x...',
    name: 'Token Name',
    version: '1',
    decimals: 18,
  },
};

Solana

Solana support uses the @x402/svm facilitator pattern where:

  • The client partially signs a transaction
  • Your facilitator wallet co-signs as fee payer and submits

Requirements:

  • SOLANA_FACILITATOR_PRIVATE_KEY — Base58 private key
  • SOLANA_RPC_URL — Solana RPC endpoint
  • *_PAY_TO_ADDRESS_SOL — Solana wallet per route

Deployment

Docker (any platform)

docker build -t x402-gateway .
docker run -p 8080:8080 --env-file .env x402-gateway

GCP Cloud Run

See docs/deploy-gcp.md for full Cloud Run deployment with Secret Manager.

# Quick deploy
gcloud run deploy x402-gateway \
  --source . \
  --region us-east1 \
  --allow-unauthenticated \
  --set-env-vars "BASE_RPC_URL=https://..." \
  --set-secrets "SETTLEMENT_PRIVATE_KEY=x402-settlement-key:latest"

AWS ECS / Fargate

See docs/deploy-aws.md.

Railway / Fly.io / Render

See docs/deploy-paas.md.

API Endpoints

MethodPathAuthDescription
GET/healthFreeGateway health + backend status
GET/acceptedFreeAgent discovery — pricing, networks, schemas
GET/.well-known/x402Freex402 discovery document
ALL/v1/{route}/*PaidYour protected API routes

Agent Discovery

Agents call GET /accepted to discover your API before making paid requests:

curl https://your-gateway.com/accepted

Returns supported networks, pricing, and input/output schemas for each route. Compatible with Bazaar agent discovery protocol.

Compatible Agent Wallets

Any wallet that supports the x402 protocol works:

WalletDescription
@x402/fetchOfficial SDK — drop-in fetch replacement
OpenClaw / LobsterAgent framework with built-in x402
AgentWallet (frames.ag)x402 endpoint for agents
VincentMPC wallet with policy controls
Spongex402_fetch one-liner integration

Client Example

import { x402Fetch } from '@x402/fetch';

const res = await x402Fetch('https://your-gateway.com/v1/myapi/endpoint', {
  method: 'POST',
  body: JSON.stringify({ key: 'value' }),
  wallet  // any x402-compatible wallet
});

const data = await res.json();

Project Structure

├── src/
│   ├── index.js              # Express app, route registration
│   ├── proxy.js              # Backend proxy (injects internal auth)
│   ├── middleware/
│   │   └── x402.js           # Payment verification + settlement
│   ├── config/
│   │   └── routes.js         # Route definitions + network registry
│   └── utils/
│       └── redis.js          # Nonce tracking + idempotency cache
├── public/
│   └── index.html            # Landing page (optional)
├── docs/
│   ├── deploy-gcp.md         # GCP Cloud Run guide
│   ├── deploy-aws.md         # AWS ECS/Fargate guide
│   └── deploy-paas.md        # Railway/Fly.io/Render guide
├── Dockerfile
├── cloudbuild.yaml           # GCP Cloud Build config
├── .env.example
└── package.json

Credit System

The gateway includes an optional credit system that compensates payers when their request settles on-chain but the backend returns an error. Instead of refunding on-chain (which costs gas), the gateway issues credits that can be redeemed on subsequent requests.

How It Works

  1. Agent pays for a request → gateway settles on-chain → backend returns 5xx
  2. Gateway asynchronously issues a credit for that payer + route
  3. On the next request, the agent signs a new payment (proving wallet ownership)
  4. Gateway detects the credit, skips settlement, proxies to backend
  5. Response includes X-x402-Credit: consumed header

No on-chain refund, no extra gas, no special tokens. The agent retries identically and it just works.

Enable

Set ENABLE_CREDIT_SYSTEM=true in your .env. The system ships disabled by default.

Configuration

Global defaults are in CREDIT_DEFAULTS in routes.js. Override per-route:

myapi: {
  // ... other route config ...
  creditOnStatusCodes: [500, 502, 503, 504],  // Which backend errors earn credits
  maxCreditsPerPayer: 10,                       // Cap per payer per route
  creditTtl: 86400,                             // 24 hours
},

Set creditOnStatusCodes: [] to disable credits for a specific route.

Security

  • Identity: Payer address is extracted from the cryptographically verified signature — cannot be spoofed
  • Isolation: Credits are scoped per payer address per route — a credit on one route can't be used on another
  • Capped: maxCreditsPerPayer prevents unlimited accumulation from a degraded backend
  • Atomic: Redis Lua scripts prevent race conditions on concurrent requests
  • Graceful degradation: If Redis is down, credits silently disable and normal payment flow continues

Security Considerations

  • Settlement key — Store in a secrets manager (GCP Secret Manager, AWS Secrets Manager, etc.), never in env vars or code
  • Settlement wallet — Only holds gas tokens, never stablecoins. If compromised, attacker can only drain small gas balances
  • Pay-to address — This is YOUR wallet. Payments go directly from payer to you on-chain. The gateway never custodies funds
  • Redis — Used for nonce tracking. If Redis is down, the gateway fails open on reads (settlement still checks on-chain) and fails closed on writes (rejects payment to be safe)
  • Backend API keys — The gateway injects these server-side. Your backend never sees x402 traffic directly

License

MIT - fork it, ship it, make money with it.

Links

More x402 projects

All 20 →