Skip to main content

Using x402 payments with Privy

Enable your users to pay for APIs and content using x402, the new HTTP payment protocol. Privy’s useX402Fetch hook makes it seamless to integrate automatic stablecoin payments with embedded wallets.

What is x402?

x402 is an open payment protocol that enables instant, automatic payments for APIs and digital content over HTTP. When a resource requires payment, the server responds with 402 Payment Required. The client constructs an X-PAYMENT header with a signed payment authorization and retries the request.

Installation

npm install @privy-io/react-auth
The useX402Fetch hook is built into @privy-io/react-auth (v3.7.0+).

Usage

Basic example

import {useX402Fetch, useWallets} from '@privy-io/react-auth';

function MyComponent() {
  const {wallets} = useWallets();
  const {wrapFetchWithPayment} = useX402Fetch();

  async function fetchPremiumContent() {
    // Wrap fetch with your wallet
    const fetchWithPayment = wrapFetchWithPayment({
      walletAddress: wallets[0]?.address,
      fetch
    });

    // Use exactly like native fetch - automatically handles 402 payments
    const response = await fetchWithPayment('https://api.example.com/premium');
    const data = await response.json();

    return data;
  }

  return <button onClick={fetchPremiumContent}>Fetch Premium Content</button>;
}

Using default connected wallet

import {useX402Fetch} from '@privy-io/react-auth';

function MyComponent() {
  const {wrapFetchWithPayment} = useX402Fetch();

  async function fetchPremiumContent() {
    // Omit walletAddress to use first connected wallet
    const fetchWithPayment = wrapFetchWithPayment({fetch});

    const response = await fetchWithPayment('https://api.example.com/premium');
    const data = await response.json();

    return data;
  }

  return <button onClick={fetchPremiumContent}>Fetch Premium Content</button>;
}

With maximum payment protection

import {useX402Fetch, useWallets} from '@privy-io/react-auth';

const {wallets} = useWallets();
const {wrapFetchWithPayment} = useX402Fetch();

const fetchWithPayment = wrapFetchWithPayment({
  walletAddress: wallets[0].address,
  fetch,
  maxValue: BigInt(1000000) // Max 1 USDC (6 decimals)
});

How it works

  1. User requests content: Client calls fetchWithPayment()
  2. Server responds 402: Returns payment requirements (USDC amount, recipient address, time window)
  3. Build typed data: Hook constructs EIP-712 typed data for USDC’s transferWithAuthorization
  4. Sign with Privy: User signs the authorization using their embedded wallet (no gas required)
  5. Build X-PAYMENT: Hook creates a base64-encoded JSON payload with authorization + signature
  6. Retry with payment: Request repeats with X-PAYMENT header
  7. Server verifies: Resource server calls facilitator to verify the payment
  8. Facilitator settles: Facilitator submits the authorization onchain and confirms the transaction
  9. Server delivers: Returns content with 200 OK

Key details

Requirements:
  • Users need USDC in their Privy embedded wallet on the correct network (e.g. Base, Base Sepolia, or Solana)
  • Use Privy’s useFundWallet hook to help users add funds if needed
  • The facilitator pays gas fees (users only need USDC, not ETH or SOL)
Testing:

x402 facilitators

Facilitators are services that verify payment authorizations and submit transactions onchain on behalf of users. They handle gas fees and transaction settlement, allowing users to pay only with USDC without needing native tokens like ETH or SOL. Several x402 facilitators are available, including:

Learn more