Skip to content

Crypto Gateway Integration Guide

Complete guide to integrating the Rach Crypto Payment Gateway into your application.

Overview

This guide will walk you through integrating crypto payments into your application step-by-step, with code examples in multiple programming languages.

Prerequisites

  • Rach Payments account with approved KYC
  • API key (test or production)
  • Basic understanding of REST APIs
  • (Optional) Webhook endpoint for real-time notifications

Integration Flow


Step 1: Create Checkout Session

When a customer wants to pay with cryptocurrency, create a checkout session:

javascript
// JavaScript / Node.js
const axios = require('axios');

async function createCryptoCheckout(orderData) {
  try {
    const response = await axios.post(
      'https://payments-api-dev-966260606560.europe-west2.run.app/api/v1/checkout/crypto',
      {
        amount: orderData.totalAmount,
        currency: 'USDT',
        network: 'BSC',
        customer_email: orderData.customerEmail,
        reference: orderData.orderId,
        callback_url: 'https://yoursite.com/webhooks/payment'
      },
      {
        headers: {
          'X-API-Key': process.env.RACH_API_KEY,
          'Content-Type': 'application/json'
        }
      }
    );
    
    return response.data;
  } catch (error) {
    console.error('Checkout creation failed:', error.response?.data);
    throw error;
  }
}

// Usage
const checkout = await createCryptoCheckout({
  totalAmount: 99.99,
  customerEmail: 'customer@example.com',
  orderId: 'ORDER-12345'
});

console.log('Deposit Address:', checkout.deposit_address);
console.log('QR Code:', checkout.qr_code);
python
# Python
import requests
import os

def create_crypto_checkout(order_data):
    """Create a crypto checkout session"""
    url = 'https://payments-api-dev-966260606560.europe-west2.run.app/api/v1/checkout/crypto'
    
    payload = {
        'amount': order_data['total_amount'],
        'currency': 'USDT',
        'network': 'BSC',
        'customer_email': order_data['customer_email'],
        'reference': order_data['order_id'],
        'callback_url': 'https://yoursite.com/webhooks/payment'
    }
    
    headers = {
        'X-API-Key': os.getenv('RACH_API_KEY'),
        'Content-Type': 'application/json'
    }
    
    try:
        response = requests.post(url, json=payload, headers=headers)
        response.raise_for_status()
        return response.json()
    except requests.exceptions.RequestException as e:
        print(f'Checkout creation failed: {e}')
        raise

# Usage
checkout = create_crypto_checkout({
    'total_amount': 99.99,
    'customer_email': 'customer@example.com',
    'order_id': 'ORDER-12345'
})

print(f"Deposit Address: {checkout['deposit_address']}")
print(f"QR Code: {checkout['qr_code']}")
go
// Go
package main

import (
    "bytes"
    "encoding/json"
    "fmt"
    "net/http"
    "os"
)

type CheckoutRequest struct {
    Amount       float64 `json:"amount"`
    Currency     string  `json:"currency"`
    Network      string  `json:"network"`
    CustomerEmail string `json:"customer_email"`
    Reference    string  `json:"reference"`
    CallbackURL  string  `json:"callback_url"`
}

type CheckoutResponse struct {
    CheckoutID     string  `json:"checkout_id"`
    DepositAddress string  `json:"deposit_address"`
    Amount         string  `json:"amount"`
    Currency       string  `json:"currency"`
    Network        string  `json:"network"`
    QRCode         string  `json:"qr_code"`
    Status         string  `json:"status"`
    ExpiresAt      string  `json:"expires_at"`
}

func createCryptoCheckout(orderID string, amount float64, email string) (*CheckoutResponse, error) {
    apiKey := os.Getenv("RACH_API_KEY")
    
    payload := CheckoutRequest{
        Amount:        amount,
        Currency:      "USDT",
        Network:       "BSC",
        CustomerEmail: email,
        Reference:     orderID,
        CallbackURL:   "https://yoursite.com/webhooks/payment",
    }
    
    body, _ := json.Marshal(payload)
    
    req, _ := http.NewRequest(
        "POST",
        "https://payments-api-dev-966260606560.europe-west2.run.app/api/v1/checkout/crypto",
        bytes.NewBuffer(body),
    )
    
    req.Header.Set("X-API-Key", apiKey)
    req.Header.Set("Content-Type", "application/json")
    
    client := &http.Client{}
    resp, err := client.Do(req)
    if err != nil {
        return nil, err
    }
    defer resp.Body.Close()
    
    var checkout CheckoutResponse
    json.NewDecoder(resp.Body).Decode(&checkout)
    
    return &checkout, nil
}

func main() {
    checkout, err := createCryptoCheckout("ORDER-12345", 99.99, "customer@example.com")
    if err != nil {
        fmt.Println("Error:", err)
        return
    }
    
    fmt.Println("Deposit Address:", checkout.DepositAddress)
    fmt.Println("QR Code:", checkout.QRCode)
}
php
// PHP
<?php

function createCryptoCheckout($orderData) {
    $apiKey = getenv('RACH_API_KEY');
    
    $payload = [
        'amount' => $orderData['total_amount'],
        'currency' => 'USDT',
        'network' => 'BSC',
        'customer_email' => $orderData['customer_email'],
        'reference' => $orderData['order_id'],
        'callback_url' => 'https://yoursite.com/webhooks/payment'
    ];
    
    $ch = curl_init('https://payments-api-dev-966260606560.europe-west2.run.app/api/v1/checkout/crypto');
    
    curl_setopt($ch, CURLOPT_POST, 1);
    curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode($payload));
    curl_setopt($ch, CURLOPT_HTTPHEADER, [
        'X-API-Key: ' . $apiKey,
        'Content-Type: application/json'
    ]);
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
    
    $response = curl_exec($ch);
    $httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
    curl_close($ch);
    
    if ($httpCode !== 200) {
        throw new Exception('Checkout creation failed');
    }
    
    return json_decode($response, true);
}

// Usage
$checkout = createCryptoCheckout([
    'total_amount' => 99.99,
    'customer_email' => 'customer@example.com',
    'order_id' => 'ORDER-12345'
]);

echo "Deposit Address: " . $checkout['deposit_address'] . "\n";
echo "QR Code: " . $checkout['qr_code'] . "\n";
?>
ruby
# Ruby
require 'net/http'
require 'json'

def create_crypto_checkout(order_data)
  api_key = ENV['RACH_API_KEY']
  uri = URI('https://payments-api-dev-966260606560.europe-west2.run.app/api/v1/checkout/crypto')
  
  payload = {
    amount: order_data[:total_amount],
    currency: 'USDT',
    network: 'BSC',
    customer_email: order_data[:customer_email],
    reference: order_data[:order_id],
    callback_url: 'https://yoursite.com/webhooks/payment'
  }
  
  request = Net::HTTP::Post.new(uri)
  request['X-API-Key'] = api_key
  request['Content-Type'] = 'application/json'
  request.body = payload.to_json
  
  response = Net::HTTP.start(uri.hostname, uri.port, use_ssl: true) do |http|
    http.request(request)
  end
  
  JSON.parse(response.body)
rescue => e
  puts "Checkout creation failed: #{e.message}"
  raise
end

# Usage
checkout = create_crypto_checkout(
  total_amount: 99.99,
  customer_email: 'customer@example.com',
  order_id: 'ORDER-12345'
)

puts "Deposit Address: #{checkout['deposit_address']}"
puts "QR Code: #{checkout['qr_code']}"
java
// Java (Spring Boot)
import org.springframework.http.*;
import org.springframework.web.client.RestTemplate;
import java.util.HashMap;
import java.util.Map;

public class RachPaymentService {
    
    private final String apiKey = System.getenv("RACH_API_KEY");
    private final RestTemplate restTemplate = new RestTemplate();
    
    public Map<String, Object> createCryptoCheckout(OrderData orderData) {
        String url = "https://payments-api-dev-966260606560.europe-west2.run.app/api/v1/checkout/crypto";
        
        Map<String, Object> payload = new HashMap<>();
        payload.put("amount", orderData.getTotalAmount());
        payload.put("currency", "USDT");
        payload.put("network", "BSC");
        payload.put("customer_email", orderData.getCustomerEmail());
        payload.put("reference", orderData.getOrderId());
        payload.put("callback_url", "https://yoursite.com/webhooks/payment");
        
        HttpHeaders headers = new HttpHeaders();
        headers.set("X-API-Key", apiKey);
        headers.setContentType(MediaType.APPLICATION_JSON);
        
        HttpEntity<Map<String, Object>> request = new HttpEntity<>(payload, headers);
        
        ResponseEntity<Map> response = restTemplate.postForEntity(url, request, Map.class);
        
        return response.getBody();
    }
}

// Usage
OrderData order = new OrderData("ORDER-12345", 99.99, "customer@example.com");
Map<String, Object> checkout = paymentService.createCryptoCheckout(order);

System.out.println("Deposit Address: " + checkout.get("deposit_address"));
System.out.println("QR Code: " + checkout.get("qr_code"));
csharp
// C# (.NET)
using System;
using System.Net.Http;
using System.Text;
using System.Text.Json;
using System.Threading.Tasks;

public class RachPaymentService
{
    private readonly HttpClient _httpClient;
    private readonly string _apiKey;
    
    public RachPaymentService()
    {
        _httpClient = new HttpClient();
        _apiKey = Environment.GetEnvironmentVariable("RACH_API_KEY");
    }
    
    public async Task<CheckoutResponse> CreateCryptoCheckout(OrderData orderData)
    {
        var payload = new
        {
            amount = orderData.TotalAmount,
            currency = "USDT",
            network = "BSC",
            customer_email = orderData.CustomerEmail,
            reference = orderData.OrderId,
            callback_url = "https://yoursite.com/webhooks/payment"
        };
        
        var json = JsonSerializer.Serialize(payload);
        var content = new StringContent(json, Encoding.UTF8, "application/json");
        
        var request = new HttpRequestMessage(HttpMethod.Post,
            "https://payments-api-dev-966260606560.europe-west2.run.app/api/v1/checkout/crypto");
        request.Headers.Add("X-API-Key", _apiKey);
        request.Content = content;
        
        var response = await _httpClient.SendAsync(request);
        response.EnsureSuccessStatusCode();
        
        var responseJson = await response.Content.ReadAsStringAsync();
        return JsonSerializer.Deserialize<CheckoutResponse>(responseJson);
    }
}

// Usage
var service = new RachPaymentService();
var checkout = await service.CreateCryptoCheckout(new OrderData
{
    OrderId = "ORDER-12345",
    TotalAmount = 99.99m,
    CustomerEmail = "customer@example.com"
});

Console.WriteLine($"Deposit Address: {checkout.DepositAddress}");
Console.WriteLine($"QR Code: {checkout.QRCode}");

**Response:**
```json
{
  "checkout_id": "checkout_xyz789",
  "deposit_address": "0x742d35Cc6634C0532925a3b844Bc9e7595f0bEb",
  "amount": "99.99",
  "currency": "USDT",
  "network": "BSC",
  "qr_code": "data:image/png;base64,iVBORw0KGgo...",
  "status": "pending",
  "expires_at": "2025-12-22T05:00:00Z",
  "created_at": "2025-12-22T04:30:00Z"
}
```

---

## Step 2: Display Payment Info to Customer

Show the customer:
1. **Deposit Address** - Where to send the payment
2. **Amount** - Exact amount to send
3. **Network** - CRITICAL: Which blockchain to use
4. **QR Code** - For easy mobile wallet scanning

**Example UI:**

```html
<div class="payment-card">
  <h2>Complete Your Payment</h2>
  
  <div class="amount">
    <strong>{{checkout.amount}} {{checkout.currency}}</strong>
    <span>on {{checkout.network}}</span>
  </div>
  
  <div class="qr-code">
    <img src="{{checkout.qr_code}}" alt="Payment QR Code" />
  </div>
  
  <div class="address">
    <label>Deposit Address:</label>
    <input type="text" value="{{checkout.deposit_address}}" readonly />
    <button onclick="copyAddress()">Copy</button>
  </div>
  
  <div class="warning">
    ⚠️ Only send {{checkout.currency}} on {{checkout.network}} network!
    Sending on wrong network will result in permanent loss of funds.
  </div>
  
  <div class="timer">
    Expires in: <span id="countdown"></span>
  </div>
</div>
```

---

## Step 3: Monitor Payment Status

Poll the checkout status or wait for webhook notification:

```javascript
async function checkPaymentStatus(checkoutId) {
  const response = await axios.get(
    `https://payments-api-dev-966260606560.europe-west2.run.app/api/v1/checkout/${checkoutId}`,
    {
      headers: {
        'X-API-Key': process.env.RACH_API_KEY
      }
    }
  );
  
  return response.data;
}

// Poll every 10 seconds
const pollInterval = setInterval(async () => {
  const status = await checkPaymentStatus(checkoutId);
  
  if (status.status === 'confirmed') {
    clearInterval(pollInterval);
    console.log('Payment confirmed!');
    // Fulfill order
  } else if (status.status === 'expired') {
    clearInterval(pollInterval);
    console.log('Payment expired');
  }
}, 10000);
```

---

## Step 4: Handle Webhook Notifications

Set up a webhook endpoint to receive real-time payment notifications:

```javascript
const express = require('express');
const crypto = require('crypto');
const app = express();

app.use(express.json());

app.post('/webhooks/payment', (req, res) => {
  const signature = req.headers['x-rach-signature'];
  const webhookSecret = process.env.RACH_WEBHOOK_SECRET;
  
  // Verify signature
  const hmac = crypto.createHmac('sha256', webhookSecret);
  hmac.update(JSON.stringify(req.body));
  const computed = hmac.digest('hex');
  
  if (!crypto.timingSafeEqual(Buffer.from(signature), Buffer.from(computed))) {
    return res.status(401).send('Invalid signature');
  }
  
  const event = req.body;
  
  if (event.event === 'payment.confirmed') {
    // Payment confirmed - fulfill order
    fulfillOrder(event.reference, event.checkout_id);
  }
  
  res.sendStatus(200);
});

function fulfillOrder(orderId, checkoutId) {
  console.log(`Fulfilling order ${orderId} for checkout ${checkoutId}`);
  // Your order fulfillment logic here
}

app.listen(3000);
```

See the [Webhook Documentation](/crypto-gateway/webhooks) for complete details.

---

## Error Handling

```javascript
async function createCheckoutWithErrorHandling(orderData) {
  try {
    const checkout = await createCryptoCheckout(orderData);
    return { success: true, data: checkout };
  } catch (error) {
    if (error.response?.status === 401) {
      return { success: false, error: 'Invalid API key' };
    } else if (error.response?.status === 400) {
      return { success: false, error: 'Invalid request data', details: error.response.data };
    } else if (error.response?.status === 429) {
      return { success: false, error: 'Rate limit exceeded' };
    } else {
      return { success: false, error: 'Unknown error occurred' };
    }
  }
}
```

---

## Best Practices

::: tip Integration Checklist
- ✅ Always verify webhook signatures
- ✅ Store checkout_id with your order
- ✅ Display correct network prominently to customers
- ✅ Implement proper error handling
- ✅ Set up monitoring for failed payments
- ✅ Test in sandbox before production
- ✅ Handle partial payments gracefully
- ✅ Set reasonable checkout expiration times

Next Steps

Built with ❤️ by Rach Finance