Skip to main content

Overview

This guide shows how to use Magic’s Embedded Wallet to pay for x402-protected API endpoints. x402 is an open payment protocol by Coinbase that uses the HTTP 402 Payment Required status code to enable instant, gasless stablecoin payments over HTTP. When a server responds with 402, your app automatically signs a USDC payment and retries — no gas fees, no manual transfers.

Prerequisites

Before starting, ensure you have:
  1. A Magic Publishable API Key from your Magic Dashboard
  2. A Base RPC endpoint (e.g., from Alchemy or QuickNode)
  3. USDC on Base Sepolia in the user’s wallet (for testing)

How It Works

  1. User authenticates with Magic
  2. Your app makes a request to an x402-protected endpoint
  3. The server responds with HTTP 402 and payment requirements
  4. The x402 client signs a gasless USDC transfer (EIP-3009) using the user’s wallet
  5. The request is retried with the payment signature
  6. A facilitator verifies and settles the payment on-chain
  7. The server returns the requested resource
x402 payments are gasless for the payer. The protocol uses EIP-3009 transferWithAuthorization, which means the user signs a typed data message — no ETH needed for gas. The facilitator submits the on-chain transaction.

Setting Up the Clients

Install dependencies and initialize Magic with viem.
TypeScript

Creating a Custom Account

The x402 SDK expects a viem Account object that can sign typed data. Create a custom account adapter that delegates signing to Magic’s wallet.
TypeScript

Setting Up the x402 Client

Register the Magic account with the x402 client and create a payment-enabled fetch wrapper.
TypeScript

Making Paid Requests

Use fetchWithPayment just like the regular fetch API. If the server responds with 402, the x402 client automatically handles the payment flow.
TypeScript
The x402 client handles everything automatically:
  1. Receives the 402 response with payment requirements
  2. Signs a gasless USDC transfer using the Magic wallet
  3. Retries the request with the payment signature in the header
  4. Returns the successful response

Setting Up a Test Server

To test the payment flow, you can set up a simple Express server that requires x402 payment.
TypeScript
The testnet facilitator at https://x402.org/facilitator requires no API keys or signup. For production, switch to the Coinbase CDP facilitator with network eip155:8453 (Base mainnet).

Switching to Production

To move from testnet to mainnet, update the network and facilitator:
TypeScript

Key Dependencies


Troubleshooting

Symptoms: The facilitator rejects the payment signature.Solutions:
  • Ensure the user has sufficient USDC on the correct network (Base Sepolia for testing, Base mainnet for production)
  • Verify the Magic wallet is connected to the right chain
  • Check that the signTypedData call is not being blocked by content security policy
Symptoms: The fetch call returns a raw 402 response instead of automatically paying.Solutions:
  • Make sure you’re using fetchWithPayment (the wrapped version), not the native fetch
  • Verify the x402 client has a scheme registered for the server’s network
  • Check that ExactEvmScheme is imported from @x402/evm/exact/client (not /server)
Symptoms: Payment fails with a network mismatch error.Solutions:
  • The Magic instance must be configured for the same chain as the x402 server
  • Use eip155:84532 for Base Sepolia or eip155:8453 for Base mainnet
  • Ensure the viem chain matches (baseSepolia or base)

Resources

Magic Embedded Wallets

Learn about Magic’s Embedded Wallet product

x402 Documentation

Official x402 protocol documentation

x402 GitHub

Reference implementations and examples

x402 Foundation

Protocol specification and facilitator info