Skip to main content

What is x402?

x402 is a payment protocol that uses the HTTP 402 Payment Required status code to enable machine-to-machine payments. When an agent hits a paywalled endpoint, the server responds with payment requirements; the agent’s wallet signs a USDC payment, and the request is retried with the payment proof attached. This gives AI agents a payment rail that works like an API call — no card forms, no browser sessions, no human in the loop.

How It Works

Payment Requirements

The 402 response includes everything the agent needs to construct a payment:
{
  "x402Version": 1,
  "accepts": [{
    "scheme": "exact",
    "network": "base",
    "maxAmountRequired": "25000000",
    "resource": "https://api.podium.build/api/v1/x402/orders/ord_abc/pay",
    "payToAddress": "0x...",
    "validUntil": "2026-03-08T00:00:00Z"
  }]
}
FieldDescription
schemePayment scheme (exact for fixed amount)
networkBlockchain network (base for Base mainnet)
maxAmountRequiredAmount in USDC atomic units (6 decimals, so 25000000 = $25.00)
payToAddressMerchant’s receiving address
validUntilPayment window expiration

Payment Execution

The agent signs a USDC payment using its wallet and includes the proof in the X-PAYMENT header:
import { wrapFetchWithPayment } from '@x402/fetch';

const response = await wrapFetchWithPayment(
  fetch,
  `${API_BASE}/api/v1/x402/orders/${orderId}/pay`,
  {}, // fetch options
  {
    wallet,                    // Privy embedded or server wallet
    maxValue: priceInUSDC,     // Max USDC willing to spend
    facilitatorUrl: 'https://facilitator.x402.org'
  }
);

Three Use Cases

1. Companion Order Payments

The most common flow: agents create a companion order and pay for it via x402. The concierge model means the user pays Podium in USDC, and Podium handles purchasing from the retailer and shipping.
import { createPodiumClient } from '@podium-sdk/node-sdk'
import { wrapFetchWithPayment } from '@x402/fetch'

const client = createPodiumClient({ apiKey: process.env.PODIUM_API_KEY })

const { data: order } = await client.companion.createOrders({
  requestBody: {
    userId: 'user_xyz',
    productId: 'prod_abc',
    shippingAddress: { street: '123 Main St', city: 'San Francisco', state: 'CA', zip: '94102', country: 'US' },
    email: 'user@example.com',
  },
})

const payment = await wrapFetchWithPayment(
  fetch,
  `https://api.podium.build/api/v1/x402/orders/${order.id}/pay`,
  {},
  { wallet, maxValue: order.amountUsdc }
)

// Order is now PAID — Podium handles fulfillment
console.log(`Order ${order.id} paid with USDC`)
The Conversational Agent automates this entire flow during chat — the agent’s create_order tool creates the companion order and the initiate_order tool guides the user through providing shipping details.

2. Standard Commerce Payments

For orders in Podium’s core commerce system (not companion orders), x402 works the same way:
const payment = await wrapFetchWithPayment(
  fetch,
  `https://api.podium.build/api/v1/x402/order/${coreOrderId}/pay`,
  {},
  { wallet, maxValue: orderAmountUsdc }
)

3. Pay-Per-Call API Access

Podium’s x402 middleware can gate any endpoint behind a crypto paywall. Agents pay per-request in USDC to access premium data or services:
// The middleware responds with 402 + payment requirements
// x402/fetch handles the payment negotiation automatically
const enrichedData = await wrapFetchWithPayment(
  fetch,
  `${API_BASE}/api/v1/premium/enrichment-data`,
  {},
  { wallet, maxValue: '100000' } // $0.10 per call
);
The x402 middleware is configured per-endpoint in the Podium API. When enabled, it intercepts requests before the route handler and requires a valid payment proof.

Wallet Options

Privy Server Wallets (Automated)

For bots and backend agents that need to pay without user interaction:
import { PrivyClient } from '@privy-io/node';

const privy = new PrivyClient(appId, appSecret);
const wallet = await privy.wallets().create({ chain_type: 'ethereum' });
// Use wallet for automated x402 payments

Privy Embedded Wallets (User-Controlled)

For consumer-facing apps where the user funds and controls the wallet:
import { usePrivy, useX402Fetch } from '@privy-io/react-auth';

const { user } = usePrivy();
const x402Fetch = useX402Fetch();

// User sees balance, can fund via Apple Pay / Google Pay / Coinbase
const response = await x402Fetch(
  `${API_BASE}/api/v1/x402/orders/${orderId}/pay`,
  { maxValue: priceInUSDC }
);

USDC on Base

All x402 payments settle in USDC on Base L2:
NetworkUSDC Address
Base Mainnet0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913
Base SepoliaDeployed MockUSDC per environment
The facilitator at https://facilitator.x402.org (Coinbase) handles payment verification and settlement.

Payment States

StateDescription
PENDINGPayment requirements sent, awaiting proof
VERIFIEDFacilitator confirmed the payment proof
SETTLEDUSDC transferred on-chain
FAILEDPayment verification or settlement failed

Graceful Fallback

When x402 payment fails (insufficient balance, network issues, wallet not configured), applications should fall back gracefully:
try {
  const result = await wrapFetchWithPayment(fetch, payUrl, {}, { wallet, maxValue });
  // Record PURCHASED interaction + full points
} catch (error) {
  // Record PURCHASE_INTENT interaction + partial points
  // Show user a link to the product page for manual checkout
}
The Beauty Companion reference implementation demonstrates this pattern — it awards 25 points for successful x402 purchases and 10 points for purchase intents where payment failed.