Payments

x402 payments

Implement paid API calls using the x402 protocol. Every request is paid for by the user with a micro payment onchain.

React

x402 Playground

Try out a x402 payment in our live playground

Client Side

wrapFetchWithPayment wraps the native fetch API to automatically handle 402 Payment Required responses from any API call. It will:

  • Make the initial request
  • If a 402 response is received, parse the payment requirements
  • Verify the payment amount is within the allowed maximum
  • Sign a payment authorization
  • Create a payment header using the provided wallet signature
  • Retry the request with the payment header

Here's an example:

import { wrapFetchWithPayment } from "thirdweb/x402";
import { createThirdwebClient } from "thirdweb";
import { createWallet } from "thirdweb/wallets";
const client = createThirdwebClient({ clientId: "your-client-id" });
const wallet = createWallet("io.metamask"); // or any other wallet
await wallet.connect({ client });
const fetchWithPay = wrapFetchWithPayment(fetch, client, wallet);
// Make a request that may require payment
const response = await fetchWithPay(
"https://api.example.com/paid-endpoint",
);

Server Side

To make your API calls payable, you can use the settlePayment function in a middleware or in your endpoint directly.

Use the facilitator configuration function settle transactions with your thirdweb server wallet gaslessly and pass it to the settlePayment function.

Here's an example with a Next.js middleware:

import { createThirdwebClient } from "thirdweb";
import { facilitator, settlePayment } from "thirdweb/x402";
import { arbitrumSepolia } from "thirdweb/chains";
const client = createThirdwebClient({ secretKey: "your-secret-key" });
const thirdwebX402Facilitator = facilitator({
client,
serverWalletAddress: "0xYourWalletAddress",
});
export async function middleware(request: NextRequest) {
const method = request.method.toUpperCase();
const resourceUrl = request.nextUrl.toString();
const paymentData = request.headers.get("X-PAYMENT");
const result = await settlePayment({
resourceUrl,
method,
paymentData,
payTo: "0xYourWalletAddress",
network: arbitrumSepolia, // or any other chain
price: "$0.01", // can also be a ERC20 token amount
routeConfig: {
description: "Access to paid content",
},
facilitator: thirdwebX402Facilitator,
});
if (result.status === 200) {
// payment successful, execute the request
const response = NextResponse.next();
// optionally set the response headers back to the client
for (const [key, value] of Object.entries(
result.responseHeaders,
)) {
response.headers.set(key, value);
}
return response;
}
// otherwise, request payment
return NextResponse.json(result.responseBody, {
status: result.status,
headers: result.responseHeaders,
});
}
// Configure which paths the middleware should run on
export const config = {
matcher: ["/api/paid-endpoint"],
};

You can also use the verifyPayment function to verify the payment before settling it. This lets you do the work that requires payment first and then settle the payment.