Developers · API v1

Take payments with
one HTTP request.

A small JSON API over HTTPS. Create a payment, send your customer to the checkout link, and we call your webhook the moment it clears.

Base URL https://pay.gsmxtool.com/api/v1

Getting started

Three things and you are live:

1Add a wallet. In the dashboard, open Payment Gateways and enter the address for TRC-20, BEP-20 or Binance C2C.
2Create an API key. API Keys → Create. It is shown once and starts with gsmxtool_. Keep it on your server.
3Create a payment and redirect your customer to the payment_url you get back.

Using DHRU, WHMCS or Joudisoft? You do not need the API — download the ready module from Modules in your dashboard.

Authentication

Send your key in the X-API-Key header on every request. Authorization: Bearer <key> works too.

X-API-Key: gsmxtool_your_api_key
Content-Type: application/json
Never put the key in browser code or a mobile app. Anyone holding it can create payments in your name.
POST/api/v1/payment

Create a payment

Creates a payment and returns the checkout link to send your customer to.

FieldTypeDescription
amount requireddecimalAmount to charge, e.g. 25.00.
webhook_url requiredurlWhere we POST the result when the payment changes status.
currencystringCurrency code. Defaults to USDT.
gatewaystringtrc20usdt, bep20usdt, binancec2c, banglaqr, bkashpersonal, bkashlive or auto (default) to let the customer choose.
return_urlurlWhere the customer goes after paying.
descriptionstringShown on the checkout, e.g. Order #1042.
customer_namestringPre-fills the checkout.
customer_emailstringPre-fills the checkout.
curl -X POST https://pay.gsmxtool.com/api/v1/payment \
  -H "X-API-Key: gsmxtool_your_api_key" \
  -H "Content-Type: application/json" \
  -d '{
    "amount": "25.00",
    "gateway": "trc20usdt",
    "webhook_url": "https://yourapp.com/webhooks/gsmxtool",
    "return_url": "https://yourapp.com/thanks",
    "description": "Order #1042"
  }'
$ch = curl_init('https://pay.gsmxtool.com/api/v1/payment');
curl_setopt_array($ch, [
    CURLOPT_POST           => true,
    CURLOPT_RETURNTRANSFER => true,
    CURLOPT_HTTPHEADER     => ['X-API-Key: gsmxtool_your_api_key', 'Content-Type: application/json'],
    CURLOPT_POSTFIELDS     => json_encode([
        'amount'      => '25.00',
        'webhook_url' => 'https://yourapp.com/webhooks/gsmxtool',
        'return_url'  => 'https://yourapp.com/thanks',
        'description' => 'Order #1042',
    ]),
]);
$res = json_decode(curl_exec($ch), true);
if ($res['success']) header('Location: ' . $res['payment_url']);
const res = await fetch('https://pay.gsmxtool.com/api/v1/payment', {
  method: 'POST',
  headers: { 'X-API-Key': process.env.GSMX_KEY, 'Content-Type': 'application/json' },
  body: JSON.stringify({ amount: '25.00', webhook_url: 'https://yourapp.com/webhooks/gsmxtool' }),
});
const { payment_url } = await res.json();

Response

{
  "success": true,
  "ref": "GX5C9BB433AC",
  "payment_url": "https://pay.gsmxtool.com/pay/GX5C9BB433AC",
  "amount": "25.00000000",
  "currency": "USDT",
  "status": "initiated",
  "created_at": "2026-10-21 09:52:11"
}
GET/api/v1/payment/{ref}

Payment status

Returns the current state of one payment. Call this from your server before delivering anything — never trust a redirect alone.

curl https://pay.gsmxtool.com/api/v1/payment/GX5C9BB433AC -H "X-API-Key: gsmxtool_your_api_key"

Response

{
  "success": true,
  "ref": "GX5C9BB433AC",
  "amount": "25.00000000",
  "currency": "USDT",
  "gateway": "trc20usdt",
  "gateway_trx_id": "9f2c…e81a",
  "status": "completed",
  "webhook_status": "success",
  "payment_url": "https://pay.gsmxtool.com/pay/GX5C9BB433AC",
  "created_at": "2026-10-21 09:52:11",
  "updated_at": "2026-10-21 09:52:39"
}
GET/api/v1/payments

List payments

Your payments, newest first.

QueryTypeDescription
statusstringFilter: initiated, pending, completed, failed, canceled.
pageintPage number, from 1.
per_pageintRows per page, 1–100. Default 20.
curl "https://pay.gsmxtool.com/api/v1/payments?status=completed&per_page=50" -H "X-API-Key: gsmxtool_your_api_key"

The response has data (the rows) and pagination (total, page, per_page, last_page).

POST/api/v1/payment/{ref}/cancel

Cancel a payment

Cancels a payment that has not completed yet. A completed, failed or already canceled payment cannot be canceled.

curl -X POST https://pay.gsmxtool.com/api/v1/payment/GX5C9BB433AC/cancel -H "X-API-Key: gsmxtool_your_api_key"

{ "success": true, "ref": "GX5C9BB433AC", "status": "canceled" }

Webhooks

When a payment changes status we send a POST with a JSON body to the webhook_url you gave. Answer with any 2xx code.

{
  "ref": "GX5C9BB433AC",
  "status": "completed",
  "amount": "25.00000000",
  "currency": "USDT",
  "gateway": "trc20usdt",
  "gateway_trx": "9f2c…e81a",
  "created_at": "2026-10-21 09:52:11"
}
Always verify. The webhook is not signed. Before you deliver, call Payment status with the ref and check that status is completed and the amount is what you expected.
// webhook.php — the safe pattern
$in  = json_decode(file_get_contents('php://input'), true);
$ch  = curl_init('https://pay.gsmxtool.com/api/v1/payment/' . urlencode($in['ref']));
curl_setopt_array($ch, [CURLOPT_RETURNTRANSFER => true, CURLOPT_HTTPHEADER => ['X-API-Key: ' . getenv('GSMX_KEY')]]);
$trx = json_decode(curl_exec($ch), true);
if (($trx['status'] ?? '') === 'completed') {
    // mark your order paid — once
}
http_response_code(200);

Laravel example

Put the key in .env and use the Http facade.

# .env
GSMX_KEY=gsmxtool_your_api_key
GSMX_URL=https://pay.gsmxtool.com
use Illuminate\Support\Facades\Http;

public function checkout(Order $order)
{
    $res = Http::withHeaders(['X-API-Key' => env('GSMX_KEY')])
        ->post(env('GSMX_URL') . '/api/v1/payment', [
            'amount'      => $order->total,
            'webhook_url' => route('payments.webhook'),
            'return_url'  => route('orders.show', $order),
            'description' => "Order #{$order->id}",
        ]);

    return $res->json('success')
        ? redirect($res->json('payment_url'))
        : back()->withErrors($res->json('message'));
}

Errors & statuses

Every error has "success": false and a human-readable message, with a matching HTTP code — most often 400 (bad input), 401 (missing or wrong key), 404 (unknown ref) and 422 (gateway not available on your plan).

StatusMeaning
initiatedCreated; the customer has not paid yet.
pendingPayment submitted and waiting for confirmation or your review.
completedConfirmed. Safe to deliver after a status check.
failedVerification failed. Do not deliver.
canceledCanceled by you through the API or dashboard.