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
- Token-Based Pricing: Hold Bridge402 tokens to unlock discounts (see Token-Based Pricing section)
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
- Test token-based pricing with wallet address (if using Solana)
Token-Based Pricing¶
Bridge402 offers tiered pricing for Solana users who hold Bridge402 tokens. This feature automatically applies discounts based on your token holdings.
How It Works¶
- Provide Wallet Address: Include your Solana wallet address as the
wallet_addressquery parameter when requesting an invoice - Automatic Balance Query: The system queries your Bridge402 token balance on Solana
- Tiered Pricing: Your invoice is calculated based on your token holdings using linear interpolation
- Transparent Pricing: The invoice response includes your token balance and calculated daily rate
Pricing Tiers¶
| Token Balance | Daily Rate | Per Minute | Savings vs Base |
|---|---|---|---|
| 0 tokens | $15.00 | $0.0104 | - |
| 1,000,000 | ~$12.20 | ~$0.0085 | - |
| 2,500,000 | $8.00 | $0.0056 | - |
| 5,000,000+ | $1.00 | $0.000694 | 80% discount |
Token Details¶
- Token Mint:
86Qzt4Dpx51pYGj7TscfEEBbTspsnQJQpNQxodm6pump - Network: Solana Mainnet
- Calculation: Linear interpolation between tiers
- Automatic: No manual configuration needed
Usage Example¶
# Request invoice with wallet address for token-based pricing
curl -X POST "https://bridge402.tech/connect?duration_min=60&network=sol&wallet_address=YOUR_SOLANA_WALLET_ADDRESS"
Response:
{
"x402Version": 1,
"error": "X-PAYMENT header is required",
"accepts": [
{
"scheme": "exact",
"network": "solana",
"maxAmountRequired": "41667",
"asset": "EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v",
"extra": {
"tokenBalance": 2500000,
"pricePerDay": 8.0,
"product": "Bridge402 News — 60 min (Solana)"
}
}
]
}
Integration Tips¶
- Always provide
wallet_addressfor Solana payments to get the best pricing - Check the
extra.tokenBalanceandextra.pricePerDayfields in the invoice response - Token-based pricing applies to both initial connections and session extensions
- Works seamlessly with existing payment flow - no code changes required