RazCrypto Gateway Integration Guide

Seamless USDT Recharge System Integration for Any App or Website

Overview

This comprehensive guide details the integration of the RazCrypto Gateway into any application or website. We'll leverage simple PHP and MySQL code, coupled with a BEP20 blockchain scanner like BscScan, to create a robust USDT recharge system.

Upon completing this guide, your system will be capable of:

  • Generating a static payment address for users.
  • Accurately tracking USDT deposits on the BEP20 network.
  • Auto-crediting user wallet balances upon successful transactions.
  • Sending real-time notifications via callback/webhook to your application.

Phase 1: Recharge System + BEP20 Tracker

This phase covers the foundational setup for your USDT recharge system, including database design, the user-facing recharge form, and the BEP20 blockchain scanner.

Step 1: Database Tables Required

To manage users, pending transactions, and completed transactions, you'll need three primary database tables. Ensure your database is set up to use utf8mb4 encoding for full character support.

CREATE TABLE users (
  id INT PRIMARY KEY AUTO_INCREMENT,
  wallet_balance DOUBLE DEFAULT 0,
  gateway_id VARCHAR(255) UNIQUE,
  ... other fields /* Include any other user-specific fields you need */
);

CREATE TABLE transactions_temp (
  id INT PRIMARY KEY AUTO_INCREMENT,
  user_id INT,
  amount DOUBLE,
  status ENUM('pending','completed') DEFAULT 'pending',
  callback_url TEXT, /* Optional: For specific transaction callbacks */
  created_at DATETIME DEFAULT CURRENT_TIMESTAMP
);

CREATE TABLE transactions (
  id INT PRIMARY KEY AUTO_INCREMENT,
  user_id INT,
  amount DOUBLE,
  tx_hash TEXT,
  status ENUM('success') DEFAULT 'success',
  created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
);

Table Explanations:

  • users: Stores user information, including their current wallet balance and a unique gateway_id for identification.
  • transactions_temp: Holds temporary records for pending recharge requests. This table is crucial for matching incoming blockchain transactions.
  • transactions: Archives all successfully completed USDT deposits, including the blockchain transaction hash for reference.

Step 2: Recharge Form (recharge.php)

This step involves setting up the user interface for initiating a USDT recharge and the backend logic to process the request and provide a payment address.

Frontend (HTML & AJAX JavaScript):

Place this HTML and JavaScript code within your application's recharge page. This simple form allows users to enter the desired USDT amount and submit their request via AJAX.

<!-- Frontend: recharge.html or within your PHP template -->
<div class="form-section">
    <h4>Initiate USDT Recharge</h4>
    <form id="rechargeForm">
        <input type="number" name="amount" placeholder="Enter USDT Amount" step="0.01" min="0.01" required>
        <button type="submit">Get Payment Address</button>
    </form>
    <div id="result">
        <p>Payment details will appear here after submission.</p>
    </div>
</div>

<!-- AJAX JS: -->
<script>
document.getElementById('rechargeForm').onsubmit = function(e){
    e.preventDefault();
    const amount = document.querySelector('[name=amount]').value;
    
    // Basic validation
    if (parseFloat(amount) <= 0) {
        document.getElementById('result').innerText = 'Please enter a valid amount.';
        return;
    }

    fetch('recharge.php', {
        method: 'POST',
        headers: {'Content-Type': 'application/x-www-form-urlencoded'},
        body: 'amount='+encodeURIComponent(amount)
    })
    .then(res => res.json())
    .then(data => {
        if (data.status === 'success') {
            document.getElementById('result').innerHTML = `
                <p><strong>Payment Address:</strong> <code>${data.payment_address}</code></p>
                <p><strong>Amount to Send:</strong> <span class="highlight">${data.amount} USDT</span></p>
                <p><em>Please send the exact amount to the address above.</em></p>
            `;
        } else {
            document.getElementById('result').innerText = Error: ${data.message || 'Something went wrong.'};
        }
    })
    .catch(error => {
        console.error('Error:', error);
        document.getElementById('result').innerText = 'An error occurred while fetching payment address.';
    });
};
</script>

Backend (recharge.php):

This PHP script handles the AJAX request from the frontend. It associates a recharge request with a user and inserts a pending transaction into the transactions_temp table. It then returns the static payment address to the user.

<?php
// recharge.php
require_once '../includes/db.php'; // Ensure this path is correct for your database connection
session_start();

header('Content-Type: application/json'); // Set header for JSON response

// IMPORTANT: In a real application, implement robust session management
// and ensure $gateway_id is securely fetched and validated.
// For testing, you might manually set it as described in the Testing section.
if (!isset($_SESSION['user_id'])) { // Assuming 'user_id' is stored in session after login
    echo json_encode(['status' => 'error', 'message' => 'User not logged in.']);
    exit();
}
$user_id = $_SESSION['user_id']; // This should be the ID from your 'users' table

// Fetch gateway_id from the users table for the current user
$stmt_user = $pdo->prepare("SELECT gateway_id FROM users WHERE id = ?");
$stmt_user->execute([$user_id]);
$user_data = $stmt_user->fetch(PDO::FETCH_ASSOC);

if (!$user_data) {
    echo json_encode(['status' => 'error', 'message' => 'User not found.']);
    exit();
}
$gateway_id = $user_data['gateway_id']; // Use the gateway_id associated with the logged-in user

$amount = floatval($_POST['amount'] ?? 0);

if ($amount <= 0) {
    echo json_encode(['status' => 'error', 'message' => 'Invalid amount.']);
    exit();
}

try {
    // Start a transaction for atomicity
    $pdo->beginTransaction();

    // Remove any existing pending transactions for this user to ensure only one active request
    $pdo->prepare("DELETE FROM transactions_temp WHERE user_id = ? AND status = 'pending'")->execute([$user_id]);

    // Insert the new pending transaction
    // You might also want to include a 'callback_url' if the client provides one per transaction
    $stmt_insert_temp = $pdo->prepare("INSERT INTO transactions_temp (user_id, amount, status) VALUES (?, ?, 'pending')");
    $stmt_insert_temp->execute([$user_id, $amount]);

    // Commit the transaction
    $pdo->commit();

    // This is your static wallet address where users will send USDT
    // IMPORTANT: Replace with your actual BEP20 static wallet address
    $payment_address = '0xYourStaticWalletAddressHere'; 

    echo json_encode([
      'status' => 'success',
      'payment_address' => $payment_address,
      'amount' => $amount,
      'gateway_id' => $gateway_id // Optionally return gateway_id for client info
    ]);

} catch (PDOException $e) {
    $pdo->rollBack(); // Rollback on error
    error_log("Database Error in recharge.php: " . $e->getMessage());
    echo json_encode(['status' => 'error', 'message' => 'Database operation failed.']);
}
?>

Important: Remember to replace '0xYourStaticWalletAddressHere' with your actual BEP20 static USDT receiving address. Also, ensure the path to db.php is correct.

Step 3: BEP20 Cron (bep.php)

This script is the heart of the auto-crediting system. It should be run periodically (e.g., every minute) using a cron job. It fetches the latest USDT transactions from your static wallet using the BscScan API, identifies matching pending transactions, updates user balances, and records completed transactions.

<?php
// bep.php - To be run as a cron job, e.g., every minute
require '../includes/db.php'; // Ensure this path is correct for your database connection

// Your BscScan API Key - Get this from https://bscscan.com/myapikey
$api_key = 'YOUR_BSCSCAN_API_KEY'; 

// Your Static BEP20 Wallet Address where you receive USDT
$wallet = '0xYourStaticWalletAddressHere'; 

// USDT Token Contract Address on BEP20 (Binance Smart Chain)
$contract = '0x55d398326f99059fF775485246999027B3197955'; // Official USDT (BSC-Peg)

// BscScan API URL for token transactions
$url = "https://api.bscscan.com/api?module=account&action=tokentx&contractaddress={$contract}&address={$wallet}&page=1&offset=20&sort=desc&apikey={$api_key}";

// Fetch transaction data from BscScan API
$response_json = @file_get_contents($url); // Use @ to suppress warnings for failed requests
if ($response_json === FALSE) {
    error_log("BEP20 Cron: Failed to fetch BscScan API data for URL: " . $url);
    exit("Failed to fetch BscScan API data.");
}

$response = json_decode($response_json, true);

if (!isset($response['result']) || !is_array($response['result'])) {
    error_log("BEP20 Cron: Invalid BscScan API response. " . ($response['message'] ?? 'No result found.'));
    exit("Invalid BscScan API response.");
}

foreach ($response['result'] as $tx) {
    // Basic validation for transaction data
    if (!isset($tx['hash']) || !isset($tx['value']) || !isset($tx['tokenDecimal']) || !isset($tx['to'])) {
        error_log("BEP20 Cron: Skipping malformed transaction entry: " . json_encode($tx));
        continue;
    }

    $tx_hash = $tx['hash'];
    $received_amount_wei = gmp_init($tx['value']); // Use GMP for large numbers
    $token_decimal = (int)$tx['tokenDecimal'];
    
    // Calculate the actual amount in USDT
    $amount = gmp_div($received_amount_wei, gmp_pow(10, $token_decimal));
    $amount = (double)gmp_strval($amount); // Convert GMP to double for comparison

    // Check if the transaction is incoming to our static wallet
    if (strtolower($tx['to']) !== strtolower($wallet)) {
        continue; // Skip outgoing transactions or transactions not to our wallet
    }

    // Check if this transaction hash has already been processed
    $stmt_check_tx = $pdo->prepare("SELECT COUNT(*) FROM transactions WHERE tx_hash = ?");
    $stmt_check_tx->execute([$tx_hash]);
    if ($stmt_check_tx->fetchColumn() > 0) {
        continue; // Transaction already processed, skip
    }

    // Attempt to match with a pending transaction in transactions_temp
    // We try to match by amount and status. Ordering by created_at helps process older requests first.
    // In a production system, consider adding a unique identifier to transactions_temp
    // that the user sends, making matching more robust than just by amount.
    $stmt_temp = $pdo->prepare("SELECT * FROM transactions_temp WHERE amount = ? AND status = 'pending' ORDER BY created_at ASC LIMIT 1");
    $stmt_temp->execute([$amount]);
    $temp = $stmt_temp->fetch(PDO::FETCH_ASSOC);

    if (!$temp) {
        // No pending transaction found for this exact amount, or already processed
        // Log this if you want to identify unmatched incoming transactions
        // error_log("BEP20 Cron: No pending transaction found for amount {$amount} with hash {$tx_hash}");
        continue;
    }

    $user_id = $temp['user_id'];
    $callback_url = $temp['callback_url'];
    $temp_transaction_id = $temp['id'];

    try {
        $pdo->beginTransaction();

        // 1. Insert into main transactions table
        $stmt_insert_main = $pdo->prepare("INSERT INTO transactions (user_id, amount, tx_hash, status) VALUES (?, ?, ?, 'success')");
        $stmt_insert_main->execute([$user_id, $amount, $tx_hash]);

        // 2. Update user wallet balance
        $stmt_update_user = $pdo->prepare("UPDATE users SET wallet_balance = wallet_balance + ? WHERE id = ?");
        $stmt_update_user->execute([$amount, $user_id]);

        // 3. Mark the temporary transaction as completed
        $stmt_update_temp = $pdo->prepare("UPDATE transactions_temp SET status = 'completed' WHERE id = ?");
        $stmt_update_temp->execute([$temp_transaction_id]);

        $pdo->commit();

        // ✅ Send Webhook if callback_url is set for this transaction
        if (!empty($callback_url)) {
            // Fetch gateway_id for the user to include in webhook payload
            $stmt_gw_id = $pdo->prepare("SELECT gateway_id FROM users WHERE id = ?");
            $stmt_gw_id->execute([$user_id]);
            $user_gateway_data = $stmt_gw_id->fetch(PDO::FETCH_ASSOC);
            $gateway_id_for_webhook = $user_gateway_data['gateway_id'] ?? 'unknown';

            $payload = json_encode([
                'status' => 'success',
                'amount' => $amount,
                'tx_hash' => $tx_hash,
                'gateway_id' => $gateway_id_for_webhook,
                'timestamp' => date("Y-m-d H:i:s"),
                'temp_transaction_id' => $temp_transaction_id // Optionally include temp ID
            ]);

            $ch = curl_init($callback_url);
            curl_setopt($ch, CURLOPT_CUSTOMREQUEST, "POST");
            curl_setopt($ch, CURLOPT_POSTFIELDS, $payload);
            curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
            curl_setopt($ch, CURLOPT_HTTPHEADER, [
                'Content-Type: application/json',
                'Content-Length: ' . strlen($payload)
            ]);
            $response = curl_exec($ch);
            if (curl_errno($ch)) {
                error_log("Webhook failed for {$callback_url}: " . curl_error($ch));
            } else {
                error_log("Webhook sent to {$callback_url}. Response: {$response}");
            }
            curl_close($ch);
        }

    } catch (PDOException $e) {
        $pdo->rollBack();
        error_log("Database Error in bep.php during transaction processing for TX {$tx_hash}: " . $e->getMessage());
    } catch (Exception $e) {
        error_log("General Error in bep.php for TX {$tx_hash}: " . $e->getMessage());
    }
}
?>

Configuration Reminder:

  • Replace 'YOUR_BSCSCAN_API_KEY' with your actual API key from BscScan.
  • Replace '0xYourStaticWalletAddressHere' with the BEP20 wallet address where you expect to receive USDT.
  • The offset parameter in the BscScan API URL controls how many recent transactions are fetched. Adjust based on your expected transaction volume.
  • This script should be set up as a cron job on your server to run automatically (e.g., * * * * * php /path/to/your/bep.php > /dev/null 2>&1).

Callback/Webhook API

The RazCrypto Gateway can notify your application when a successful USDT deposit is detected and processed. Your client application should provide a callback_url when initiating a recharge request (this URL can be stored in the transactions_temp table).

Webhook Example Payload:

Upon a successful transaction, the BEP20 Cron script will send a POST request with a JSON payload to the specified callback_url. Your application should be configured to receive and process this payload.

{
  "status": "success",
  "amount": 10,
  "tx_hash": "0xabc123456789abcdef123456789abcdef123456789abcdef123456789",
  "gateway_id": "fastuser-011",
  "timestamp": "2025-06-25 13:00:00",
  "temp_transaction_id": 12345 // Optional: ID from transactions_temp
}

Payload Fields:

  • status: Always "success" for a successful deposit notification.
  • amount: The amount of USDT credited.
  • tx_hash: The unique blockchain transaction hash.
  • gateway_id: The unique identifier of the user who initiated the recharge, as stored in your users table.
  • timestamp: The time when the transaction was detected and processed by the gateway.
  • temp_transaction_id: (Optional) The ID of the temporary transaction record, useful for internal reconciliation.

Your callback URL should be a secure endpoint (HTTPS) capable of receiving POST requests and processing JSON data.


Testing the Gateway

Follow these steps to thoroughly test your RazCrypto Gateway integration:

  1. Login as a User: Ensure you are logged into your application as a user who has an entry in your users table.
  2. Set $gateway_id (for testing recharge.php): If you're testing recharge.php in isolation, you might temporarily set $_SESSION['user_id'] and verify the gateway_id is being fetched correctly for that user. In a real application, this would come from your authenticated session.
  3. Fill Recharge Form: Go to your recharge page and enter an exact amount (e.g., 5 USDT). Submit the form to get the payment address.
  4. Send Exact Amount: From a separate cryptocurrency wallet, send the exact amount of USDT (e.g., 5 USDT) to the static wallet address provided by recharge.php. Ensure you send it on the BEP20 (Binance Smart Chain) network.
  5. Wait for Cron: Allow up to 1 minute for your bep.php cron job to run and detect the transaction.
  6. Verify Wallet Balance: Check your database; the user's wallet balance in the users table should be updated. Also, verify that an entry exists in the transactions table and the corresponding transactions_temp entry is marked 'completed'.
  7. Check Webhook: If a callback_url was provided, verify that your callback endpoint received the webhook notification with the transaction details.

Frequently Asked Questions (FAQ)

Q. क्या Payment Address change होता है?
A. नहीं — Payment Address Static है। आपका एक ही फिक्स्ड BEP20 USDT वॉलेट एड्रेस होगा जहां सभी यूजर डिपॉजिट करेंगे।
Q. Callback URL कब Trigger होता है?
A. Callback URL तब Trigger होता है जब blockchain पर USDT token receive होता है और BEP Cron उसे पकड़ लेता है (यानी, आपके static वॉलेट में डिपॉजिट होने के बाद bep.php स्क्रिप्ट उसे डिटेक्ट और प्रोसेस कर लेती है)।
Q. Gateway ID क्या है?
A. Gateway ID आपके user की unique पहचान है। BEP Cron स्क्रिप्ट इसी ID का उपयोग करके उस यूजर को ढूंढता है जिसने रिचार्ज रिक्वेस्ट की थी, ताकि सही यूजर के वॉलेट बैलेंस में क्रेडिट किया जा सके। यह यूजर की सेशन में होना चाहिए और users table में मौजूद होना चाहिए।

Done 🎉

Congratulations! You have successfully integrated the RazCrypto Gateway into your PHP-based system. Whether you are building a Wallet App, an MLM Panel, or any Recharge Website, this guide provides the foundation.

We hope this documentation was clear and helpful. If you require an HTML Sample Frontend for further customization, please let us know!

Stay Razor-Sharp 🚀