# 1. Merchant Integration

    # 1.1 Online Service Address

    https://openplatform.gateapi.io
    

    # 1.2 Configure New Applet

    • Log into the merchant backend at https://www.gate.com/zh/merchant#/get-started
    • Fill in basic information to apply for merchant status
    • Go to the application configuration page to configure a new application
    • View the list of configured applications to obtain the application ClientId

    # 1.3 Generate Payment Key

    • Go to the developer page to generate the "Payment API Key," used for signing and verifying the payment interface
    • Go to the developer page to generate the "Authorization Key," used for signing and verifying the authorization interface

    # 1.4 Key Parameters

    • Payment API Key, used for request signing
    • ClientId, used for identity verification, along with the payment API key for signature verification

    # 2. Security Requirements

    # 2.1 Protocol Rules

    # 2.1.1 API Interface Rules

    Field Description
    Transmission Method To ensure transaction security, use HTTPS and TLS1.2 or higher
    Data Format Both request and response data are in JSON format
    Signature Algorithm HMAC-512 algorithm
    Signature Requirement Both request and response data require signature verification; see the Interface Signature section for details
    Validation Logic First check the protocol's status field, then the business response, and finally the transaction status

    # 2.1.2 Response Format

    All interface responses return in JSON format

    Field Name Type Description
    status string API response result, SUCESS for success, FAIL for failure
    code string Response error code
    label string Response error name
    errorMessage string Error description
    data string Business response data in JSON format

    Successful response example:

    {
        "status": "SUCCESS",
        "code": "000000",
        "errorMessage": "",
        "data": {
            "prepayId": "43013197477711872",
            "merchantId": 10002,
            "merchantTradeNo": "13683379532935164644",
            "currency": "USDT",
            "totalFee": "1.6",
            "merchant_name": "MINIAPP PAYMENT TEST",
            "goods_name": "NFT",
            "status": "PENDING",
            "qrcode": "http://openplatform.gate.io/qr/P_6uSR4icI56VUdM2lbYdVihLxR_SsrcNfbdzNzfgp0=",
            "create_time": 1672216745425,
            "expire_time": 1672220345420
        }
    }
    

    Failure response example:

    {
      "status": "FAIL",
      "code": "400002",
      "label": "INVALID_SIGNATURE",
      "errorMessage": "Incorrect signature result",
      "data": {}
    }
    

    # 2.2 API Protocol Header Specification

    To ensure that requests received by the GatePay API come from authorized third-party platforms, GatePay API will check the required fields in the HTTP request headers for signature validation.

    # 2.2.1 New Version Protocol Header

    In the new protocol header, the signature is calculated using the key generated in the merchant backend.

    Header Field To ensure transaction security, HTTPS transmission is used
    X-GatePay-Certificate-ClientId clientId assigned to the merchant when registering the application in the Gate merchant backend
    X-GatePay-Timestamp UTC timestamp in millisecondswhen the request is generated. Note: GatePay will not process requests if the difference between the received request time and this timestamp exceeds 10 seconds.
    X-GatePay-Nonce Random string that conforms to HTTP Header specifications, recommended length within 32 characters, composed of numbers and letters
    X-GatePay-Signature Request signature. GatePay uses this signature to verify the legitimacy of the request.

    # 2.3 Interface Signature

    # 2.3.1 Signature Specification

    Constructing the signature string:

    We expect the technical developers of merchants to construct the signature string according to the rules specified in this document. GatePay will use the same method to construct the signature string. If the merchant constructs the signature string incorrectly, the signature verification will fail. Below is the specific format of the signature string.

    Each line is a parameter, ending with \n (newline character, ASCII code 0x0A). If the parameter itself ends with \n, an additional \n is required.

    request timestamp\nrequest random string\nrequest body\n

    # 2.3.2 Signature Algorithm

    Signature algorithm examples are shown on the right.

    Golang

    import 
    (
    "crypto/hmac"
    "crypto/sha512"
    "encoding/hex"
    "fmt"
    )
    // GenerateSignature generates the request signature
    // timestamp: UTC timestamp as string, precision is milliseconds
    // nonce: random string
    // body: request body
    // secretKey: api_secret provided by Gate
    // return: string signature
    func GenerateSignature(timestamp string, nonce string, body string, secretKey string) string {
      payload := fmt.Sprintf("%s\n%s\n%s\n", timestamp, nonce, body)
      mac := hmac.New(sha512.New, []byte(secretKey))
      mac.Write([]byte(payload))
      signature := mac.Sum(nil)
      return hex.EncodeToString(signature)
    }
    

    Java

    import javax.crypto.Mac;
      import javax.crypto.spec.SecretKeySpec;
      import java.security.InvalidKeyException;
      import java.security.NoSuchAlgorithmException;
      import java.util.Formatter;
      
      public class Main {
      
          private static final String HMAC_SHA512 = "HmacSHA512";
      
          private static String toHexString(byte[] bytes) {
              Formatter formatter = new Formatter();
              for (byte b : bytes) {
                  formatter.format("%02x", b);
              }
              return formatter.toString();
          }
      
          public static String calculateHMAC(String data, String key)
                  throws  InvalidKeyException, NoSuchAlgorithmException {
              SecretKeySpec secretKeySpec = new SecretKeySpec(key.getBytes(), HMAC_SHA512);
              Mac mac = Mac.getInstance(HMAC_SHA512);
              mac.init(secretKeySpec);
              return toHexString(mac.doFinal(data.getBytes()));
          }
      
          public static void main(String[] args) throws Exception {
              String timeStamp = "1673613945439";
              String nonce = "3133420233";
              String body = "{\"code\":\"ac8B7Pl7C-XgfH6zxtd3SidYt7XIfWKU\",\"grant_type\":\"authorization_code\",\"redirect_uri\":\"https://gate.bytetopup.com\",\"client_id\":\"2Ugf9YGMCFRk85Yy\"}";
              String data = String.format("%s\n%s\n%s\n", timeStamp, nonce, body);
              String key = "zgsN5DntmQ2NCQiyJ4kJLyyEO25ewdDHydOSFIHdGrM=";
              String hmac = calculateHMAC(data, key);
              System.out.println(hmac);
          }
      }
    

    Python

    import hashlib
      import hmac
      def generate_signature(timestamp: string, nonce: string, body string, secret: string) -> string:
          '''
          Generate the request signature
          :param timestamp: UTC timestamp as string, precision is milliseconds
          :param nonce: random string
          :param body: request body
          :param secret: api_secret provided by GatePay
          :return: string signature
          '''
          payload = '%s\n%s\n%s\n' % (timestamp, nonce, body)
          signed = hmac.new(secret.encode(), payload.encode(), hashlib.sha512)
          return signed.digest().hex()
    

    PHP

    <?php
    
    function generateSignature($timestamp, $nonce, $body, $secretKey) {
        $payload = "$timestamp\n$nonce\n$body\n";
        $signature = hash_hmac('sha512', $payload, $secretKey, true);
        return bin2hex($signature);
    }
    
    $timestamp = "1631257823000";
    $nonce = "abcd1234";
    $body = 'the post request body content';
    $secretKey = "your_secret_key";
    
    $signature = generateSignature($timestamp, $nonce, $body, $secretKey);
    echo "Signature: " . $signature;
    

    # 3. Withdrawal API List

    # 3.1 Place Withdrawal Order

    • Data Type: JSON (content-type:application/json)

    • Request Method: POST

    • Path: /v1/pay/withdraw

    • erification Method: Signature verification

    • Request Body Content:

      Field Name Type Required Description
      batch_id string Yes A unique ID generated by the merchant, composed of uppercase and lowercase letters, numbers, and underscores, max length 32 characters.
      withdraw_list array object Yes Details of each withdrawal sub-order
      channel_id string No Client Name.

      Fields in the withdraw_list:

      Field Name Type Required Description
      merchant_withdraw_id string Yes Unique ID for the sub-order generated by the merchant, composed of uppercase and lowercase letters, numbers, and underscores, max length 32 characters.
      amount string Yes Withdrawal amount for each transaction, precision max length 6 digits; exceeding 6 digits will be truncated.
      currency string Yes Currency for withdrawal
      chain string Yes Network chain
      address string Yes Withdrawal address
      memo string Yes Remarks for a transfer, etc.; required for transfers on certain networks. Filling it out when it's not required may result in failure, max length 128 characters

    Request Example:

    curl --location 'https://openplatform.gateapi.io/v1/pay/withdraw' \
    --header 'X-GatePay-Certificate-ClientId: mZ96D37oKk-HrWJc' \
    --header 'Content-Type: application/json' \
    --header 'X-GatePay-Timestamp: 1725956825391' \
    --header 'X-GatePay-Nonce: 1698252264' \
    --header 'X-GatePay-Signature: fee74083ef2f64b8c0acbc4c0638586e6352b0d307d74aac038b2a7f40b396f8b47e6c18a6ed3da296168c9ff5a2a973b55115f969e95c0231c2bbbc70f7dea7' \
    --data '{
      "batch_id" : "237394559478075350",
      "channel_id" : "123456",
      "withdraw_list": [
        {
          "merchant_withdraw_id": "M137394559478075550",  
          "currency": "USDT",
          "amount": "1",
          "chain": "ETH",
          "address": "0x1234567890abcdef",
          "memo" : "Payment for services-1"
        },
        {
          "merchant_withdraw_id": "M137394559478075551",    
          "currency": "USDT",
          "amount": "0.001",
          "chain": "ETH",
          "address": "1A1zP1eP5QGefi2DMPTfTL5SLmv7DivfNa",
          "memo" : "Payment for services-1"
        }
      ]
    }'
    

    Response Example:

    {
        "status": "SUCCESS",
        "code": "000000",
        "errorMessage": "",
        "data": {
            "batch_id": "237394559478075550"
        }
    }
    

    Response Body Content:

    Field Name Type Description
    batch_id string Unique ID generated by the merchant

    # 3.2 Query Withdrawal Order Status

    • Data Type: JSON (content-type:application/json)
    • Request Method: POST
    • Path: /v1/pay/withdraw/query
    • Verification Method: Signature verification
    • Request Body Content:
    Field Name Type Required Description
    batch_id string Yes Unique ID generated by the merchant at /v1/pay/withdraw
    detail_status string Yes Query status of sub-orders
    ALL: all sub-orders
    PENDING: pending sub-orders
    PROCESSING: submitted withdrawal request, pending confirmation
    CHECK: in review
    FAIL: failed sub-orders
    DONE: successful sub-orders
    • Response Body Content:

    # Main order details:

    Field Name Type Description
    batch_id string Batch ID
    merchant_id int64 Merchant ID
    client_id string Client ID
    status string Main order status
    create_time int64 Main order creation time
    withdraw_list []*gfpay.BatchWithdrawSuborderDB Sub-order information
    channel_id string Customer channel name

    Master Order Status (Payout):

    Field Description
    PROCESSING Payout order created
    PARTIAL Partially successful
    FAIL Fully failed
    SUCCESS Fully successful

    # withdraw_list list details

    Field Name Type Description
    id int64 Record ID
    batch_id string Merchant batch withdrawal ID
    merchant_id int64 Merchant ID
    channel_id string Customer channel name
    suborder_id string Sub-order ID generated by gatepay
    withdraw_id string Withdrawal transaction ID, used to query withdrawal order
    chain string gate_chain name
    address string Withdrawal address
    currency string Currency
    amount decimal.Decimal Initiated withdrawal amount
    fee decimal.Decimal Transaction fee
    tx_id string Transaction hash
    timestamp int64 Deposit/withdrawal operation time
    memo string Transfer memo and other note information
    status string Status
    merchant_withdraw_id string Merchant withdrawal ID
    err_msg string Reason for withdrawal initiation failure
    client_id string Client ID
    create_time int64 Creation time
    update_time int64 Update time
    fee_type int8 0-Amount is deduction amount, 1-Amount is received amount
    batch_withdraw_id string Deprecated
    desc string Non-column field, customer channel remarks
    reconciliation_status int8 Withdrawal reconciliation status: 0-Not reconciled, 1-Reconciliation in progress, 2-Reconciliation matching failed, 3-Reconciliation matching successful
    is_placed int 0-Not placed, 1-Placed
    finish_time int64 Order completion time
    sub_amount decimal.Decimal Total deduction amount (fee amount + received amount)
    done_amount decimal.Decimal Received amount

    Sub-order Status (Payout)

    Field Description
    PENDING Order created, pending processing
    PROCESSING Order is being processed
    CHECK Under review
    FAIL Withdrawal failed
    DONE Withdrawal successful

    Request Example:

    curl --location 'https://openplatform.gateapi.io/v1/pay/withdraw/query' \
    --header 'X-GatePay-Certificate-ClientId: mZ96D37oKk-HrWJc' \
    --header 'Content-Type: application/json' \
    --header 'X-GatePay-Timestamp: 1726027137585' \
    --header 'X-GatePay-Nonce: 2290830087' \
    --header 'X-GatePay-Signature: 601d560c54d53412aca5901256f101e7078b5779f61f30bedfe9a5f0b92f049589952a151ea477371e4a99ac0e1c3cc8dec62654b3c6a1794ef981efe19232bc' \
    --data '{
        "batch_id":"237394559478075555",
        "detail_status":"ALL"
    }'
    

    Response Example:

    {
        "status": "SUCCESS",
        "code": "000000",
        "errorMessage": "",
        "data": {
            "batch_id": "237394559478075350",
            "merchant_id": 10002,
            "client_id": "mZ96D37oKk-HrWJc",
            "status": "FAIL",
            "create_time": 1726055849126,
            "channel_id": "123456",
            "withdraw_list": [
                {
                    "id": 35,
                    "batch_id": "237394559478075350",
                    "merchant_id": 10002,
                    "suborder_id": "268830764354768896",
                    "chain": "ETH",
                    "address": "0x1234567890abcdef",
                    "currency": "USDT",
                    "amount": "1",
                    "fee": "0",
                    "tx_id": "",
                    "timestamp": 0,
                    "memo": "Payment for services-1",
                    "status": "FAIL",
                    "merchant_withdraw_id": "M137394559478075550",
                    "err_msg": "unexpected http code error",
                    "client_id": "mZ96D37oKk-HrWJc",
                    "create_time": 1726055848856,
                    "update_time": 1726055856011,
                    "channel_id": "123456",
                    "fee_type": 1,
                    "done_amount": "1"
                },
                {
                    "id": 36,
                    "batch_id": "237394559478075350",
                    "merchant_id": 10002,
                    "suborder_id": "268830764354768897",
                    "chain": "ETH",
                    "address": "1A1zP1eP5QGefi2DMPTfTL5SLmv7DivfNa",
                    "currency": "USDT",
                    "amount": "0.001",
                    "fee": "0",
                    "tx_id": "",
                    "timestamp": 0,
                    "memo": "Payment for services-1",
                    "status": "FAIL",
                    "merchant_withdraw_id": "M137394559478075551",
                    "err_msg": "unexpected http code error",
                    "client_id": "mZ96D37oKk-HrWJc",
                    "create_time": 1726055848856,
                    "update_time": 1726055856010,
                    "channel_id": "123456",
                    "fee_type": 1,
                    "done_amount": "0.001"
                }
            ]
        }
    }
    

    If batch_id does not exist, return empty:

    {
        "status": "SUCCESS",
        "code": "000000",
        "errorMessage": "",
        "data": {
            "batch_id": "237394559478075358",
            "merchant_id": 0,
            "client_id": "",
            "status": "",
            "create_time": 0,
            "withdraw_list": []
        }
    }
    

    # 3.3 Query Supported Chains for Currency

    • Data Type: JSON (content-type: application/json)

    • Request Method: GET

    • Path: /v1/pay/wallet/currency_chains

    • Authentication: Signature Verification

    • Request Body:

      Field Name Type Required Description
      currency string Yes Specify currency name
    • Response Format:

      Status Code 200

    Field Name Type Required Description
    chain string Yes Blockchain network name (e.g. ERC20, TRC20, BEP20)
    name_cn string Yes Chinese name of blockchain (e.g. 以太坊 for Ethereum)
    name_en string Yes English name of blockchain (e.g. Ethereum, Tron)
    contract_address string Yes Smart contract address (empty string for native coins like BTC, ETH)
    is_disabled integer(int32) Yes Global disable status:
    0-enabled
    1-disabled
    is_deposit_disabled integer(int32) Yes Deposit function status:
    0-enabled
    1-disabled
    is_withdraw_disabled integer(int32) Yes Withdrawal function status:
    0-enabled
    1-disabled
    decimal string Yes Withdrawal precision (decimal places, e.g. "6" for BTC)

    Sample Code

    # coding: utf-8
    import requests
    
    host = "https://openplatform.gateapi.io/"
    prefix = "/v1/pay"
    headers = {'Accept': 'application/json', 'Content-Type': 'application/json'}
    
    url = '/wallet/currency_chains'
    query_param = 'currency=GT'
    r = requests.request('GET', host + prefix + url + "?" + query_param, headers=headers)
    print(r.json())
    

    Response Example: CODE 200

    [
      {
        "chain": "ETH",
        "name_cn": "以太坊ERC20",
        "name_en": "ETH/ERC20",
        "contract_address": "",
        "is_disabled": 0,
        "is_deposit_disabled": 0,
        "is_withdraw_disabled": 0
      }
    ]
    

    # 3.4 Query Total Balance of Personal Account

    • Data Type: JSON (content-type: application/json)

    • Request Method: GET

    • Path: /v1/pay/wallet/total_balance

    • Authentication: Signature Verification

    • Request Body:

      Field Name Type Required Description
      currency string Yes Specify currency name
    • Response Format:

      Status Code 200

    Field Name Type Required Description
    total object Yes Total account balance converted to target currency
    › amount string Yes Total balance amount
    › currency string Yes Target currency
    › unrealised_pnl string No Unrealized PnL total (only appears in futures/options/delivery/total accounts)
    › borrowed string No Total margin borrowing (only appears in margin/cross_margin accounts)
    details object Yes Account type details
    › account_type object Yes Account type key (see account types below)
    ›› amount string Yes Balance amount for this account type
    ›› currency string Yes Target currency
    ›› unrealised_pnl string No Unrealized PnL (only appears in futures/options/delivery/total accounts)
    ›› borrowed string No Margin borrowing (only appears in margin/cross_margin accounts)

    Simple Code

    # coding: utf-8
    import requests
    
    host = "https://openplatform.gateapi.io/"
    prefix = "/v1/pay"
    headers = {'Accept': 'application/json', 'Content-Type': 'application/json'}
    
    url = '/wallet/currency_chains'
    query_param = 'currency=GT'
    r = requests.request('GET', host + prefix + url + "?" + query_param, headers=headers)
    print(r.json())
    

    Response:

    CODE 200 
    
    [
      {
        "chain": "ETH",
        "name_cn": "以太坊ERC20",
        "name_en": "ETH/ERC20",
        "contract_address": "",
        "is_disabled": 0,
        "is_deposit_disabled": 0,
        "is_withdraw_disabled": 0
      }
    ]
    

    # 3.5 Withdrawal Status Query

    • Data Type: JSON (content-type: application/json)

    • Request Method: GET

    • Path: /v1/pay/wallet/withdraw_status

    • Authentication: Signature Verification

    • Request Body:

      Field Name Type Required Description
      currency string Yes Specify currency name
    • Response Format:

      Status Code 200

    Field Name Type Required Description
    currency string Yes Currency symbol (e.g. BTC, ETH)
    name string Yes Currency name (e.g. Bitcoin, Ethereum)
    name_cn string Yes Chinese name of currency (e.g. 比特币, 以太坊)
    deposit string Yes Deposit fee (usually "0" as string)
    withdraw_percent string Yes Withdrawal fee percentage (e.g. "0.1" means 0.1%)
    withdraw_fix string Yes Fixed withdrawal fee (e.g. "0.0005")
    withdraw_day_limit string Yes Daily withdrawal limit (max total withdrawal amount per day)
    withdraw_amount_mini string Yes Minimum withdrawal amount (single withdrawal cannot be lower than this)
    withdraw_day_limit_remain string No Remaining daily withdrawal limit (available amount left for today)
    withdraw_eachtime_limit string Yes Maximum single withdrawal amount (cannot exceed this per transaction)
    withdraw_fix_on_chains object No Fixed withdrawal fees per chain (property: chain name, value: fee string)
    withdraw_percent_on_chains object No Percentage withdrawal fees per chain (property: chain name, value: percentage string)

    No handling fees are charged for withdrawals to a Gate addresss, whereas handling fees apply when withdrawingto a non-Gate address.

    • When you call the "Withdrawal Status Query" interface, it retturns the handling fees required by the supported chains for the coin. Choose the chain you need.
    • Pay attention to the two parameters below:
    • [withdraw_fix_on_chains] refers to the fixed handling fee.
    • [withdraw_percent_on_chains] refers to the percentage-based handling fee (When you withdraw certain special coins, the fee is calculated as the withdrawal quantity rmultiplied by the percentage).
    • Withdrawal Handling Fee = Fixed Handling Fee + Fee Percentage >Withdrawal Quantity
    • At present, most common chains only charge a fixed handling feewhich is updated hourly.
    • Call the interface to check the handling fee every time you make awithdrawal. The handling fee is updated hourly.

    Simple Code:

    import requests
    import time
    import hashlib
    import hmac
    import math
    import random
    
    host = "https://openplatform.gateapi.io/"
    prefix = "/v1/pay"
    headers = {'Accept': 'application/json', 'Content-Type': 'application/json'}
    
    url = '/wallet/withdraw_status'
    query_param = ''
    
    nonce = math.floor(((random.random() * 9 + 1) * 1000000000))
    secret = ""
    
    sign_headers = generate_signature(str(int(time.time()*1000)),nonce,"",secret)
    headers.update(sign_headers)
    r = requests.request('GET', host + prefix + url, headers=headers)
    print(r.json())```
    
    

    Response:

    [
      {
        "currency": "GT",
        "name": "GateToken",
        "name_cn": "GateToken",
        "deposit": "0",
        "withdraw_percent": "0%",
        "withdraw_fix": "0.01",
        "withdraw_day_limit": "20000",
        "withdraw_day_limit_remain": "20000",
        "withdraw_amount_mini": "0.11",
        "withdraw_eachtime_limit": "20000",
        "withdraw_fix_on_chains": {
          "BTC": "20",
          "ETH": "15",
          "TRX": "0",
          "EOS": "2.5"
        },
        "withdraw_percent_on_chains": {
          "ETH": "0%",
          "GTEVM": "0%"
        }
      }
    ]
    

    # 3.6 Withdrawal Records

    • Data Type: JSON (content-type: application/json)
    • Request Method: GET
    • Path: /v1/pay/wallet/withdrawals
    • Authentication: Signature Verification
    • Request Parameters:
    Field Name Type Required Description
    currency string No Specify currency to query, returns all currencies if empty
    withdraw_id string No Withdrawal record ID (starts with 'w', e.g. w1879219868), queries single record if specified
    asset_class string No Currency type (Main/Pilot zone), empty by default. Values: SPOT, PILOT
    withdraw_order_id string No User-defined withdrawal order number for specific record query
    from integer(int64) No Start timestamp (Unix) units in seconds, defaults to last 7 days
    to integer(int64) No End timestamp (Unix) units in seconds, defaults to current time
    limit integer No Maximum number of records to return
    offset integer No Return record offset (starts from 0)

    Query time range cannot exceed 30 days

    Detailed description:

    • Response Format:

    Status Code 200

    Field Name Type Description
    id string Transaction record ID
    txid string Blockchain transaction hash
    block_number string Block number
    withdraw_order_id string Client order ID (max 32 chars, only allows numbers/letters/_/-/.)
    timestamp string Operation time
    amount string Amount of currency
    fee string Fee amount
    currency string Currency name
    address string Withdrawal address
    fail_reason string Failure reason (only when status = CANCEL)
    timestamp2 string Final status time:
    • CANCEL: Cancellation time
    • DONE(block_number>0): Success time
    memo string Transaction memo/notes
    status string Transaction status:
    - DONE: Completed (block_number > 0 means on-chain confirmed)
    - CANCEL: Cancelled
    - REQUEST: Requesting
    - MANUAL: Pending manual review
    - BCODE: Top-up code operation
    - EXTPEND: Sent awaiting confirmation
    - FAIL: On-chain failure awaiting confirmation
    - INVALID: Invalid order
    - VERIFY: Verifying
    - PROCES: Processing
    - PEND: Processing
    - DMOVE: Pending manual review
    - REVIEW: Under review
    chain string Withdrawal chain name

    Request:

    # coding: utf-8
    import requests
    import time
    import hashlib
    import hmac
    
    host = "https://openplatform.gateapi.io"
    prefix = "/v1/pay"
    headers = {'Accept': 'application/json', 'Content-Type': 'application/json'}
    
    url = '/wallet/withdrawals'
    query_param = ''
    
    sign_headers = gen_sign('GET', prefix + url, query_param)
    headers.update(sign_headers)
    r = requests.request('GET', host + prefix + url, headers=headers)
    print(r.json())
    

    Response:

    [
      [
        {
          "id": "w1879219868",
          "currency": "USDT",
          "address": "THISISTESTADDRESSFORGATEPAY",
          "amount": "4.023",
          "fee": "0",
          "txid": "Internal transaction 260594131",
          "chain": "BSC",
          "timestamp": "1745220149",
          "status": "DONE",
          "withdraw_order_id": "202504211521368538928",
          "block_number": "1000",
          "fail_reason": "",
          "type": "appbankgp",
          "timestamp2": "1745220149",
          "memo": ""
        }
      ]
    ]
    

    # 3.7 Callback Notification

    Withdrawal order callback notification fields:

    Field Name Type Description
    main_order object Main withdrawal order details
    suborders array Suborder details

    # 3.7.1 Callback

    # Main Order

    Field Name Type Required Description
    batch_id string Yes Batch ID
    merchant_id integer Yes Merchant ID
    status string Yes Order status
    client_id string Yes Client ID
    pay_back_status string Yes Refund status
    channel_id string Yes Channel ID

    # Suborder

    Field Name Type Required Description
    merchant_id integer Yes Merchant ID
    channel_id string Yes Channel ID
    suborder_id string Yes Suborder ID
    chain string Yes Blockchain network
    address string Yes Receiving address
    currency string Yes Currency
    amount string Yes Transfer amount
    fee string Yes Fee
    tx_id string Yes Transaction hash
    memo string Yes Memo
    status string Yes Status (DONE/FAIL)
    merchant_withdraw_id string Yes Merchant withdrawal ID
    fee_type integer Yes Fee type: 0-Withdrawal amount includes fee, 1-Withdrawal amount is net amount
    batch_withdraw_id string Yes Batch withdrawal ID
    desc string Yes Description
    reconciliation_status integer Yes Reconciliation status
    is_placed integer Yes Processing status: 0-Not submitted, 1-Submitted
    finish_time integer Yes Completion timestamp
    sub_amount string Yes Suborder total amount
    done_amount string Yes Actual completed amount

    Callback :

    {
      "main_order": {
        "batch_id": "831618381568",
        "merchant_id": 17329983,
        "status": "SUCCESS",
        "client_id": "igasgasdbub",
        "pay_back_status": "NO",
        "channel_id": ""
      },
      "suborders": [
        {
          "merchant_id": 130559,
          "channel_id": "",
          "suborder_id": "30969031299072",
          "chain": "TRX",
          "address": "QBTW9qTMQBTW9qnoeMMmUxaAWEqVDDUgUw",
          "currency": "USDT",
          "amount": "2362.1",
          "fee": "1",
          "tx_id": "aaa33e642d6fb6e3272ae3c21c60f1248d1cd7ccdc000458308d690699",
          "memo": "",
          "status": "DONE",
          "merchant_withdraw_id": "1839295815",
          "fee_type": 1,
          "batch_withdraw_id": "",
          "desc": "",
          "reconciliation_status": 0,
          "is_placed": 1,
          "finish_time": 1748581414000,
          "sub_amount": "2363.1",
          "done_amount": "2362.1"
        }
      ]
    }
    

    # 4. Common Error Codes for Merchant Bulk Withdrawal

    HTTP Status Code Error Code descriptions Notes
    200 550233 Insufficient withdrawal balance. 提现划转余额不足
    200 550234 Memo exceeds length limit. 提现memo超过长度限制
    200 550235 The minimum precision limit of the withdrawal currency, the precision can not be less than 6 decimal places 提现币种最小精度限制,精度不能小于小数点6位
    200 550236 The user does not have withdrawal permissions. 当前提现用户无权限,可联系运营人员申请开通
    200 550237 Failure to transfer. 提现划转失败
    200 550238 The number of withdrawals exceeds the limit of {xx} 提现子单数量超限制
    200 550239 amount is required. 提现金额不能为空
    200 550240 currency is required. 提现币种不能为空
    200 550241 address is required. 提现地址不能为空
    200 550242 chain is required. 提现链名不能为空
    200 550243 withdraw_order_id is required. 子单withdraw_order_id参数不能为空
    200 550244 batch_id is required. batch_id不能为空
    200 550245 batch_id duplicates batch_id重复
    200 550246 currency withdrawals are not supported yet. 不支持的币种提现
    200 550247 Incorrect state parameters. 提现查询接口状态参数不合法
    200 550248 Sub-order parameter error. 子订单参数错误
    200 550249 Invalid merchant order id. batch_id,或者withdraw_order_id参数不合法