ChainX Protocol

HTTP 402 Payment Protocol - Complete Implementation Guide

What is HTTP 402?

HTTP 402 is a standard HTTP status code meaning "Payment Required". ChainX Protocol implements a complete payment protocol using blockchain transactions (Solana, Base, BSC).

Step 1: Client Makes Initial Request

// Client requests protected resource const response = await fetch('https://chainx402.xyz/api/data', { method: 'GET', headers: { 'Content-Type': 'application/json' } }); console.log('Status:', response.status); // Will be 402

Step 2: Server Responds with HTTP 402

HTTP/1.1 402 Payment Required X-Payment-Required: true X-Payment-Id: payment_abc123xyz X-Payment-Amount: 0.0004 X-Payment-Token: USDC X-Payment-Token-Mint: EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v X-Payment-To: SELLER_WALLET_ADDRESS X-Payment-Memo: ChainX:payment_abc123xyz X-Payment-Facilitator: https://chainx402.xyz/facilitator { "error": "Payment Required", "code": 402, "payment": { "id": "payment_abc123xyz", "amount": 0.0004, "token": "USDC" } }

Step 3: Client Reads Payment Headers

if (response.status === 402) { const paymentId = response.headers.get('X-Payment-Id'); const amount = parseFloat(response.headers.get('X-Payment-Amount')); const token = response.headers.get('X-Payment-Token'); const sellerWallet = response.headers.get('X-Payment-To'); const facilitatorUrl = response.headers.get('X-Payment-Facilitator'); console.log('Payment Required:', { paymentId, amount, token }); }

Step 4: Client Creates Payment Transaction

// Get payment instructions from facilitator const paymentRequest = await fetch(`${facilitatorUrl}/payment/request`, { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ chain: 'solana', seller: sellerWallet, amount: amount, token: token, tokenMint: tokenMint, metadata: { apiEndpoint: '/protected-data', paymentId: paymentId } }) }); const { paymentId: facilitatorPaymentId, paymentInstructions } = await paymentRequest.json();

Step 5: Client Signs and Sends Blockchain Transaction

// Solana payment transaction import { Connection, PublicKey, Transaction } from '@solana/web3.js'; import { getAssociatedTokenAddress, createTransferInstruction } from '@solana/spl-token'; async function sendPayment(instructions, wallet) { const connection = new Connection('https://api.mainnet-beta.solana.com'); // Get token accounts const tokenMint = new PublicKey(instructions.tokenMint); const sellerWallet = new PublicKey(instructions.to); const buyerTokenAccount = await getAssociatedTokenAddress( tokenMint, wallet.publicKey ); const sellerTokenAccount = await getAssociatedTokenAddress( tokenMint, sellerWallet ); // Create transfer instruction const transferInstruction = createTransferInstruction( buyerTokenAccount, sellerTokenAccount, wallet.publicKey, instructions.amount * 1e6, // USDC has 6 decimals [], TOKEN_PROGRAM_ID ); // Create and sign transaction const transaction = new Transaction().add(transferInstruction); transaction.recentBlockhash = (await connection.getLatestBlockhash()).blockhash; transaction.feePayer = wallet.publicKey; const signed = await wallet.signTransaction(transaction); const signature = await connection.sendRawTransaction(signed.serialize()); await connection.confirmTransaction(signature); return signature; } const signature = await sendPayment(paymentInstructions, wallet);

Step 6: Client Verifies Payment with Facilitator

const verifyResponse = await fetch(`${facilitatorUrl}/payment/verify`, { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ paymentId: facilitatorPaymentId, signature: signature, chain: 'solana' }) }); const verification = await verifyResponse.json(); // { status: 'verified', paymentId: '...', signature: '...' }

Step 7: Client Retries Request with Payment Proof

// Retry original request with payment headers const paidResponse = await fetch('https://chainx402.xyz/api/data', { method: 'GET', headers: { 'Content-Type': 'application/json', 'X-Payment-Id': paymentId, 'X-Payment-Signature': signature } }); if (paidResponse.status === 200) { const data = await paidResponse.json(); console.log('Protected data:', data); }

Step 8: Server Verifies Payment and Grants Access

// Server middleware verifies payment async function verifyPayment(paymentId, signature) { const response = await fetch(`${facilitatorUrl}/payment/verify`, { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ paymentId, signature }) }); const result = await response.json(); return result.status === 'verified'; } // Protected endpoint app.get('/protected-data', async (req, res) => { const paymentId = req.headers['x-payment-id']; const signature = req.headers['x-payment-signature']; if (!paymentId || !signature) { return res.status(402).json({ error: 'Payment Required' }); } const isValid = await verifyPayment(paymentId, signature); if (!isValid) { return res.status(402).json({ error: 'Payment verification failed' }); } // Payment verified, return data return res.json({ data: 'Protected content here' }); });

Complete Example: Paid API Server

// server.ts import { createPaidAPIServer } from '@ChainX/seller-sdk'; const server = await createPaidAPIServer({ facilitatorUrl: process.env.FACILITATOR_URL, sellerWallet: 'YOUR_WALLET_ADDRESS', defaultToken: 'USDC', defaultTokenMint: 'EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v', pricePerRequest: 0.0004, // $0.0004 USDC port: 3000 }); console.log('ChainX Protocol API Server running on port 3000');

Complete Example: Client with Auto-Payment

// client.ts import { createAPIClient } from '@ChainX/buyer-sdk'; const client = createAPIClient({ facilitatorUrl: process.env.FACILITATOR_URL, rpcUrl: 'https://api.mainnet-beta.solana.com' }); // Automatically handles 402, payment, and retry const data = await client.get('https://chainx402.xyz', '/api/data', { fromWallet: wallet.publicKey, signTransaction: wallet.signTransaction }); console.log('Data:', data);

HTTP 402 Headers Reference

Header Description Example
X-Payment-Id Unique payment identifier payment_abc123
X-Payment-Amount Payment amount (decimal) 0.0004
X-Payment-Token Token symbol USDC
X-Payment-To Seller wallet address YOUR_WALLET_ADDRESS
X-Payment-Signature Transaction signature (retry) 5j7s8...

Key Benefits

  • Standard HTTP Status Code - Uses official HTTP 402
  • Blockchain Payments - Supports Solana, Base, BSC
  • Sub-second Verification - Fast payment confirmation
  • Programmatic - Works with AI agents and automation
  • No Subscriptions - Pay per request
  • Automatic - SDK handles entire flow
← Back to Home