Payment Integration
Payment Integration Guide¶
This guide covers how to integrate x402 payments with the Bridge402 API.
Overview¶
Bridge402 uses the x402 payment protocol to bridge Web2 APIs to Web3. All API endpoints require payment verification through the X-PAYMENT header, enabling crypto-native access to premium APIs that traditionally required subscriptions or credit cards.
Why x402 Payments? - AI Agent Friendly: Autonomous agents can make payments programmatically - No Subscriptions: Pay-per-use model perfect for intermittent access - Multi-chain: Supports both Base (EVM) and Solana networks - Micro-payments: Small, granular payments enable cost-effective access
Payment Flow¶
1. Request Payment Requirements¶
Make a request without the X-PAYMENT header to get payment requirements:
Response (402 Payment Required):
{
  "x402Version": 1,
  "error": "X-PAYMENT header is required",
  "accepts": [
    {
      "scheme": "exact",
      "network": "base",
      "maxAmountRequired": "10000",
      "asset": "0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913",
      "payTo": "0x745221d90e41193ee85c9d4679e40a9B57898A47",
      "resource": "https://bridge402.tech/stream",
      "description": "Access to Bridge402 crypto news stream for 10 minute(s)",
      "mimeType": "application/json",
      "maxTimeoutSeconds": 120,
      "extra": {
        "name": "USD Coin",
        "version": "2",
        "product": "Bridge402 News — 10 min",
        "minutes": 10,
        "resourcePath": "/stream"
      }
    }
  ]
}
2. Generate Payment¶
Use the x402-python library to generate payment authorization:
from x402 import X402Client
from x402.schemes.exact import ExactScheme
# Initialize client
client = X402Client(private_key, network="base")
# Create payment
payment = client.create_payment(
    scheme=ExactScheme(),
    amount=10000,  # 0.01 USDC in atomic units
    asset="0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913",
    pay_to="0x745221d90e41193ee85c9d4679e40a9B57898A47",
    resource="https://bridge402.tech/stream",
    description="Access to Bridge402 crypto news stream for 10 minute(s)"
)
# Encode payment
payment_b64 = payment.encode()
3. Submit Payment¶
Include the payment in the X-PAYMENT header:
curl -X POST "https://bridge402.tech/connect" \
  -H "X-PAYMENT: <base64-encoded-payment>" \
  -d "duration_min=10"
Payment Requirements¶
Supported Networks¶
- Base Mainnet (EVM): 
base - USDC Asset: 
0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913 - 
Uses EIP-3009 authorization flow
 - 
Solana Mainnet:
solanaorsol - USDC Mint: 
EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v - Uses transaction-based payments with feePayer support
 
Pricing¶
- News Stream: $0.0035 USDC per minute
 - 5 minutes: $0.0175 USDC (17,500 atomic units)
 - 10 minutes: $0.035 USDC (35,000 atomic units)
 - 60 minutes: $0.21 USDC (210,000 atomic units)
 - Earnings Transcripts: $0.05 USDC per document (50,000 atomic units)
 - Minimum Purchase: 5 minutes ($0.0175 USDC)
 
Amount Calculation¶
def calculate_amount(minutes: int) -> int:
    """Calculate payment amount in USDC atomic units"""
    rate_per_minute = 0.0035  # USDC per minute
    usdc_decimals = 6
    return int(minutes * rate_per_minute * (10 ** usdc_decimals))
# Examples:
# 5 minutes = 17,500 atomic units (0.0175 USDC)
# 10 minutes = 35,000 atomic units (0.035 USDC)
# 60 minutes = 210,000 atomic units (0.21 USDC)
Payment Schemes¶
Exact Scheme¶
Bridge402 uses the "exact" payment scheme, which requires:
- Exact Amount: Payment must match exactly (no overpayment)
 - Network: Base mainnet (EVM) or Solana mainnet
 - Asset: USDC with 6 decimals (same on both networks)
 - Timeout: 120 seconds for payment verification
 - Solana-Specific: Requires 
feePayeraddress (provided in invoiceextra.feePayer) 
Payment Payload Structure¶
Base (EVM) Payment:
{
  "x402Version": 1,
  "scheme": "exact",
  "network": "base",
  "payload": {
    "signature": "0x...",
    "authorization": "0x...",
    "transaction": "0x..."
  }
}
Solana Payment:
{
  "x402Version": 1,
  "scheme": "exact",
  "network": "solana",
  "payload": {
    "transaction": "base64-encoded-partially-signed-transaction"
  }
}
Note: Solana payments only require a transaction field in the payload. The transaction must be partially signed (payer signs, facilitator completes).
Integration Examples¶
Python Integration¶
import asyncio
import httpx
from x402 import X402Client
from x402.schemes.exact import ExactScheme
class Bridge402Client:
    def __init__(self, api_url: str, private_key: str):
        self.api_url = api_url
        self.x402_client = X402Client(private_key, network="base")
    async def create_payment(self, minutes: int, resource_path: str) -> str:
        """Create x402 payment for specified duration"""
        amount = int(minutes * 0.0035 * 1_000_000)  # USDC atomic units
        payment = self.x402_client.create_payment(
            scheme=ExactScheme(),
            amount=amount,
            asset="0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913",
            pay_to="0x745221d90e41193ee85c9d4679e40a9B57898A47",
            resource=f"{self.api_url}{resource_path}",
            description=f"Bridge402 access for {minutes} minutes"
        )
        return payment.encode()
    async def connect(self, minutes: int) -> dict:
        """Connect to Bridge402 with payment"""
        payment_data = await self.create_payment(minutes, "/stream")
        async with httpx.AsyncClient() as client:
            response = await client.post(
                f"{self.api_url}/connect",
                params={"duration_min": minutes},
                headers={"X-PAYMENT": payment_data}
            )
            if response.status_code == 200:
                return response.json()
            else:
                raise Exception(f"Payment failed: {response.text}")
JavaScript Integration¶
// Note: JavaScript x402 integration would require a library
// This is a conceptual example
class Bridge402Client {
  constructor(apiUrl, privateKey) {
    this.apiUrl = apiUrl;
    this.privateKey = privateKey;
  }
  async createPayment(minutes, resourcePath) {
    // In production, use a proper x402 JavaScript library
    const amount = minutes * 0.002 * 1_000_000; // USDC atomic units
    const payment = {
      x402Version: 1,
      scheme: "exact",
      network: "base",
      payload: {
        signature: "0x...", // Generated by x402 library
        authorization: "0x...", // Generated by x402 library
      }
    };
    return btoa(JSON.stringify(payment));
  }
  async connect(minutes) {
    const paymentData = await this.createPayment(minutes, "/stream");
    const response = await fetch(`${this.apiUrl}/connect`, {
      method: 'POST',
      headers: {
        'X-PAYMENT': paymentData,
        'Content-Type': 'application/json'
      },
      body: JSON.stringify({ duration_min: minutes })
    });
    if (response.ok) {
      return await response.json();
    } else {
      throw new Error(`Payment failed: ${response.statusText}`);
    }
  }
}
Error Handling¶
Payment Errors¶
402 Payment Required¶
402 Payment Verification Failed¶
402 Payment Settlement Failed¶
Error Handling Strategy¶
async def handle_payment_error(response):
    """Handle payment-related errors"""
    if response.status_code == 402:
        data = response.json()
        if "accepts" in data:
            # Payment required - show payment requirements
            print("Payment required:")
            for accept in data["accepts"]:
                print(f"  Amount: {accept['maxAmountRequired']} atomic units")
                print(f"  Asset: {accept['asset']}")
                print(f"  Pay To: {accept['payTo']}")
        else:
            # Payment verification failed
            print(f"Payment failed: {data.get('detail', 'Unknown error')}")
    elif response.status_code == 400:
        print("Bad request - check parameters")
    else:
        print(f"Unexpected error: {response.status_code}")
Testing Payments¶
Test Environment¶
For testing, you can use:
- Testnet: Base Sepolia testnet
 - Test USDC: Use test USDC tokens
 - Mock Payments: Use mock payment data (development only)
 
Mock Payment (Development Only)¶
def create_mock_payment(minutes: int) -> str:
    """Create mock payment for testing (NOT for production)"""
    mock_payment = {
        "x402Version": 1,
        "scheme": "exact",
        "network": "base",
        "payload": {
            "signature": "0x" + "0" * 130,
            "authorization": "0x" + "0" * 130,
        }
    }
    import base64
    import json
    return base64.b64encode(json.dumps(mock_payment).encode()).decode()
Security Considerations¶
Private Key Management¶
- Never hardcode private keys in source code
 - Use environment variables for sensitive data
 - Implement key rotation for production systems
 - Use hardware wallets for high-value transactions
 
Payment Validation¶
- Verify payment amounts before submission
 - Check network compatibility (Base mainnet)
 - Validate asset addresses (USDC contract)
 - Implement timeout handling for payment verification
 
Rate Limiting¶
- Limit payment attempts to prevent abuse
 - Implement exponential backoff for failed payments
 - Monitor payment patterns for suspicious activity
 
Production Checklist¶
Before deploying to production:
- Use real x402-python library (not mock payments)
 - Configure proper private key management
 - Set up monitoring for payment failures
 - Implement proper error handling
 - Test with small amounts first
 - Verify network connectivity to Base
 - Set up logging for payment events
 - Implement retry logic for failed payments
 - Test session extension flows
 - Verify WebSocket reconnection logic