x402 Payment Protocol

The first multi-chain, multi-asset x402 facilitator. Accept BTC, ETH, SOL, POL, BCH, USDC, Lightning, and card payments — all inline with HTTP requests.

BTCETHSOLPOLBCHUSDC⚡ Lightning💳 Stripe

How It Works

1

Client Requests

Client hits your API endpoint

2

402 + Options

Server returns all accepted payment methods

3

Client Pays

Client picks BTC, ETH, Lightning, card...

4

Access Granted

Payment verified, resource served

Fees

CoinPayPortal charges a small commission on each x402 payment, deducted before forwarding to the merchant. The same fee structure applies to all CoinPayPortal payment methods.

PlanCommissionMerchant ReceivesPrice
Starter (Free)1.0%99.0%$0/mo
Professional0.5%99.5%$49/mo

Network fees (gas, miner fees) are separate and vary by chain. Lightning payments have near-zero network fees. No hidden fees — what you see is what you pay.

How Clients Pay

When a client (browser, AI agent, or bot) hits an x402-protected endpoint, they get back a 402 response with all accepted payment methods. Here's what happens:

1. Client receives payment options

The 402 response body contains an accepts array — one entry per payment method the merchant supports:

HTTP/1.1 402 Payment Required
Content-Type: application/json

{
  "x402Version": 1,
  "accepts": [
    {
      "scheme": "exact",
      "network": "bitcoin",
      "asset": "BTC",
      "maxAmountRequired": "769",       // satoshis
      "payTo": "bc1qMerchant...",
      "extra": { "label": "Bitcoin" }
    },
    {
      "scheme": "exact",
      "network": "base",
      "asset": "0xA0b8...eB48",         // USDC contract
      "maxAmountRequired": "5000000",    // 6 decimals = $5.00
      "payTo": "0xMerchant...",
      "extra": { "label": "USDC on Base", "chainId": 8453 }
    },
    {
      "scheme": "exact",
      "network": "lightning",
      "asset": "BTC",
      "maxAmountRequired": "769",
      "payTo": "lno1Merchant...",        // BOLT12 offer
      "extra": { "label": "Lightning" }
    }
    // ... more methods
  ],
  "error": "Payment required"
}

2. Client picks a method and creates payment proof

The client chooses a payment method from the accepts array, then:

  • USDC (EVM chains): Sign an EIP-712 typed message authorizing a transferFrom — no on-chain tx yet, just a signature
  • Bitcoin/BCH: Broadcast a transaction to the merchant's address, include the txid as proof
  • Lightning: Pay the BOLT12 offer, include the preimage as proof
  • Solana: Sign and broadcast a transfer, include the signature
  • Stripe: Complete card checkout, include the payment intent ID

3. Client retries the request with payment proof

The payment proof goes in the X-PAYMENT header as a base64-encoded JSON payload:

GET /api/premium HTTP/1.1
X-PAYMENT: eyJzY2hlbWUiOiJleGFjdCIsIm5ldHdvcmsiOiJiYXNlIiwiYXNzZXQiOiIweEEwYjg2OTkx...

// Decoded X-PAYMENT payload:
{
  "scheme": "exact",
  "network": "base",
  "asset": "0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48",
  "payload": {
    "signature": "0xabc123...",       // EIP-712 sig (USDC)
    "authorization": {
      "from": "0xBuyerAddress...",
      "to": "0xMerchantAddress...",
      "value": "5000000",
      "validAfter": 0,
      "validBefore": 1739980800,      // expiry timestamp
      "nonce": "0xUniqueNonce..."
    }
  }
}

4. Server verifies and serves content

The middleware sends the proof to CoinPayPortal's facilitator (/api/x402/verify) which validates the signature, checks expiry, prevents replay attacks, and optionally settles on-chain. If valid → content is served. If invalid → another 402.

Client Libraries

For automated clients (AI agents, bots), use a library that handles the 402 → pay → retry loop:

import { x402fetch } from '@profullstack/coinpay';

// Wraps fetch() — automatically handles 402 responses
const response = await x402fetch('https://api.example.com/premium', {
  paymentMethods: {
    // Provide wallet/signer for chains you want to pay with
    base: { signer: wallet },           // EVM wallet (ethers/viem)
    lightning: { macaroon, host },       // LND credentials
    bitcoin: { wif: 'privateKey...' },   // BTC wallet
  },
  preferredMethod: 'usdc_base',          // optional: try this first
});

const data = await response.json();

Quick Setup

  1. Install the SDK: npm install @profullstack/coinpay
  2. Get your API key from Business Settings
  3. Configure wallet addresses for each chain you want to accept
  4. Add the x402 middleware — set a USD price and let the buyer choose their chain
  5. Test: coinpay x402 test --url http://localhost:3000/api/premium

Integration Code

import { createX402Middleware } from '@profullstack/coinpay';

const x402 = createX402Middleware({
  apiKey: 'YOUR_API_KEY',
  payTo: {
    bitcoin: 'bc1qYourBtcAddress',
    ethereum: '0xYourEvmAddress',
    polygon: '0xYourEvmAddress',
    solana: 'YourSolanaAddress',
    lightning: 'lno1YourBolt12Offer',
    stripe: 'acct_YourStripeId',
    'bitcoin-cash': 'bitcoincash:qYourBchAddress',
    base: '0xYourEvmAddress',
  },
  rates: { BTC: 65000, ETH: 3500, SOL: 150, POL: 0.50, BCH: 350 },
});

// Charge $5 — buyer picks their chain/asset
app.get('/api/premium', x402({ amountUsd: 5.00 }), (req, res) => {
  res.json({ data: 'premium content', paidWith: req.x402Payment });
});

Active x402 Endpoints

Endpoints are tracked automatically when payment verifications come through the facilitator.

EndpointMethodsPricePayments
No x402 endpoints detected yet. Set up the middleware to get started.

x402 Payment History

DateFromAmountMethodStatusTx
No x402 payments yet.

Supported Payment Methods

MethodAssetNetworkTypeKey
BitcoinBTCbitcoinNativebtc
Bitcoin CashBCHbitcoin-cashNativebch
EthereumETHethereumNativeeth
PolygonPOLpolygonNativepol
SolanaSOLsolanaNativesol
USDC on EthereumUSDCethereumStablecoinusdc_eth
USDC on PolygonUSDCpolygonStablecoinusdc_polygon
USDC on SolanaUSDCsolanaStablecoinusdc_solana
USDC on BaseUSDCbaseStablecoinusdc_base
LightningBTClightningLightninglightning
Card (Stripe)USDstripeFiatstripe