Basic Payment
The most basic x402test usage - make a request that requires payment.
Prerequisites
Section titled “Prerequisites”-
Solana validator running:
Terminal window solana-test-validator -
x402test server running:
Terminal window npx x402test start
Create 01-simple-payment.ts:
import { x402 } from "x402test";
async function example() { console.log("Example 1: Simple Payment\n");
try { // Make a request to a payment-protected endpoint const response = await x402("http://localhost:4402/api/data") .withPayment({ amount: "0.01" }) // Willing to pay up to 0.01 USDC .expectStatus(200) // Expect success .execute();
console.log("✔ Payment successful!"); console.log("Response:", JSON.stringify(response.body, null, 2)); console.log("Payment signature:", response.payment?.signature); } catch (error) { console.error("✘ Payment failed:", error); process.exit(1); }}
example();npx tsx 01-simple-payment.tsExpected Output
Section titled “Expected Output”Example 1: Simple Payment
✔ Payment successful!Response: { "method": "GET", "path": "/api/data", "data": { "message": "Your data here" }}Payment signature: 5XzT4qW3Hk2p7vN...What’s Happening
Section titled “What’s Happening”1. Initial Request
Section titled “1. Initial Request”The client makes a GET request to /api/data:
GET /api/data HTTP/1.1Host: localhost:44022. Server Response (402)
Section titled “2. Server Response (402)”Server returns payment requirements:
HTTP/1.1 402 Payment RequiredContent-Type: application/json
{ "x402Version": 1, "accepts": [{ "scheme": "solanaTransferChecked", "network": "solana-devnet", "maxAmountRequired": "10000", "resource": "http://localhost:4402/api/data", "payTo": "FcxKSp7YxqYXdq...", "asset": "EPjFWdd5AufqSSqeM2..." }]}3. Payment Creation
Section titled “3. Payment Creation”The client automatically:
- Creates a USDC transfer transaction
- Signs with test wallet
- Submits to Solana blockchain
- Waits for confirmation
4. Retry with Payment
Section titled “4. Retry with Payment”Client retries with X-PAYMENT header:
GET /api/data HTTP/1.1Host: localhost:4402X-PAYMENT: eyJ4NDAyVmVyc2lvbiI6...5. Server Verification
Section titled “5. Server Verification”Server verifies:
- Transaction exists and succeeded
- Amount matches requirement
- Recipient is correct
- Token is USDC
- Signature not already used
6. Success Response
Section titled “6. Success Response”Server returns protected content:
HTTP/1.1 200 OKContent-Type: application/json
{ "method": "GET", "path": "/api/data", "data": { "message": "Your data here" }}Key Concepts
Section titled “Key Concepts”withPayment()
Section titled “withPayment()”Specifies maximum amount willing to pay:
.withPayment({ amount: "0.01" }) // Object form.withPayment("0.01") // String formexpectStatus()
Section titled “expectStatus()”Asserts response status code:
.expectStatus(200) // Expect 200 OKThrows error if status doesn’t match.
execute()
Section titled “execute()”Executes the request:
const response = await request.execute();Returns X402Response<T> with:
status: HTTP status codebody: Response bodypayment: Payment details (if payment was made)
Variations
Section titled “Variations”Without Expectations
Section titled “Without Expectations”const response = await x402("http://localhost:4402/api/data") .withPayment("0.01") .execute();
// Manually check statusif (response.status === 200) { console.log("Success:", response.body);} else { console.error("Failed:", response.status);}With Additional Validation
Section titled “With Additional Validation”const response = await x402("http://localhost:4402/api/data") .withPayment("0.01") .expectStatus(200) .expectPaymentSettled() .expectBody((body) => body.data !== undefined) .execute();Error Handling
Section titled “Error Handling”try { const response = await x402(url) .withPayment("0.01") .expectStatus(200) .execute();
console.log("Success:", response.body);} catch (error) { if (error.message.includes("less than server required")) { console.error("Payment amount too low"); } else { console.error("Request failed:", error.message); }}Troubleshooting
Section titled “Troubleshooting”Error: “Connection refused”
Section titled “Error: “Connection refused””Cause: Server not running
Solution:
npx x402test startError: “Transaction not found”
Section titled “Error: “Transaction not found””Cause: Solana validator not running or transaction not confirmed
Solution:
solana-test-validatorError: “Insufficient balance”
Section titled “Error: “Insufficient balance””Cause: Test wallet depleted
Solution:
rm .x402test-wallets.jsonnpx x402test initNext Steps
Section titled “Next Steps”- Multiple Endpoints - Different price tiers
- Error Handling - Handle failures
- AI Agent - Autonomous agent example