Skip to content
Closed
Changes from 4 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
255 changes: 240 additions & 15 deletions apps/portal/src/app/payments/x402/page.mdx
Original file line number Diff line number Diff line change
@@ -1,29 +1,121 @@
import { ArticleIconCard } from "@doc";
import { ReactIcon } from "@/icons";

# x402 payments
# 402 Gated Payments

Implement paid API calls using the x402 protocol. Every request is paid for by the user with a micro payment onchain.
Implement gated API access with pay-per-request pricing. Users pay small amounts for each API call using cryptocurrency through the HTTP 402 Payment Required protocol.

<ArticleIconCard
title="x402 Playground"
description="Try out a x402 payment in our live playground"
title="402 Payments Playground"
description="Try out a 402 gated payment in our live playground"
icon={ReactIcon}
href="https://playground.thirdweb.com/payments/x402"
/>

## Client Side
## Introduction & Core Concepts

`wrapFetchWithPayment` wraps the native fetch API to automatically handle `402 Payment Required` responses from any API call. It will:
**402 gated payments** enable micropayments for API access using the HTTP 402 Payment Required status code, allowing developers to monetize their APIs with per-request pricing. Instead of traditional subscription models or API keys, users pay small amounts (typically $0.01-$0.10) for each API call using cryptocurrency.

### How it works
When a user makes a request to a paid API:
1. The API returns a `402 Payment Required` response with payment details
2. The user's wallet signs a payment authorization
3. The request is retried with a payment header
4. The API validates the payment and returns the requested data
5. The payment is settled on-chain to the API provider

### Benefits
- **No subscriptions**: Users only pay for what they use
- **Global access**: Works with any web3 wallet worldwide
- **Instant monetization**: Start earning from your APIs immediately
- **Micropayment friendly**: Perfect for small, frequent transactions

## 402 Payment Protocol Fundamentals

### Payment Flow
The 402 payment protocol follows a simple request-retry pattern:

1. **Initial request**: Client makes normal API call
2. **402 response**: Server responds with payment requirements if payment needed
3. **Payment authorization**: User signs payment message in their wallet
4. **Retry with payment**: Request is retried with payment header
5. **Content delivery**: Server validates payment and returns content

### Payment Processors
A **payment processor** is a service that handles payment verification and settlement for 402 payments. Think of it as the backend service that:
- Validates payment signatures from users
- Executes on-chain transfers to collect payments
- Provides payment infrastructure to API providers

### Payment Schemes
thirdweb's 402 payment implementation currently supports:
- **"exact"**: Fixed price payments (e.g., exactly $0.01 USDC) - our first supported scheme
- Additional schemes (percentage-based, auction-style, variable pricing) are planned for future versions

### Security Model
- **Signature-based**: Users sign payment authorizations, no direct token transfers from client
- **Replay protection**: Each payment includes unique identifiers to prevent reuse
- **Amount validation**: Clients can set maximum payment limits for protection

## Supported Payment Networks & Tokens

### Supported Networks
thirdweb's 402 payment processor currently supports payments on:
- **Base** (mainnet)
- **Base Sepolia** (testnet)
- **Avalanche** (C-Chain)
- **Avalanche Fuji** (testnet)
- **IoTeX** (mainnet)
- **Sei** (mainnet)
- **Sei Testnet**

### Payment Tokens
- **Primary**: USDC on all supported networks
- **Stablecoins**: Other USD-pegged tokens as available per network
- **Network selection**: Client and server automatically negotiate the best payment network

### Chain Switching
If your wallet is connected to a different network than required for payment, the client will automatically:
1. Detect the payment network requirement
2. Prompt you to switch to the correct network
3. Proceed with payment once switched

## thirdweb as 402 Payment Processor

thirdweb provides a complete 402 payment processing service that handles all the payment infrastructure for your APIs.

### What thirdweb Provides
- **Payment verification**: Validates user payment signatures and wallet balances
- **Multi-chain settlement**: Supports payments across multiple blockchain networks
- **Server wallet integration**: Uses your configured server wallet to receive payments
- **Gasless transactions**: Handles all gas costs for payment settlement
- **Automatic execution**: Payments are settled without manual intervention

### Server Wallet Concept
Your **server wallet** is the blockchain address where all API payments are collected. When users pay for API access:
1. They sign a payment authorization to your server wallet address
2. thirdweb validates the payment signature and user's token balance
3. thirdweb executes the token transfer to your server wallet
4. You receive the payment automatically without gas costs

### Integration Benefits
- **Simple setup**: Just provide your server wallet address and thirdweb secret key
- **No blockchain complexity**: thirdweb handles all on-chain interactions
- **Reliable settlement**: Payments are automatically executed when valid
- **Multi-chain support**: Accept payments on multiple networks simultaneously

## Client-Side Implementation

### Basic Usage

`wrapFetchWithPayment` wraps the native fetch API to automatically handle `402 Payment Required` responses, implementing thirdweb's "exact" payment scheme. It will:
1. Make the initial request
2. If a 402 response is received, parse the payment requirements
3. Verify the payment amount is within the allowed maximum
4. Sign a payment authorization
4. Sign a payment authorization
5. Create a payment header using the provided wallet signature
6. Retry the request with the payment header

Here's an example:

```typescript
import { wrapFetchWithPayment } from "thirdweb/x402";
import { createThirdwebClient } from "thirdweb";
Expand All @@ -39,11 +131,84 @@ const fetchWithPay = wrapFetchWithPayment(fetch, client, wallet);
const response = await fetchWithPay('https://api.example.com/paid-endpoint');
```

## Server Side
### Advanced Configuration

You can configure payment limits and behavior:

```typescript
// Set maximum payment amount (default: 1 USDC)
const fetchWithPay = wrapFetchWithPayment(
fetch,
client,
wallet,
BigInt(5 * 10 ** 6) // Maximum 5 USDC
);
```

### Error Handling

To make your API calls payable, you can use any x402 middleware library like x402-hono, x402-next, x402-express, etc.
Handle different payment scenarios:

Then, use the `facilitator` configuratino function settle transactions with your thirdweb server wallet gaslessly and pass it to the middleware.
```typescript
try {
const response = await fetchWithPay('/api/paid-endpoint');
const data = await response.json();
} catch (error) {
if (error.message.includes("Payment amount exceeds maximum")) {
// Handle payment too expensive
console.error("Payment required exceeds your limit");
} else if (error.message.includes("Wallet not connected")) {
// Handle wallet connection issues
console.error("Please connect your wallet");
} else if (error.message.includes("Payment already attempted")) {
// Handle retry scenarios
console.error("Payment was already processed");
} else {
// Handle other errors (user rejected, insufficient funds, etc.)
console.error("Payment failed:", error.message);
}
}
```

### React Integration

Use with React hooks for better UX:

```typescript
import { useActiveWallet } from "thirdweb/react";
import { useMutation } from "@tanstack/react-query";

function PayableAPICall() {
const wallet = useActiveWallet();

const paidApiCall = useMutation({
mutationFn: async () => {
if (!wallet) throw new Error("Wallet not connected");

const fetchWithPay = wrapFetchWithPayment(fetch, client, wallet);
const response = await fetchWithPay('/api/paid-endpoint');
return response.json();
},
});

return (
<button
onClick={() => paidApiCall.mutate()}
disabled={!wallet || paidApiCall.isPending}
>
{paidApiCall.isPending ? "Processing Payment..." : "Call Paid API"}
</button>
);
}
```

## Server-Side Implementation

### Basic Middleware Setup

To make your API calls payable, you can use any 402 payment middleware library. thirdweb provides payment processor integration for popular frameworks like `x402-next`, `x402-hono`, `x402-express`, etc.

Then, use the thirdweb payment processor configuration to settle transactions with your server wallet gaslessly and pass it to the middleware.

Here's an example with Next.js:

Expand All @@ -57,7 +222,7 @@ const client = createThirdwebClient({
});

export const middleware = paymentMiddleware(
"0xdd99b75f095d0c4d5112aCe938e4e6ed962fb024",
"0xdd99b75f095d0c4d5112aCe938e4e6ed962fb024", // Your server wallet address
{
"/api/paid-endpoint": {
price: "$0.01",
Expand All @@ -69,12 +234,72 @@ export const middleware = paymentMiddleware(
},
facilitator({
client,
serverWalletAddress: "0x1234567890123456789012345678901234567890",
}),
serverWalletAddress: process.env.SERVER_WALLET_ADDRESS,
}), // thirdweb payment processor configuration
);

// Configure which paths the middleware should run on
export const config = {
matcher: ["/api/paid-endpoint"],
};
```

### Payment Processor Configuration Deep-Dive

The `facilitator` function configures thirdweb's payment processor and accepts several options:

```typescript
facilitator({
client: thirdwebClient, // Your thirdweb client with secret key
serverWalletAddress: "0x..." // Where payments are collected
})
```

### Multiple Endpoint Configuration

Configure different pricing for multiple API endpoints:

```typescript
export const middleware = paymentMiddleware(
serverWalletAddress,
{
"/api/basic-data": {
price: "$0.01",
network: "base-sepolia",
config: { description: "Basic data access" },
},
"/api/premium-analytics": {
price: "$0.05",
network: "base", // Use mainnet for higher-value endpoints
config: { description: "Premium analytics data" },
},
"/api/ai-processing": {
price: "$0.10",
network: "base",
config: { description: "AI-powered data processing" },
},
},
facilitator({ client, serverWalletAddress }), // thirdweb payment processor
);

export const config = {
matcher: ["/api/basic-data", "/api/premium-analytics", "/api/ai-processing"],
};
```

### Environment Variables

Set up the required environment variables:

```bash
# .env.local
THIRDWEB_SECRET_KEY=your_thirdweb_secret_key
SERVER_WALLET_ADDRESS=0x1234567890123456789012345678901234567890
```

### Security Considerations

- **Never expose your secret key**: Keep `THIRDWEB_SECRET_KEY` in server environment only
- **Server wallet security**: Use a dedicated wallet for collecting payments, separate from development wallets
- **Network selection**: Use testnets for development, mainnets for production
- **Price validation**: Set appropriate prices to prevent abuse while maintaining accessibility
Loading