Chapter 5: Payment & Credits
Overview
The Polysystems Backend API uses a prepaid credit system powered by x402 cryptocurrency payments. This chapter explains how to add credits to your account, manage transactions, and understand the payment flow.
Credit System Architecture
User Account
├── Credit Balance (USD)
├── Payment Methods (BTC, ETH, SOL)
├── Transaction History
└── Spending Limits (per Access Token)
↓
API Request → Pricing Check → Balance Check → Deduct Credits → Execute RequestHow Credits Work
Credit Model
- Currency: All credits are denominated in USD
- Precision: Prices calculated to 4 decimal places ($0.0001)
- Minimum Balance: $0.00 (but requests require sufficient balance)
- No Expiration: Credits never expire
- Non-Refundable: Credits cannot be withdrawn or refunded
Credit Flow
1. Add Credits via Crypto Payment
↓
2. Credits Added to Account Balance
↓
3. Make API Requests
↓
4. Credits Automatically Deducted
↓
5. Transaction Recorded
↓
6. Balance UpdatedChecking Your Balance
Get Current Balance
curl -X GET https://api.polysystems.ai/api/payments/credits/balance \
-H "Authorization: Bearer YOUR_JWT_TOKEN"Response:
{
"user_id": "user-123e4567-e89b-12d3-a456-426614174000",
"balance": 47.3250,
"currency": "USD",
"last_updated": "2024-01-15T14:30:00Z"
}Balance Information
- balance: Current available credits in USD
- currency: Always USD
- last_updated: Timestamp of last balance change
x402 Payment System
What is x402?
x402 is a payment protocol that enables direct cryptocurrency payments for API usage. It provides:
- Direct Crypto Payments: No intermediaries or payment processors
- Multiple Currencies: BTC, ETH, and SOL supported
- Automatic Confirmation: Blockchain monitoring for payment verification
- Instant Credit: Credits added immediately after confirmation
Supported Cryptocurrencies
| Currency | Symbol | Required Confirmations | Avg Confirmation Time |
|---|---|---|---|
| Bitcoin | BTC | 3 | ~30 minutes |
| Ethereum | ETH | 12 | ~3 minutes |
| Solana | SOL | 1 | ~30 seconds |
Creating a Payment
Step 1: Get Payment Methods
Check available payment methods:
curl -X GET https://api.polysystems.ai/api/payments/payments/methods \
-H "Authorization: Bearer YOUR_JWT_TOKEN"Response:
{
"methods": [
{
"currency": "BTC",
"name": "Bitcoin",
"required_confirmations": 3,
"average_confirmation_time": "30 minutes",
"network_fee_estimate": "low"
},
{
"currency": "ETH",
"name": "Ethereum",
"required_confirmations": 12,
"average_confirmation_time": "3 minutes",
"network_fee_estimate": "medium"
},
{
"currency": "SOL",
"name": "Solana",
"required_confirmations": 1,
"average_confirmation_time": "30 seconds",
"network_fee_estimate": "low"
}
]
}Step 2: Create Payment Request
curl -X POST https://api.polysystems.ai/api/payments/payments \
-H "Authorization: Bearer YOUR_JWT_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"amount_usd": 50.00,
"currency": "ETH"
}'Request Parameters:
amount_usd(required): Amount in USD to add to balancecurrency(required): Cryptocurrency to use (BTC, ETH, or SOL)expires_in_minutes(optional): Payment expiration (default: 1440 = 24 hours)
Response:
{
"id": "pay-123e4567-e89b-12d3-a456-426614174000",
"payment_hash": "x402_a1b2c3d4e5f6g7h8i9j0k1l2m3n4o5p6",
"currency": "ETH",
"amount_crypto": 0.0275,
"amount_usd": 50.00,
"to_address": "0x742d35Cc6634C0532925a3b844Bc9e7595f0bEb",
"status": "pending",
"confirmations": 0,
"required_confirmations": 12,
"tx_hash": null,
"created_at": "2024-01-15T15:00:00Z",
"expires_at": "2024-01-16T15:00:00Z"
}Step 3: Send Cryptocurrency
Send the exact amount_crypto to the to_address:
Important:
- ⚠️ Send exactly the amount specified in
amount_crypto - ⚠️ Send to the exact address in
to_address - ⚠️ Complete transaction before
expires_at - ⚠️ Include sufficient network fees for timely confirmation
Step 4: Wait for Confirmation
The system automatically monitors the blockchain for your transaction. You can check status:
curl -X GET https://api.polysystems.ai/api/payments/payments/{payment_id} \
-H "Authorization: Bearer YOUR_JWT_TOKEN"Response (Confirming):
{
"id": "pay-123e4567-e89b-12d3-a456-426614174000",
"payment_hash": "x402_a1b2c3d4e5f6g7h8i9j0k1l2m3n4o5p6",
"currency": "ETH",
"amount_crypto": 0.0275,
"amount_usd": 50.00,
"to_address": "0x742d35Cc6634C0532925a3b844Bc9e7595f0bEb",
"status": "confirming",
"confirmations": 6,
"required_confirmations": 12,
"tx_hash": "0x1234567890abcdef...",
"created_at": "2024-01-15T15:00:00Z",
"confirmed_at": null,
"expires_at": "2024-01-16T15:00:00Z"
}Response (Confirmed):
{
"id": "pay-123e4567-e89b-12d3-a456-426614174000",
"payment_hash": "x402_a1b2c3d4e5f6g7h8i9j0k1l2m3n4o5p6",
"currency": "ETH",
"amount_crypto": 0.0275,
"amount_usd": 50.00,
"to_address": "0x742d35Cc6634C0532925a3b844Bc9e7595f0bEb",
"status": "confirmed",
"confirmations": 12,
"required_confirmations": 12,
"tx_hash": "0x1234567890abcdef...",
"created_at": "2024-01-15T15:00:00Z",
"confirmed_at": "2024-01-15T15:15:00Z",
"expires_at": "2024-01-16T15:00:00Z"
}Payment Status States
| Status | Description | Next Action |
|---|---|---|
pending | Waiting for transaction | Send cryptocurrency |
confirming | Transaction detected, waiting for confirmations | Wait |
confirmed | Payment confirmed, credits added | Use API |
failed | Transaction failed | Create new payment |
expired | Payment window expired | Create new payment |
Listing Payments
View all your payment history:
curl -X GET "https://api.polysystems.ai/api/payments/payments?limit=10&offset=0" \
-H "Authorization: Bearer YOUR_JWT_TOKEN"Response:
{
"payments": [
{
"id": "pay-123",
"amount_usd": 50.00,
"currency": "ETH",
"status": "confirmed",
"created_at": "2024-01-15T15:00:00Z",
"confirmed_at": "2024-01-15T15:15:00Z"
},
{
"id": "pay-456",
"amount_usd": 100.00,
"currency": "BTC",
"status": "confirmed",
"created_at": "2024-01-10T10:00:00Z",
"confirmed_at": "2024-01-10T10:45:00Z"
}
],
"total": 2,
"limit": 10,
"offset": 0
}Transaction History
Every credit deduction creates a transaction record.
List Transactions
curl -X GET "https://api.polysystems.ai/api/payments/transactions?limit=20&offset=0" \
-H "Authorization: Bearer YOUR_JWT_TOKEN"Response:
{
"transactions": [
{
"id": "tx-123e4567-e89b-12d3-a456-426614174000",
"user_id": "user-123",
"amount": 0.0020,
"type": "debit",
"status": "completed",
"description": "API request: POST /api/hub/agents/chat",
"reference_id": "key-789",
"metadata": {
"route": "/api/hub/agents/chat",
"method": "POST",
"price": 0.0020
},
"created_at": "2024-01-15T14:30:00Z"
},
{
"id": "tx-456e7890-e12b-34d5-a678-901234567890",
"user_id": "user-123",
"amount": 50.00,
"type": "credit",
"status": "completed",
"description": "x402 payment confirmed",
"reference_id": "pay-123",
"metadata": {
"payment_hash": "x402_...",
"currency": "ETH"
},
"created_at": "2024-01-15T15:15:00Z"
}
],
"total": 2,
"limit": 20,
"offset": 0
}Transaction Types
| Type | Description | Amount |
|---|---|---|
credit | Credits added to account | Positive |
debit | Credits deducted for API usage | Negative (shown as positive) |
refund | Credits refunded (rare) | Positive |
adjustment | Manual adjustment by admin | Positive or Negative |
Transaction Status
| Status | Description |
|---|---|
pending | Transaction initiated |
completed | Transaction finalized |
failed | Transaction failed |
reversed | Transaction reversed |
Get Transaction Details
curl -X GET https://api.polysystems.ai/api/payments/transactions/{transaction_id} \
-H "Authorization: Bearer YOUR_JWT_TOKEN"Response:
{
"id": "tx-123e4567-e89b-12d3-a456-426614174000",
"user_id": "user-123e4567-e89b-12d3-a456-426614174000",
"amount": 0.0020,
"type": "debit",
"status": "completed",
"description": "API request: POST /api/hub/agents/chat",
"reference_id": "key-789abc",
"metadata": {
"route": "/api/hub/agents/chat",
"method": "POST",
"price": 0.0020,
"tokens_used": 150,
"model": "gpt-4"
},
"created_at": "2024-01-15T14:30:00Z",
"updated_at": "2024-01-15T14:30:01Z"
}Transaction Statistics
Get aggregated statistics about your transactions:
curl -X GET "https://api.polysystems.ai/api/payments/transactions/stats?start_date=2024-01-01&end_date=2024-01-31" \
-H "Authorization: Bearer YOUR_JWT_TOKEN"Response:
{
"period": {
"start_date": "2024-01-01T00:00:00Z",
"end_date": "2024-01-31T23:59:59Z"
},
"summary": {
"total_credits_added": 150.00,
"total_credits_spent": 47.65,
"net_change": 102.35,
"transaction_count": 2345,
"average_transaction_amount": 0.0203
},
"by_type": {
"credit": {
"count": 3,
"total_amount": 150.00
},
"debit": {
"count": 2342,
"total_amount": 47.65
}
},
"by_day": [
{
"date": "2024-01-15",
"credits_spent": 5.23,
"transaction_count": 156
}
],
"top_routes": [
{
"route": "/api/hub/agents/chat",
"count": 1234,
"total_cost": 24.68
},
{
"route": "/api/hub/memory",
"count": 567,
"total_cost": 11.34
}
]
}Automatic Payment Processing
Background Jobs
The system runs automated jobs to:
- Monitor Blockchain: Check for incoming transactions every 30 seconds
- Update Confirmations: Track confirmation counts for pending payments
- Mark Expired: Automatically expire payments past their deadline
- Send Webhooks: Notify on payment status changes
- Add Credits: Automatically credit accounts when payments confirm
Webhook Notifications
Configure webhooks to receive payment notifications (see Chapter 8):
Payment Events:
payment.created- New payment initiatedpayment.confirming- Transaction detected on blockchainpayment.confirmed- Payment confirmed, credits addedpayment.failed- Payment failedpayment.expired- Payment window expired
Example Webhook Payload:
{
"event_id": "evt-123",
"event_type": "payment.confirmed",
"timestamp": "2024-01-15T15:15:00Z",
"data": {
"payment_id": "pay-123",
"amount_usd": 50.00,
"currency": "ETH",
"user_id": "user-123",
"new_balance": 97.32
},
"signature": "sha256_signature_here"
}Payment Best Practices
1. Choose Appropriate Cryptocurrency
Bitcoin (BTC)
- ✅ Most secure (highest confirmations)
- ✅ Widely available
- ❌ Slower confirmation (30+ minutes)
- ❌ Higher network fees during congestion
Ethereum (ETH)
- ✅ Good balance of speed and security
- ✅ Moderate confirmation time (3 minutes)
- ❌ Network fees can be high during congestion
Solana (SOL)
- ✅ Fastest confirmation (30 seconds)
- ✅ Low network fees
- ❌ Fewer confirmations (less secure for large amounts)
Recommendation:
- Small amounts (50): Use SOL for speed
- Medium amounts (500): Use ETH for balance
- Large amounts ($500+): Use BTC for security
2. Payment Amount Strategy
# Good: Add credits in bulk to reduce transaction fees
curl -X POST https://api.polysystems.ai/api/payments/payments \
-H "Authorization: Bearer $JWT_TOKEN" \
-d '{"amount_usd": 100.00, "currency": "ETH"}'
# Avoid: Many small payments (higher cumulative fees)
# Multiple $10 payments instead of one $100 payment3. Monitor Payment Status
#!/bin/bash
# payment_monitor.sh
PAYMENT_ID=$1
JWT_TOKEN=$PS_JWT_TOKEN
while true; do
STATUS=$(curl -s -X GET \
"https://api.polysystems.ai/api/payments/payments/$PAYMENT_ID" \
-H "Authorization: Bearer $JWT_TOKEN" \
| jq -r '.status')
echo "Payment status: $STATUS"
if [ "$STATUS" = "confirmed" ]; then
echo "Payment confirmed! Credits added."
break
elif [ "$STATUS" = "failed" ] || [ "$STATUS" = "expired" ]; then
echo "Payment $STATUS. Please create a new payment."
break
fi
sleep 30
done4. Set Balance Alerts
Monitor your balance and set up alerts:
import os
import requests
def check_balance_alert(threshold=10.0):
"""Alert if balance falls below threshold"""
response = requests.get(
'https://api.polysystems.ai/api/payments/credits/balance',
headers={'Authorization': f'Bearer {os.getenv("PS_JWT_TOKEN")}'}
)
balance = response.json()['balance']
if balance < threshold:
# Send alert (email, SMS, Slack, etc.)
print(f"⚠️ LOW BALANCE ALERT: ${balance}")
print(f"Please add credits to avoid service interruption.")
return True
return False
# Run periodically
if __name__ == '__main__':
check_balance_alert(threshold=10.0)5. Pre-fund for Production
For production applications:
# Calculate estimated monthly usage
monthly_requests = 100000 # 100k requests/month
avg_cost_per_request = 0.0020 # $0.002 per request
monthly_cost = monthly_requests * avg_cost_per_request # $200
# Add 20% buffer
recommended_balance = monthly_cost * 1.2 # $240
print(f"Recommended initial balance: ${recommended_balance}")Troubleshooting
Payment Not Appearing
Problem: Sent cryptocurrency but payment status still “pending”
Solutions:
- Verify you sent the exact amount to the exact address
- Check blockchain explorer for transaction confirmation
- Wait for required confirmations (varies by currency)
- Ensure transaction has sufficient network fee
- Check payment hasn’t expired
Payment Expired
Problem: Payment shows “expired” status
Solution:
# Create a new payment
curl -X POST https://api.polysystems.ai/api/payments/payments \
-H "Authorization: Bearer $JWT_TOKEN" \
-d '{"amount_usd": 50.00, "currency": "ETH"}'
# Send crypto to new address before expirationWrong Amount Sent
Problem: Sent incorrect cryptocurrency amount
Solutions:
- If you sent more: Credits will be added based on actual amount received
- If you sent less: Payment may fail or be credited with received amount
- Contact support for manual resolution if needed
Confirmation Taking Too Long
Problem: Payment stuck in “confirming” for extended period
Possible Causes:
- Network congestion (especially Bitcoin/Ethereum)
- Low transaction fee (transaction delayed)
- Blockchain issues
Solutions:
- Check blockchain explorer for confirmation status
- For Bitcoin: Consider using Replace-By-Fee (RBF) to increase fee
- For Ethereum: Consider increasing gas price
- Wait for next block (may take longer during congestion)
- Contact support if stuck for more than 2x expected time
Advanced Payment Features
Programmatic Payment Workflow
import os
import time
import requests
class PaymentManager:
def __init__(self, jwt_token):
self.jwt_token = jwt_token
self.base_url = "https://api.polysystems.ai"
self.headers = {
"Authorization": f"Bearer {jwt_token}",
"Content-Type": "application/json"
}
def create_payment(self, amount_usd, currency="ETH"):
"""Create a new payment"""
response = requests.post(
f"{self.base_url}/api/payments/payments",
headers=self.headers,
json={
"amount_usd": amount_usd,
"currency": currency
}
)
return response.json()
def check_payment_status(self, payment_id):
"""Check payment status"""
response = requests.get(
f"{self.base_url}/api/payments/payments/{payment_id}",
headers=self.headers
)
return response.json()
def wait_for_confirmation(self, payment_id, timeout=3600, check_interval=30):
"""Wait for payment confirmation with timeout"""
start_time = time.time()
while time.time() - start_time < timeout:
payment = self.check_payment_status(payment_id)
status = payment['status']
print(f"Status: {status}, Confirmations: {payment['confirmations']}/{payment['required_confirmations']}")
if status == 'confirmed':
return True
elif status in ['failed', 'expired']:
return False
time.sleep(check_interval)
print("Timeout waiting for confirmation")
return False
def get_balance(self):
"""Get current balance"""
response = requests.get(
f"{self.base_url}/api/payments/credits/balance",
headers=self.headers
)
return response.json()['balance']
# Usage
manager = PaymentManager(os.getenv('PS_JWT_TOKEN'))
# Check balance
balance = manager.get_balance()
print(f"Current balance: ${balance}")
# If low, create payment
if balance < 10.0:
payment = manager.create_payment(50.0, "ETH")
print(f"Payment created: {payment['id']}")
print(f"Send {payment['amount_crypto']} ETH to {payment['to_address']}")
# Wait for confirmation
if manager.wait_for_confirmation(payment['id']):
new_balance = manager.get_balance()
print(f"Payment confirmed! New balance: ${new_balance}")Summary
In this chapter, you learned:
- ✅ How the prepaid credit system works
- ✅ How to check your account balance
- ✅ How to create and manage x402 payments
- ✅ Supported cryptocurrencies and their characteristics
- ✅ Payment status lifecycle and monitoring
- ✅ Transaction history and statistics
- ✅ Best practices for payment management
- ✅ Troubleshooting common payment issues
- ✅ Programmatic payment automation
Next Steps
- Chapter 6: Spending Limits - Control costs with spending limits
- Chapter 7: API Pricing - Understand pricing structure
- Chapter 8: Webhooks - Set up payment notifications