DEV Community

ORION
ORION

Posted on Edited on

x402 in Practice: Charge USDC Per API Call From Any Node.js Server

The x402 protocol revival (HTTP 402 "Payment Required") is picking up steam, and for good reason: it turns any API endpoint into a vending machine. No Stripe account, no webhook plumbing, no KYC queue. A client wants your data? It pays USDC first.

I maintain usdc-paywall, a small Node.js/TypeScript library that implements this flow end to end. This post shows the moving parts and the code.

The flow in 30 seconds

  1. Client calls your endpoint.
  2. Your server returns 402 with payment details (amount, recipient address, chain).
  3. Client pays USDC onchain and retries with a payment header.
  4. Your server verifies the tx onchain (amount, recipient, not reused) and serves the response.

No subscriptions, no invoicing. Pay per call.

Server side

import { paywall } from 'usdc-paywall';

const gate = paywall({
  recipient: process.env.PAY_WALLET, // your USDC address (Base)
  amount: 0.01,                      // USDC per call
  network: 'base',
});

app.get('/api/heavy', gate, (req, res) => {
  res.json({ result: 'paid and served' });
});
Enter fullscreen mode Exit fullscreen mode

Unpaid requests get a structured 402:

{
  "error": "payment_required",
  "payTo": "0x82d1...",
  "amount": "0.01",
  "network": "base",
  "asset": "USDC"
}
Enter fullscreen mode Exit fullscreen mode

Client side

import { UsdcpayClient } from 'usdc-paywall';

const client = new UsdcpayClient({
  payer: process.env.PAYER_WALLET, // EOA with USDC
  network: 'base',
});

const data = await client.fetch('https://api.example.com/api/heavy');
// handles 402 -> pays -> retries automatically
Enter fullscreen mode Exit fullscreen mode

The client reads the 402 terms, sends the transfer, waits for the receipt, and retries with the payment proof header. Your server validates it onchain — signature, amount, recipient, and replay protection are all checked in the library.

Why this matters more in 2026

  • Agents are callers now. AI agents with wallets can't fill Stripe checkout forms. They can, however, answer a 402 programmatically. Machine-to-machine payments are exactly what HTTP 402 was reserved for in 1996.
  • USDC on Base costs cents. A $0.01 API call is viable; card rails were never built for that.
  • No platform risk. Funds go straight to your address. No payout schedule, no reserve holds.

Gotchas I hit

  • Replay attacks: always track seen tx hashes server-side; the middleware does this by default.
  • Confirmations: don't serve on the mempool sighting; wait for the transfer receipt (the lib defaults to this).
  • Pricing granularity: expose the amount in the 402 body so clients can decide before paying.

Beyond the middleware

The free package covers the middleware and client. There's also a one-time Pro tier ($19 USDC) with Ed25519-signed licenses, a live pro watch mode that streams incoming payments via eth_getLogs (useful for dashboards and alerts), and CLI verification tooling.

If you're building paid endpoints for agents — or trying x402 before committing to it — I'd love to hear what's blocking you in the comments.

Top comments (0)