Gateway API

Gateway API reference

The Gateway service is the reseller integration layer for top-ups, bill payments, refunds, and order lookups. All business endpoints use POST with JSON bodies that include client credentials.

Base URL: http://localhost:3105/api/v1 Open Swagger UI

Authentication

Every request must include api_key, timestamp, and signature in the JSON body. Credentials are validated on every call; there are no auth headers.

FieldTypeRequiredDescription
api_keystringYesShop API key issued by GamzTopup
timestampintegerYesUnix timestamp in seconds; must be within ±5 minutes of server time
signaturestringYesMD5 hex digest of `secret_key + timestamp` (no separator)
IP whitelist required. The caller IP must be registered in the shop's whitelist. An empty whitelist blocks all requests until IPs are configured in the reseller console.
const crypto = require('crypto');

const SECRET_KEY = process.env.GAMZ_SECRET_KEY;
const timestamp = Math.floor(Date.now() / 1000);
const signature = crypto
  .createHash('md5')
  .update(SECRET_KEY + timestamp)
  .digest('hex');

const body = {
  api_key: process.env.GAMZ_API_KEY,
  timestamp,
  signature,
  // ...endpoint-specific fields
};

const res = await fetch('{{BASE_URL}}/balance', {
  method: 'POST',
  headers: { 'content-type': 'application/json' },
  body: JSON.stringify(body),
});
const json = await res.json();

Response format

Successful responses are wrapped in a uniform envelope. HTTP status codes reflect errors (401, 403, 404, 400, etc.) with the same JSON shape.

Success
{
  "status": "success",
  "message": "success",
  "data": { ... }
}
Error
{
  "status": "error",
  "data": null,
  "message": "Invalid credentials"
}

balance

POST{{BASE_URL}}/balance

Get wallet balance

Returns the authenticated shop wallet balance (available and held funds).

Request body

Send as application/json via POST to the endpoint above.

FieldTypeRequiredDescription
api_keystringYesShop API key issued by GamzTopup
timestampintegerYesUnix timestamp in seconds; must be within ±5 minutes of server time
signaturestringYesMD5 hex digest of `secret_key + timestamp` (no separator)
Example request
{
  "api_key": "ak_24276e47fb892460",
  "timestamp": 1783321239,
  "signature": "f7f4b12685a2a2b6bd18103fa4a24d27"
}

Response

FieldTypeRequiredDescription
shopstringNoShop code
currencystringNoWallet currency (e.g. THB)
availablenumberNoSpendable balance
heldnumberNoFunds reserved for in-flight orders
Example response
{
  "status": "success",
  "message": "success",
  "data": {
    "shop": "demo",
    "currency": "THB",
    "available": 50000,
    "held": 150
  }
}
POST{{BASE_URL}}/service

List provider services

Paginated catalog of enabled provider services (games, billers, top-up products).

Request body

Send as application/json via POST to the endpoint above.

FieldTypeRequiredDescription
api_keystringYesShop API key issued by GamzTopup
timestampintegerYesUnix timestamp in seconds; must be within ±5 minutes of server time
signaturestringYesMD5 hex digest of `secret_key + timestamp` (no separator)
pageintegerNoPage number (default 1, minimum 1)
limitintegerNoItems per page (default 20, max 100)
categoryenumNoFilter by category: MTOPUP | CASHCARD | GTOPUP | BILLPAY
company_idstringNoFilter by company id, e.g. MLBB
Example request
{
  "api_key": "ak_24276e47fb892460",
  "timestamp": 1783321239,
  "signature": "f7f4b12685a2a2b6bd18103fa4a24d27",
  "category": "GTOPUP",
  "page": 1,
  "limit": 20
}

Response

FieldTypeRequiredDescription
itemsarrayNoList of provider services
items[].categoryenumNoMTOPUP | CASHCARD | GTOPUP | BILLPAY
items[].company_idstringNoProvider company / product code
items[].company_namestringNoDisplay name
items[].feenumberNoService fee
items[].minimum_amountnumber | nullNoMinimum top-up amount
items[].maximum_amountnumber | nullNoMaximum top-up amount
items[].refundableboolean | nullNoWhether refunds are supported
items[].denominationobject | nullNoFixed denominations when applicable
meta.pageintegerNoCurrent page
meta.limitintegerNoPage size
meta.totalintegerNoTotal matching items
meta.total_pagesintegerNoTotal pages
Example response
{
  "status": "success",
  "message": "success",
  "data": {
    "items": [
      {
        "category": "GTOPUP",
        "company_id": "MLBB",
        "company_name": "Mobile Legends",
        "fee": 0,
        "minimum_amount": 10,
        "maximum_amount": 10000,
        "refundable": false,
        "denomination": null
      }
    ],
    "meta": {
      "page": 1,
      "limit": 20,
      "total": 1,
      "total_pages": 1
    }
  }
}

orders

POST{{BASE_URL}}/orders/payment

Place payment / top-up

Charges the shop wallet and submits a top-up or bill payment to the upstream provider.

Request body

Send as application/json via POST to the endpoint above.

FieldTypeRequiredDescription
api_keystringYesShop API key issued by GamzTopup
timestampintegerYesUnix timestamp in seconds; must be within ±5 minutes of server time
signaturestringYesMD5 hex digest of `secret_key + timestamp` (no separator)
providerenumNoUpstream provider (default WEPAY)
typeenumYesPayment type: billpay | mtopup | gtopup | cashcard
pay_to_companystringYesProvider company / product code (e.g. TRMV, MLBB)
pay_to_ref1stringYesPhone number, bill account, or game id
pay_to_amountnumberYesAmount to charge (positive)
pay_to_ref2stringNoReference 2 — required by some billpay services
pay_to_ref3stringNoReference 3 — required by some billpay services
pay_to_barcode1stringNoBarcode number for barcode-based bill payments
dest_refstringYesYour unique order reference (alphanumeric, max 20 chars)
resp_urlstringNoResult callback URL. Required unless the shop has a callback_url configured
Example request
{
  "api_key": "ak_24276e47fb892460",
  "timestamp": 1783321239,
  "signature": "f7f4b12685a2a2b6bd18103fa4a24d27",
  "type": "gtopup",
  "pay_to_company": "MLBB",
  "pay_to_ref1": "1234567890",
  "pay_to_amount": 100,
  "dest_ref": "ORD20260708001"
}

Response

FieldTypeRequiredDescription
statusenumNoSUCCESS | PENDING | FAILED
providerRefstringNoProvider transaction id when available
errorCodestringNoProvider error code on failure
errorMessagestringNoHuman-readable error on failure
rawobjectNoRaw provider response payload
Example response
{
  "status": "success",
  "message": "success",
  "data": {
    "status": "PENDING",
    "providerRef": "987654321",
    "raw": {}
  }
}
POST{{BASE_URL}}/orders/refund

Refund order

Requests a refund from the provider for a previously placed order. Wallet is credited on success.

Request body

Send as application/json via POST to the endpoint above.

FieldTypeRequiredDescription
api_keystringYesShop API key issued by GamzTopup
timestampintegerYesUnix timestamp in seconds; must be within ±5 minutes of server time
signaturestringYesMD5 hex digest of `secret_key + timestamp` (no separator)
providerenumNoUpstream provider (default WEPAY)
typeenumNoOriginal payment type: billpay | mtopup | gtopup | cashcard
transaction_idstringYesProvider transaction id returned when the order was placed
dest_refstringYesOrder reference used when the order was placed (alphanumeric, max 20 chars)
pay_to_companystringYesProvider company code used in the original payment
new_msisdnstringNoNew phone number for services that transfer credit to a new number
resp_urlstringNoResult callback URL. Required unless the shop has a callback_url configured
Example request
{
  "api_key": "ak_24276e47fb892460",
  "timestamp": 1783321239,
  "signature": "f7f4b12685a2a2b6bd18103fa4a24d27",
  "transaction_id": "987654321",
  "dest_ref": "ORD20260708001",
  "pay_to_company": "MLBB"
}

Response

FieldTypeRequiredDescription
statusenumNoSUCCESS | PENDING | FAILED
providerRefstringNoProvider refund reference when available
errorCodestringNoProvider error code on failure
errorMessagestringNoHuman-readable error on failure
rawobjectNoRaw provider response payload
Example response
{
  "status": "success",
  "message": "success",
  "data": {
    "status": "SUCCESS",
    "providerRef": "REF123456",
    "raw": {}
  }
}
POST{{BASE_URL}}/orders/status

Get order status

Looks up a single order by your dest_ref reference.

Request body

Send as application/json via POST to the endpoint above.

FieldTypeRequiredDescription
api_keystringYesShop API key issued by GamzTopup
timestampintegerYesUnix timestamp in seconds; must be within ±5 minutes of server time
signaturestringYesMD5 hex digest of `secret_key + timestamp` (no separator)
dest_refstringYesOrder reference used when the order was placed
Example request
{
  "api_key": "ak_24276e47fb892460",
  "timestamp": 1783321239,
  "signature": "f7f4b12685a2a2b6bd18103fa4a24d27",
  "dest_ref": "ORD20260708001"
}

Response

FieldTypeRequiredDescription
dest_refstringNoYour order reference
typestringNoPayment type (lowercase)
pay_to_companystringNoProvider company code
targetstringNoPhone / account / game id
statusenumNoPENDING | SENT | SUCCESS | FAILED | REFUNDED | CANCELLED
amountnumberNoOrder amount
currencystringNoCurrency code
transaction_idstring | nullNoProvider transaction id
messagestring | nullNoResult message from provider
failure_reasonstring | nullNoFailure reason when status is FAILED
created_atstringNoISO 8601 creation timestamp
completed_atstring | nullNoISO 8601 completion timestamp
Example response
{
  "status": "success",
  "message": "success",
  "data": {
    "dest_ref": "ORD20260708001",
    "type": "gtopup",
    "pay_to_company": "MLBB",
    "target": "1234567890",
    "status": "SUCCESS",
    "amount": 100,
    "currency": "THB",
    "transaction_id": "987654321",
    "message": null,
    "failure_reason": null,
    "created_at": "2026-07-08T02:30:00.000Z",
    "completed_at": "2026-07-08T02:30:05.000Z"
  }
}
POST{{BASE_URL}}/orders/history

Order history

Paginated list of orders for the authenticated shop with optional filters.

Request body

Send as application/json via POST to the endpoint above.

FieldTypeRequiredDescription
api_keystringYesShop API key issued by GamzTopup
timestampintegerYesUnix timestamp in seconds; must be within ±5 minutes of server time
signaturestringYesMD5 hex digest of `secret_key + timestamp` (no separator)
pageintegerNoPage number (default 1, minimum 1)
limitintegerNoItems per page (default 20, max 100)
statusenumNoFilter by status: PENDING | SENT | SUCCESS | FAILED | REFUNDED | CANCELLED
dest_refstringNoFilter by your order reference
date_fromstringNoOrders created at or after (ISO 8601 date)
date_tostringNoOrders created at or before (ISO 8601 date)
Example request
{
  "api_key": "ak_24276e47fb892460",
  "timestamp": 1783321239,
  "signature": "f7f4b12685a2a2b6bd18103fa4a24d27",
  "status": "SUCCESS",
  "page": 1,
  "limit": 20,
  "date_from": "2026-07-01",
  "date_to": "2026-07-31"
}

Response

FieldTypeRequiredDescription
itemsarrayNoOrder records (same shape as order status response)
metaobjectNoPagination metadata (page, limit, total, total_pages)
Example response
{
  "status": "success",
  "message": "success",
  "data": {
    "items": [
      {
        "dest_ref": "ORD20260708001",
        "type": "gtopup",
        "pay_to_company": "MLBB",
        "target": "1234567890",
        "status": "SUCCESS",
        "amount": 100,
        "currency": "THB",
        "transaction_id": "987654321",
        "message": null,
        "failure_reason": null,
        "created_at": "2026-07-08T02:30:00.000Z",
        "completed_at": "2026-07-08T02:30:05.000Z"
      }
    ],
    "meta": {
      "page": 1,
      "limit": 20,
      "total": 1,
      "total_pages": 1
    }
  }
}

webhooks

POST{resp_url}

Order result callback

When the upstream provider confirms an async payment or refund, GamzTopup relays the result to the resp_url you supplied on /orders/payment or /orders/refund (or your shop callback_url when resp_url is omitted). Only final statuses are delivered, best-effort with no retry — poll orders/status if you never receive one.

Callback payload

Posted to your resp_url as application/x-www-form-urlencoded.

FieldTypeRequiredDescription
dest_refstringYesYour order reference, as sent when the payment or refund was placed
transaction_idstringNoProvider transaction id
statusintegerYesResult code — 2 means success, anything else is a failure
smsstringNoHuman-readable result message
operator_trxnsidstringNoUpstream operator transaction id, when available
Example request
dest_ref=ORD20260708001&transaction_id=987654321&status=2&sms=Top-up+successful&operator_trxnsid=OP1234567

Your response

Return HTTP 200 to acknowledge. The response body isn't read.