Skip to content

Crypto Payment Gateway API Documentation

Overview

The Crypto Payment Gateway allows merchants to accept cryptocurrency payments (USDT/USDC) across multiple blockchain networks. The gateway supports two payment flows:

  1. Hosted Payment Page Flow - Customer selects their preferred network on a secure hosted page
  2. Direct Payment Flow - Merchant specifies the network upfront and receives payment details immediately

Authentication

All API requests require authentication using your API Key in the header:

Primary Method:

http
X-API-Key: YOUR_API_KEY

Alternative Method:

http
Authorization: Bearer YOUR_API_KEY

API Key Types:

  • Test Key (test_sk_...) - For testing with testnets (testnet funds only)
  • Production Key (live_sk_... or prod_sk_...) - For mainnet transactions with real funds

This flow provides a secure, hosted payment page where customers can select their preferred blockchain network and cryptocurrency.

Step 1: Create Checkout Session

Endpoint: POST /api/v1/checkout/create

Request:

json
{
  "amount": 100.00,
  "currency": "USD",
  "customer_email": "customer@example.com",
  "customer_name": "John Doe",
  "reference": "ORDER-12345",
  "description": "Product purchase",
  "callback_url": "https://yoursite.com/payment/callback",
  "payment_method": "crypto"
}

Important: Do NOT include network in the request to use the hosted page flow.

Response:

json
{
  "session_id": "11fec830-6b48-4e1e-b504-eef2ad0bbc01",
  "reference": "ORDER-12345",
  "amount": 100.00,
  "currency": "USD",
  "expires_at": "2026-01-30T18:15:00Z",
  "status": "pending",
  "payment_method": "crypto",
  "payment_url": "https://payments-api-dev-966260606560.europe-west2.run.app/pay/11fec830-6b48-4e1e-b504-eef2ad0bbc01",
  "instructions": {
    "instruction": "Please visit the payment URL to select your preferred cryptocurrency."
  }
}

Step 2: Direct Customer to Payment Page

Send the payment_url to your customer via:

  • Direct browser redirect
  • Email link
  • QR code
  • Embedded iframe

The customer will see a professional payment interface where they can:

  1. Select their preferred blockchain network (BSC, Ethereum, Polygon, Tron, Solana)
  2. Select cryptocurrency (USDT or USDC)
  3. See the deposit address and QR code
  4. Complete the payment
  5. Click "I have paid" to trigger instant verification

Step 3: Payment Confirmation

Automatic Monitoring:

  • Background monitoring checks for payments every 30 seconds
  • Customers can click "I have Paid" for instant verification
  • Once confirmed, the session status changes to paid

Webhook Notification: If you provided a callback_url, you'll receive:

json
{
  "event": "payment.confirmed",
  "session_id": "11fec830-6b48-4e1e-b504-eef2ad0bbc01",
  "reference": "ORDER-12345",
  "amount": 100.00,
  "currency": "USDT",
  "status": "paid",
  "network": "BSC",
  "blockchain_tx_hash": "0xabc123...",
  "paid_at": "2026-01-30T18:10:23Z"
}

Payment Flow 2: Direct Payment (Network Pre-Selected)

This flow is ideal when you want to specify the blockchain network upfront and display payment details directly in your own UI.

Step 1: Create Checkout with Network

Endpoint: POST /api/v1/checkout/create

Request:

json
{
  "amount": 100.00,
  "currency": "USDT",
  "customer_email": "customer@example.com",
  "customer_name": "John Doe",
  "reference": "ORDER-12346",
  "description": "Product purchase",
  "callback_url": "https://yoursite.com/payment/callback",
  "payment_method": "crypto",
  "network": "BSC"
}

Important: Including network triggers the direct payment flow.

Supported Networks:

  • BSC - Binance Smart Chain (BEP-20)
  • ETH - Ethereum (ERC-20)
  • POL - Polygon (Polygon)
  • TRX - Tron (TRC-20)
  • SOL - Solana (SPL)

Supported Currencies:

  • USDT - Tether USD
  • USDC - USD Coin

Response:

json
{
  "session_id": "22fec830-7b58-5f2f-c615-fef3be1ccd12",
  "reference": "ORDER-12346",
  "amount": 100.00,
  "currency": "USDT",
  "expires_at": "2026-01-30T18:15:00Z",
  "status": "pending",
  "payment_method": "crypto",
  "network": "BSC",
  "deposit_address": "0x742d35Cc6634C0532925a3b844Bc9e7595f0bEb",
  "qr_code": "data:image/png;base64,iVBORw0KGgoAAAANS...",
  "instructions": {
    "title": "Send USDT to the address below",
    "network_warning": "⚠️ Send only USDT on BSC network",
    "amount_note": "Send exactly 100.00 USDT",
    "expiry_note": "Payment expires at 2026-01-30T18:15:00Z"
  }
}

No payment_url is returned - you display the deposit address and QR code in your own UI.

Step 2: Display Payment Details

Show the customer:

  • deposit_address - The wallet address to send to
  • qr_code - A base64 encoded QR code image
  • instructions - Important warnings and notes
  • Countdown timer based on expires_at

Step 3: Monitor Payment Status

Option A: Polling (Manual Check)

Endpoint: GET /api/v1/checkout/verify/:sessionId

Response:

json
{
  "session_id": "22fec830-7b58-5f2f-c615-fef3be1ccd12",
  "reference": "ORDER-12346",
  "amount": 100.00,
  "currency": "USDT",
  "status": "paid",
  "payment_method": "crypto",
  "paid_at": "2026-01-30T18:10:23Z"
}

Option B: Webhooks (Recommended)

Same webhook format as Flow 1.


Network Selection (For Hosted Page)

If a customer has already started a payment session but wants to change networks, they can select a different network on the hosted page.

Endpoint: POST /api/v1/checkout/:uuid/select-network

This is called automatically by the hosted payment page UI. You don't need to integrate this unless you're building your own custom UI.

Request:

json
{
  "network": "ETH",
  "currency": "USDC"
}

Response:

json
{
  "session_id": "11fec830-6b48-4e1e-b504-eef2ad0bbc01",
  "deposit_address": "0x1234...",
  "qr_code": "data:image/png;base64,...",
  "network": "ETH",
  "currency": "USDC"
}

Manual Payment Verification

Customers can click "I have Paid" to trigger instant blockchain verification instead of waiting for automatic polling.

Endpoint: POST /api/v1/checkout/:uuid/verify-now

No request body required.

Response:

json
{
  "status": "paid",
  "paid_at": "2026-01-30T18:10:23Z",
  "paid_amount": 100.00
}

If payment is not yet detected:

json
{
  "status": "pending",
  "paid_at": null,
  "paid_amount": 0
}

Session Status Values

StatusDescription
pendingWaiting for payment
paidPayment confirmed on blockchain
failedSession expired without payment
successAlias for paid (legacy)

Session Expiration

  • Default expiry: 15 minutes from creation
  • Automatic cleanup: Expired sessions are marked as failed and deposit addresses are released for reuse
  • Customer notification: The hosted page shows a countdown timer

Testnet vs Mainnet

Test Mode (Using Test API Key):

  • Uses blockchain testnets (BSC Testnet, Sepolia, Mumbai, etc.)
  • No real funds required
  • Perfect for integration testing

Production Mode (Using Production API Key):

  • Uses mainnet blockchains
  • Real cryptocurrency transactions
  • 1% platform fee automatically deducted

Platform Fees

  • Crypto Payment Gateway: 1% of transaction amount
  • Minimum fee: Configurable (check dashboard)
  • Fee deduction: Automatic - merchant receives net amount

Example:

  • Customer sends: 100 USDT
  • Platform fee (1%): 1 USDT
  • Merchant receives: 99 USDT

Error Handling

Common Error Responses:

json
{
  "error": "only USDT and USDC are supported for crypto payments"
}
json
{
  "error": "reference already exists"
}
json
{
  "error": "session not found"
}
json
{
  "error": "payment already completed"
}

HTTP Status Codes:

  • 201 - Checkout created successfully
  • 200 - Request successful
  • 400 - Bad request (validation error)
  • 401 - Unauthorized (invalid API key)
  • 403 - Forbidden (KYC not approved or business account required)
  • 404 - Session not found
  • 500 - Server error

Complete Integration Example

Using the Hosted Payment Page

javascript
// Backend: Create checkout session
const response = await fetch('https://payments-api-dev-966260606560.europe-west2.run.app/api/v1/checkout/create', {
  method: 'POST',
  headers: {
    'Authorization': 'Bearer live_sk_your_key_here',
    'Content-Type': 'application/json'
  },
  body: JSON.stringify({
    amount: 150.00,
    currency: 'USD',
    customer_email: 'buyer@example.com',
    customer_name: 'Sarah Johnson',
    reference: `ORDER-${Date.now()}`,
    description: 'Premium Subscription',
    callback_url: 'https://yoursite.com/webhooks/payment',
    payment_method: 'crypto'
  })
});

const checkout = await response.json();

// Frontend: Redirect to payment page
window.location.href = checkout.payment_url;

// OR send via email
sendEmail(checkout.customer_email, {
  subject: 'Complete Your Payment',
  body: `Click here to pay: ${checkout.payment_url}`
});

Webhook Handler

javascript
app.post('/webhooks/payment', (req, res) => {
  const event = req.body;
  
  if (event.event === 'payment.confirmed') {
    // Update your database
    await updateOrder(event.reference, {
      status: 'paid',
      txHash: event.blockchain_tx_hash,
      paidAt: event.paid_at
    });
    
    // Fulfill the order
    await fulfillOrder(event.reference);
  }
  
  res.status(200).send('OK');
});

Best Practices

  1. Always use unique references - Prevents duplicate payments
  2. Implement webhooks - Don't rely solely on polling
  3. Set appropriate callback URLs - Use HTTPS endpoints
  4. Handle session expiration - Show clear error messages to customers
  5. Test with testnets first - Use test API keys before going live
  6. Store session IDs - For payment tracking and support
  7. Display network warnings - Prevent customers from sending on wrong network

Support

For technical support or questions:

Rach Payments API