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:
- Hosted Payment Page Flow - Customer selects their preferred network on a secure hosted page
- 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:
X-API-Key: YOUR_API_KEYAlternative Method:
Authorization: Bearer YOUR_API_KEYAPI Key Types:
- Test Key (
test_sk_...) - For testing with testnets (testnet funds only) - Production Key (
live_sk_...orprod_sk_...) - For mainnet transactions with real funds
Payment Flow 1: Hosted Payment Page (Recommended)
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:
{
"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:
{
"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:
- Select their preferred blockchain network (BSC, Ethereum, Polygon, Tron, Solana)
- Select cryptocurrency (USDT or USDC)
- See the deposit address and QR code
- Complete the payment
- 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:
{
"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:
{
"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 USDUSDC- USD Coin
Response:
{
"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 toqr_code- A base64 encoded QR code imageinstructions- 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:
{
"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:
{
"network": "ETH",
"currency": "USDC"
}Response:
{
"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:
{
"status": "paid",
"paid_at": "2026-01-30T18:10:23Z",
"paid_amount": 100.00
}If payment is not yet detected:
{
"status": "pending",
"paid_at": null,
"paid_amount": 0
}Session Status Values
| Status | Description |
|---|---|
pending | Waiting for payment |
paid | Payment confirmed on blockchain |
failed | Session expired without payment |
success | Alias for paid (legacy) |
Session Expiration
- Default expiry: 15 minutes from creation
- Automatic cleanup: Expired sessions are marked as
failedand 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:
{
"error": "only USDT and USDC are supported for crypto payments"
}{
"error": "reference already exists"
}{
"error": "session not found"
}{
"error": "payment already completed"
}HTTP Status Codes:
201- Checkout created successfully200- Request successful400- Bad request (validation error)401- Unauthorized (invalid API key)403- Forbidden (KYC not approved or business account required)404- Session not found500- Server error
Complete Integration Example
Using the Hosted Payment Page
// 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
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
- Always use unique references - Prevents duplicate payments
- Implement webhooks - Don't rely solely on polling
- Set appropriate callback URLs - Use HTTPS endpoints
- Handle session expiration - Show clear error messages to customers
- Test with testnets first - Use test API keys before going live
- Store session IDs - For payment tracking and support
- Display network warnings - Prevent customers from sending on wrong network
Support
For technical support or questions:
- Email: hi@rach.finance
- Documentation: https://payments.rach.finance/docs
- Dashboard: https://payments.rach.finance/dashboard
