What is x402?
x402 is a standardized HTTP-based payment protocol for monetizing API requests via Solana. It enables per-request micropayments with cryptographic proof verification.
Lightning Fast
Payments confirmed in milliseconds
Secure by Default
On-chain cryptographic proof verification
Developer First
Simple integration through middleware
How It Works
Request & Challenge
Client requests a protected endpoint and receives a 402 response with payment details including amount, payee wallet, and facilitator URL.
Payment Processing
Client pays via facilitator using Solana USDC and receives a signed proof of payment with transaction hash and signature.
Verification & Access
Client retries the request with payment proof in headers. Server verifies the proof on-chain and grants access to the protected resource.
Installation
npm install @x402/middleware @x402/client
# or
yarn add @x402/middleware @x402/client
                        Environment Setup
X402_MERCHANT_WALLET=your_solana_wallet_address
X402_FACILITATOR_URL=https://facilitator.x402.network
X402_NETWORK=mainnet-beta
X402_MIN_PAYMENT=0.01
                        Basic Implementation
import express from 'express';
import { x402Middleware } from '@x402/middleware';
const app = express();
app.get('/api/generate',
  x402Middleware({ amount: "0.01', currency: "USDC' }),
  (req, res) => { 
    res.json(({ result: 'Your AI-generated content' }));
  ;
  (req, res) => { 
    res.json(({ result: 'Your AI-generated content' }));
  ;
app.listen(3000);
                        Middleware Configuration
const config = {
  amount: '0.05',
  currency: 'USDC',
  ttl: 120,
  facilitatorUrl: process.env.X402_FACILITATOR_URL,
  merchantWallet: process.env.X402_MERCHANT_WALLET,
  verifyOnChain: true,
  network: 'mainnet-beta'
;
app.use('/api/premium/*', x402Middleware(config));
                        Supports Solana, Base, and compatible networks.
402 Response Format
HTTP/1.1 402 Payment Required
Content-Type: application/json
{
  "amount": "0.01",
  "currency": "USDC",
  "payee": "7xKz...merchant_wallet",
  "reference": "pay_abc123def456",
  "facilitatorUrl": "https://facilitator.x402.network",
  "ttl": "120",
  "message": "Payment required to access this resource"
}
                        Custom Verification
import { verifyPaymentProof } from '@x402/middleware';
async function customVerifier(proof) {
  const isValid = await verifyPaymentProof(proof);
  if (proof.amount < 0.01) throw new Error('Insufficient payment');
  if (Date.now() > proof.expiresAt) throw new Error('Payment expired');
  return isValid;
}
                        Payment Endpoint
POST /facilitator/pay
{
  "amount": "0.01",
  "currency": "USDC",
  "payee": "7xKz...merchant_wallet",
  "reference": "pay_abc123def456",
  "payer": "9yUv...payer_wallet"
}
                            Response:
{
  "txId": "2Qz7...hash",
  "signature": "3Rx8...facilitator_signature",
  "timestamp": 1698765432
}
                            Verification Endpoint
POST /facilitator/verify
{
  "reference": "pay_abc123def456",
  "signature": "3Rx8...facilitator_signature",
  "txId": "2Qz7...transaction_hash"
}
                            Response:
{
  "valid": true,
  "status": "confirmed"
}
                            X402 Client Usage
import { X402Client } from '@x402/client';
const client = new X402Client({
  facilitatorUrl: 'https://facilitator.x402.network',
  wallet: yourSolanaWallet,
  autoRetry: true
}); 
const response = await client.get('https://api.example.com/generate');
console.log(response.data);
                        Manual Payment Flow
// Step 1: Make initial request
const response = await fetch('/api/analyze');
if (response.status === 402) {
  const paymentDetails = await response.json();
  // Step 2: Pay via facilitator
  const paymentResponse = await fetch(paymentDetails.facilitatorUrl + '/pay', {
    method: 'POST',
    body: JSONstringify({
      amount: paymentDetails.amount,
      payee: paymentDetails.payee,
      reference: paymentDetails.reference
    })
  }); 
  const proof = await paymentResponse.json();
  // Step 3: Retry with proof
  const finalResponse = await fetch('/api/analyze', {
    headers: {
      'X-Payment-Proof': proof.signature,
      'X-Payment-TxId': proof.txId
    }
  }); 
  const data = await finalResponse.json();
}
                        React Integration
import { useX402 } from '@x402/react';
function MyComponent() {
  const { call, loading, error } = useX402();
  const handleGenerate = async () => {
    const result = await call('/api/generate');
    console.log(result);
  ;
  return (
    <button onClick={handleGenerate} disabled={loading}>
      {loading ? 'Processing payment...' : 'Generate'}
    </button>
  );
}
                        Need Help?
Get support, join the community, or report issues with the x402 protocol.