# 1.Merchant access

    # 1.1 Online service address

    https://openplatform.gateapi.io
    

    # 1.2 Configure new applets

    • Log in to the merchant background, via the background address: https://www.gate.com/zh/merchant#/get-started
    • Fill in the basic information and apply to become a merchant
    • Configure the new application on the configuration page -View the list of configured applications and obtain the application ClientId

    # 1.3 Generate payment key

    • Enter the developer page and generate a "Payment API Secret Key" for calculating signature verification
    • Enter the developer page and generate an "Authorize Secret Key" for calculating signature verification

    # 1.4 Key parameters

    • Payment API key, used to request a signature
    • ClientId, used to identify the identity and verify the signature together with the payment API key

    # 2. Security requirements

    # 2.1 Protocol rules

    # 2.1.1 The following rules must be followed when the merchant accesses and calls API:

    Parameter name Description
    Transmission mode To ensure transaction security, HTTPS transmission is adopted and TLS1.2 or higher is used
    Data format Both submission and return data are in JSON format
    Signature algorithm HMAC-512 algorithm
    Signature requirement Signature verification is required for both requesting and receiving data, refer to Interface Signature
    Judgmental logic First judge the return of the protocol field, then judge the return of the business, and finally judge the transaction status

    # 2.1.2 Response format

    All interface returns are in JSON format, and users need to convert and extract data by themselves.

    Parameter name Type Description
    status string The request processing result: SUCCESSmeans processing succeeds, FAILmeans processing fails
    code string The defined error code, see the chapter on error codes for the specific meaning
    label string Defined error name, which is returned only when processing fails
    errorMessage string Defined error description
    data string Request return content in JSON format

    Return successfully:

    {
        "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,
            "channelId": "123456"
        }
    }
    

    Error return:

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

    # 2.2 Parameter specification

    # 2.2.1 Merchant's order number

    The merchant can customize the order number, which should be a combination of English half-width characters such as letters, numbers, dash-, and underscore_, but should not contain Chinese characters or full-width characters. A unique order number should be generated for each deal (it is recommended to generate the order number based on the current system time plus in a random sequence). To initiate a repayment, the original order number should be submitted to avoid repeated payments.

    # 2.2.2 Amount

    All amount parameters are transmitted in strings with an accuracy of 6 decimal places, such as order amount, refund amount, etc. The minimum transaction amount of a single transaction amount is 0.000001, and the maximum is 5000000.

    # 2.2.3 Currency type

    For the currencies supported by GatePay, refer to the supported currencies section

    # 2.2.4 Time

    Unless otherwise specified, all time fields should be in the form of millisecond-level Unix timestamps.

    # 2.3 API protocol header specification

    In order to ensure that the request received by GatePay API comes from an authorized legal third-party platform, the GatePay API interface will check the required fields of the HTTP request header and perform a verification signature of the request.

    # 2.3.1 New V2 Version protocol header

    The new version of the protocol header, which uses the secret key generated in the merchant's background to calculate the signature.

    Head field To ensure transaction security, use HTTPS transmission
    X-GatePay-Certificate-ClientId The clientId assigned to the merchant when registering the application
    X-GatePay-Timestamp The UTC timestamp when the request was generated, in milliseconds. Please note that GatePay does not process requests with a time gap of more than 10 seconds between the time of receiving the request and this timestamp
    X-GatePay-Nonce The string had better in length shorter than 32 characters and should consist of numbers and letters
    X-GatePay-Signature Request signature. GatePay determines whether the request is legal depending upon this signature

    # 2.4 Interface signature

    # 2.4.1 Signature specification

    Constructing signature string rules We expect the merchant's technical developers to construct the signature string according to the rules agreed in the current documentation. GatePay will construct the signature string in the same way. If the merchant constructs the signature string in the wrong way, the signature verification will not pass. The specific format of the signature string is explained first. Each line has one parameter. The end of the line is terminated by \n (a line feed, ASCII value 0x0A). If the parameter itself ends with \n, an additional \n is also required.

    timestamp\nnonce\nbodyString\n

    # 2.4.2 Signature algorithm

    See the example of the signature algorithm on the right

    Golang

    import 
    (
    "crypto/hmac"
    "crypto/sha512"
    "encoding/hex"
    "fmt"
    )
    // GenerateSignature: generate the request signature
    // timestamp: UTC timestamp converted to a string, precision is millisecond
    // 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 converted to a string, precision is millisecond
          :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;
    

    # 2.4.3 Payment Callback Handling

    # 2.4.3.1Callback Description

    Gate Pay sends the callback message to the callback URL via a POST request. The request body contains JSON-formatted notification parameters. The parameter list is as follows:

    [
        {
            "bizType": "TRANSFER_ADDRESS",
            "bizId": "329782527190433792",
            "bizStatus": "TRANSFERRED_ADDRESS_DELAY",
            "client_id": "iVNJZdekOCMJIsmV",
            "data": "{\"merchantTradeNo\":\"1894789022551797760\",\"productType\":\"\",\"productName\":\"\",\"clientId\":\"iVNJZdekOCMJmV\",\"tradeType\":\"WAP\",\"goodsName\":\"\",\"terminalType\":\"WAP\",\"currency\":\"USDT\",\"orderAmount\":\"53.5\",\"payerId\":0,\"createTime\":1740587881545,\"transactionId\":\"32980282579722\",\"transferAmount\":\"53.5\",\"tx_hash\":\"906de03e219a0505ff42eecc804eaae38f90d6fdce8467c04455b\",\"channelId\":\"\",\"address\":\"THMpQjp3SAn5K9nwpLrtLCnGXQaYAKGCKD\",\"chain\":\"TRX\"}"
        }
    ]
    
    Name Type Description
    bizType string Enum for asynchronous callback type:
    "PAY": Non-address payment
    "PAY_BATCH": Asynchronous batch reward
    "PAY_ADDRESS": Address-based payment
    "PAY_FIXED_ADDRESS": Fixed collection QR code address-based payment
    "TRANSFER_ADDRESS": Address transfer
    bizId string Payment order ID
    bizStatus Stirng Order status
    client_id String The client_id associated with the payment order
    data json Format Varies depending on the business type; refer to the relevant business documentation for details

    # 2.4.3.2 Callback Signature Verification & Response

    Upon receiving the callback notification, the merchant must verify the signature and respond to the callback.

    Merchant response fields after signature verification::

    Parameter Description
    returnCode Whether the callback was successfully processed:
    "SUCCESS": Indicates successful processing; Gate Pay will not resend the callback
    "FAIL": Indicates processing failure; Gate Pay will retry sending the callback
    returnMessage Failure reason (string), optional

    Response format: JSON:

    {
        "returnCode": "SUCCESS",
        "returnMessage": ""
    }
    

    # 2.4.3.3 Callback Handling Steps

    Signature verification steps:

    The callback request will include signature information in the HTTP headers, used for verifying the signature. Details are as follows:

    Parameter Description
    X-GatePay-Timestamp Timestamp for signature verification
    X-GatePay-Nonce Random string for signature verification
    X-GatePay-Signatur Signature value for verification

    To verify the signature, the merchant should construct a signature verification string using the X-GatePay-Timestamp,X-GatePay-Nonce, and the JSON-formatted notification parameters in the request body (see Section 2.4.2 Signature Algorithm for details on the signature construction). Then, use the merchant's payment key to compute the signature and compare it with the X-GatePay-Signature value to ensure the callback is genuinely from Gate Pay.

    # 2.4.4 Signature Verification Tool

    Merchant developers can use this tool to troubleshoot the reasons why signature verification fails.

    Signature Verification Tool

    # 3. List of public APIs

    # 3.1 Check merchant payment account balance

    • Data type: JSON (content-type:application/json)
    • Request method: GET
    • Path: /v1/pay/balance/query
    • Verification method: Merchant signature verification
    • request body type: none

    Example of requests:

    curl --location 'https://openplatform.gateapi.io/v1/pay/balance/query' \
    --header 'Content-Type: application/json' \
    --header 'X-GatePay-Certificate-ClientId: mZ96D37oKk-HrWJc' \
    --header 'X-GatePay-Timestamp: 1695611256106' \
    --header 'x-GatePay-Nonce: 1260554069' \
    --header 'x-GatePay-Signature: bae293c2575ccea15592fe4cec2efa2629ea37c04fc8d856060ce76dc3cebdea9382a1088c43e14a33301a320b4a2aefc029b399c337459581220bcdc17de526'
    

    Example of response:

    {
        "status": "SUCCESS",
        "code": "000000",
        "errorMessage": "",
        "data": {
            "balance_list": [
                {
                    "currency": "DOGE",
                    "available": "1843.32095"
                },
                {
                    "currency": "FORG",
                    "available": "3.02"
                }
            ]
        }
    }
    
    Field name Type Required Description
    status string Required SUCCESS or FAIL
    code string Required Error Code
    data []*BalanceItem Optional Refund Order Info
    errorMessage string Optional Error Message

    BalanceItem:

    Field name Type Required Description
    currency string Required Currency
    available string Required The balance of the currency in the merchant's spot account. The balance is truncated to six decimal places, rounded down, and trailing zeros are omitted.

    # 4. Asynchronous notification of order status

    # 4.1 Asynchronous notification of order status

    1. When the order status changes, such as when the payment is successful, the payment time is exceeded, or the order is canceled, the GatePay backend will send an order status notification to the merchant at the callback url provided by the merchant during registration.
    2. If the notification fails due to network or other unknown reasons, GatePay backend will retry 10 times every 3 seconds. If the retry also fails, the merchant can get the order status by calling the order status inquiry interface.
    3. Merchants receive asynchronous notification messages and must verify the message signature parameter to validate the message's legitimacy.

    # 4.2 Message structure

    Field name Type Description
    bizType string Description of the notification type, see the BizType table
    bizId string Order ID
    bizStatus string Order status, see the BizStatus table
    client_id string Merchant client_id that created the order
    data string Message content, varies depending on the bizType

    Example message structure:

    {
        "bizType":"PAY",
        "bizId":"6948484859590",
        "bizStatus":"PAY_SUCCESS",
        "client_id":"cdhu-fgrfg44-5ggd-cdvsa",
        "data":"{...Json format data...}"
    }
    

    Upon receiving the asynchronous callback message, the merchant must respond with a successful acknowledgment. Example message structure:

    {
        "returnCode": "SUCCESS",
        "returnMessage": ""
    }
    

    # 4.3 BizType enumeration value

    Value Description
    PAY Notification of non-address payment order status change to payment successPAY_SUCCESS
    Timeout or merchant close the orderPAY_CLOSE
    Payment errorPAY_ERROR
    PAY_REFUND Notification of refund order status change, refund success or failure
    PAY_BATCH Notification of batch reward order status change
    TRANSFER_ADDRESS Notification of address payment received
    RECEIVED_CONVERT_DELAY_ADDRESS Notification of delayed payment order processing for address payments
    PAY_ACTUALLY Notification of a payment order for revenue currency specified by the merchant

    # 4.4 BizStatus value

    Value Description
    PAY_SUCCESS Payment success
    PAY_ERROR Payment encountered an error
    PAY_CLOSE Order closed by the merchant or timed out
    REFUND_SUCCESS Refund success
    REFUND_REJECTED Refund rejected
    PAY_EXPIRED_IN_PROCESS Notification of an address payment order entering the PROCESS state
    PAY_EXPIRED_IN_EXCHANGE_FLUCTUATION Address payment failed due to exchange rate fluctuations
    TRANSFERRED_ADDRESS_IN_TERM When a successful payment for a non-Convert address payment order is detected, the corresponding amount will be deposited into the merchant's Payment Account instantly (transfer received before the order expires).
    TRANSFERRED_ADDRESS_DELAY Delayed transfer of address payment
    CONVERT_ADDRESS_PAY_DELAY Delayed payment for convert, but no transfer was made
    TRANSFERRED_ADDRESS_BLOCK Funds successfully received by Gate but held due to risk (not credited)

    # 4.5 Data structure corresponding to bizType

    bizType is eitherPAY,TRANSFER_ADDRESS,RECEIVED_CONVERT_DELAY_ADDRESS`

    Field name Type Description
    merchantTradeNo string Merchant trade number
    productType string goodsType when creating the order
    productName string GoodsName when creating the order
    tradeType string terminalType when creating the order
    goodsName string GoodsName when creating the order
    terminalType string terminalType when creating the order
    currency string Order currency
    orderAmount string Order amount refers to the payment amount when the order is successfully paid viaGate.
    expectCurrency string Currency specified for revenue by the merchant
    actualCurrency string Actual currency settled by Gate to the merchant. If Gate successfully converts the order currency to the currency requested by the merchant, actualCurrency will be the same as expectCurrency. Otherwise, actualCurrency will be equal to currency
    actualAmount string Amount corresponding to the actualCurrency currency
    payerId int64 UID of the paying user
    createTime int64 Order creation time
    channelId string Client Name.
    chain string Network name
    address string Collection address

    **Address payment received, but flagged as risky (bizStatus = TRANSFERRED_ADDRESS_BLOCK)"

    {
        "bizType": "TRANSFER_ADDRESS",
        "bizId": "355736614742863872",
        "bizStatus": "TRANSFERRED_ADDRESS_BLOCK",
        "client_id": "gvnOrRLCqLPZVLut",
        "data": {
            "merchantTradeNo": "kt40t9i3t34kt0k09f5449343333",
            "productType": "",
            "productName": "Sipariş Ödemesi - 177",
            "clientId": "gvnOrRLCqLPZVLut",
            "tradeType": "APP",
            "goodsName": "Sipariş Ödemesi - 177",
            "terminalType": "APP",
            "currency": "USDT",
            "orderAmount": "10",
            "payerId": 0,
            "createTime": 1746775818221,
            "transferAmount": "100000000",
            "tx_hash": "kt40t9i3t34kt0k09t54393332223111222",
            "channelId": "",
            "address": "0x0410084a4c1a8fC8f6Ca67aF168Bc2ceB5ee8A31",
            "chain": "ETH"
        }
    }
    

    Non-address payment order status notification bizType=PAY

    {
        "bizType":"PAY",
        "bizId":"6948484859590",
        "bizStatus":"PAY_SUCCESS",
        "client_id":"cdhu-fgrfg44-5ggd-cdvsa",
        "data":{
            "merchantTradeNo":"gateio_withdraw6331782520222",
            "productType":"NFT",
            "productName":"ka",
            "tradeType":"APP",
            "goodsName":"ka",
            "terminalType":"APP",
            "currency":"USDT",
            "totalFee":"1.2",
            "orderAmount":"1.2",
            "createTime":1664123708000,
            "transactionId":"24344545",
            "channelId": "123456"
        }
    }
    
    

    Address payment received notification bizType=TRANSFER_ADDRESS

    {
        "bizType": "TRANSFER_ADDRESS",
        "bizId": "316518004856401920",
        "bizStatus": "TRANSFERRED_ADDRESS_IN_TERM",
        "client_id": "mZ96D37oKk-HrWJc",
        "data": {
            "merchantTradeNo": "2025012110092945520120735194",
            "productType": "",
            "productName": "测试订单0005",
            "clientId": "mZ96D37oKk-HrWJc",
            "tradeType": "MINIAPP",
            "goodsName": "测试订单0005",
            "terminalType": "MINIAPP",
            "currency": "USDT",
            "orderAmount": "1",
            "payerId": 0,
            "createTime": 1737425372977,
            "transactionId": "316518169102520320",
            "channelId": "test",
            "transferAmount": "1",
            "tx_hash": "2025012110093850928633404431",
            "address": "TKoWkE1DfBACQTD5hsdUbj5Bn",
            "chain": "TRX"
        }
    }
    
    

    Transfer to expired address bizType=TRANSFERRED_ADDRESS_DELAY

    {
        "bizType": "TRANSFER_ADDRESS",
        "bizId": "316518004856401920",
        "bizStatus": "TRANSFERRED_ADDRESS_DELAY",
        "client_id": "mZ96D37oKk-HrWJc",
        "data": {
            "merchantTradeNo": "2025012110092945520120735194",
            "productType": "",
            "productName": "测试订单0005",
            "clientId": "mZ96D37oKk-HrWJc",
            "tradeType": "MINIAPP",
            "goodsName": "测试订单0005",
            "terminalType": "MINIAPP",
            "currency": "USDT",
            "orderAmount": "1",
            "payerId": 0,
            "createTime": 1737425372977,
            "transactionId": "316518169102520320",
            "channelId": "test",
            "transferAmount": "1",
            "tx_hash": "2025012110093850928633404431",
            "address": "TKoWkE1DfBACQTD5hsdUbj5Bn",
            "chain": "TRX"  
        }
    }
    

    Address payment order status notification bizType=RECEIVED_CONVERT_DELAY_ADDRESS

    {
        "bizType":"RECEIVED_CONVERT_DELAY_ADDRESS",
        "bizId":"6948484859598",
        "bizStatus":"TRANSFERRED_ADDRESS_PAID",
        "client_id":"cdhu-fgrfg44-5ggd-cdvsa",
        "data":{
            "merchantTradeNo":"gateio_withdraw6331782520222",
            "productType":"NFT",
            "productName":"ka",
            "tradeType":"APP",
            "goodsName":"ka",
            "terminalType":"APP",
            "currency":"USDT",
            "totalFee":"1.2",
            "orderAmount":"1.2",
            "createTime":1664123708000,
            "transactionId":"24344545",
            "transferAmount":"0.8",
            "channelId": "123456"
        }
    }
    
    

    bizType=PAY_REFUND

    {
        "bizType":"PAY_REFUND",
        "bizId":123289163323899904,
        "bizStatus":"REFUND_SUCCESS",
        "data":{
            "merchantTradeNo":"56236",
            "orderAmount":"1.91",
            "refundInfo":{
                "orderAmount":"1.91",
                "prepayId":"1647438500687506",
                "refundRequestId":"156123911",
                "refundAmount":"0.8"
            },
            "currency":"BTC",
            "productName":"NFT",
            "terminalType":"MINIAPP"
        }
    }
    
    

    bizType=PAY_BATCH

    {
        "bizType":"PAY_BATCH",
        "bizId":"1234567999800",
        "bizStatus":"REFUND_SUCCESS",
        "client_id":"JaBxopuhY",
        "data":{
            "merchant_batch_no":"6678554A99000",
            "currency":"",
            "order_list":[
                {
                    "receiver_id":10000,
                    "amount":"1.3",
                    "currency":"USDT",
                    "status":"PAID",
                    "reward_id":"50888456789213330",
                    "create_time":1676336326072
                },
                {
                    "receiver_id":10001,
                    "amount":"5.7",
                    "currency":"USDT",
                    "status":"PAID",
                    "reward_id":"50888456789215557",
                    "create_time":1676336326072
                }
            ]
        }
    }
    
    

    bizType=PAY_ACTUALLY

    {
        "bizType":"RECEIVED_CONVERT_DELAY_ADDRESS",
        "bizId":"577886948403339870",
        "bizStatus":"CONVERT_ADDRESS_PAY_DELAY",
        "client_id":"cdhu-fgrfg44-5ggd-cdvsa",
        "data":{
            "merchantTradeNo":"2345677666545556",
            "productType":"NFT",
            "productName":"NFT",
            "tradeType":"WEB",
            "goodsName":"NFT2",
            "terminalType":"APP",
            "currency":"USDT",
            "totalFee":"2.35",
            "orderAmount":"2.35",
            "payCurrency":"USDT",
            "payAmount":"2.36",
            "expectCurrency":"",
            "actualCurrency":"",
            "actualAmount":"",
            "payerId":10000,
            "createTime":1676343810430,
            "transactionId":"59847585498494",
            "channelId": "123456"
        }
    }
    

    # 5. Error code

    Http status code Error code Description Solution
    500 300000 System error System exception, please retry with the same parameters
    500 300001 Internal error System exception, please retry with the same parameters
    500 400000 Unknown error System exception, please retry with the same parameters
    200 400001 Request parameter format error Check request data parameters and format
    200 400002 Signature verification failed Check if the merchant's signature is correct
    200 400003 Request timestamp timed out Check the timestamp field in the request header
    200 400007 Unsupported media type Check the media type set in the interface
    200 400020 Signature random number error Please check whether the random number is empty
    200 400201 Merchant order number already exists Please verify whether the merchant order number has been submitted repeatedly
    200 400202 Order does not exist Check whether the order has been traded or whether the order number is correct
    200 400203 Merchant number does not exist Check whether the merchant number is correct
    200 400204 Order status is incorrect Check whether the order has expired, canceled, or closed, and use the query interface if necessary
    200 400205 Invalid currency Check the currency type of the order
    200 400304 Refund ID does not exist Check the requested refund ID
    200 400603 Order timed out Please verify whether the order has expired
    200 400604 Invalid refund-related transaction order Check whether the refund transaction order is in a completed state
    200 400605 Insufficient balance in the payment account Insufficient balance in the payment account
    200 400607 Too many refunds The number of refunds exceeds the limit
    200 400608 Refund amount exception Please check the refund amount
    200 400620 Duplicate order payment Please verify whether the merchant order number has been submitted repeatedly
    200 400621 Incorrect payment amount Check the requested amount
    200 400622 Exchange rate fluctuations result in payment failure You can try to apply again
    200 400623 Unsupported currency payment Check the payment currency
    200 400624 Invalid order status notification address Check whether the callback address provided by the merchant is valid
    200 500008 Corresponding merchant not found Check whether the requested merchant ID is correct
    200 500100 Payment QR code expired Redefine and generate a new QR code
    200 500101 Duplicate payment QR code Please verify the order status
    200 500103 Address payment exchange currency error Exchange rate fluctuations affect the collection rat
    200 500203 Unable to query order details for address payment Please check whether the address is correct
    200 500204 Invalid recipient ID for refund transaction order Please confirm that the recipient of the refund is a Gate user
    200 500205 Refund currency does not match currency of the order or the user's payment currency Please ensure that the refund currency is one of the order currency or the user's payment currency
    200 500206 Refund amount exceeds limit Please check the refund amount of the order
    200 500207 Unable to find the refund order for address payment Please confirm whether the refund was successful or check whether the address is correct
    200 500208 Cannot refund orders without a converted address Please confirm the type of refund order

    # 6. Best practices

    # 6.1 Payment callback and order query implementation guidelines

    Background

    Due to network issues or system fluctuations, the merchant side may fail to receive the payment result notification even if the user completes the payment, and the order might be displayed as unpaid. This is the case that will give rise to user complaints and even repeated payments.

    Target

    The purpose is to let the merchant get the payment status of the order in a timely and accurate manner even when it fails to receive the payment result notification, so as to improve the robustness of the merchant system and reduce user complaints caused by out-of-sync notification of order status.

    Merchant backend service processing

    The merchant background needs to accurately and efficiently process the asynchronous payment result notification sent by GatePay, and return the processing result to GatePay according to the interface specification.

    Regular polling query

    If the merchant fails to receive the payment result notification for a long time, the merchant’s background should initiate the regular polling query (order status query interface /v1/pay/order/query) to query the order status.

    Plan 1

    Based on the time when the order is successfully placed, query the order status by calling the order status query interface (/v1/pay/order/query) every 5 seconds/10 seconds/30 seconds/1 minute/3 minutes/5 minutes/10 minutes/30 minutes. If no successful payment notice returns at the last query, stop the query, and call the closing order interface (/v1/pay/order/close) to close the order. (Merchants can set the interval and times for polling query flexibly according to their own business scenarios)

    Plan 2

    The regular polling query is performed every 30 seconds to find out the orders that have been created and not paid in the last 10 minutes, and the order status query interface is called (/v1/pay/order/query) to query the order status. The system records the number of order inquiries, and if no successful payment notice returns after 10 inquiries, stops the query, and calls the closing order interface (/v1/pay/order/close) to close the order. (Merchants can set the interval and times for polling query flexibly according to their own business scenarios)

    Note: After the payment is completed, GatePay will send the relevant payment result to the merchant in the form of a data stream, and the merchant needs to receive and process it, and return a response according to the specification.

    1. The same notification may be sent to the merchant system multiple times, so the merchant system must be able to handle repeated notifications.

    2. When interacting with asynchronous notifications in the background, if GatePay receives a response from the merchant that does not meet the specifications or fails to receive the response in the agreed time, the system will determine that the notification failed to be sent and then will resend the notification until it is successfully sent. (GatePay will send the notice 10 times every 5 seconds until it is sent successfully)

    # 6.2 Implementation guidelines for the refund process

    1. The merchant calls the refund interface (/v1/pay/order/refund) to create a refund order. Note that the refund is an asynchronous process, and the success of calling this interface does not represent the successful completion of the refund.

    2. Wait for the refund callback notification. If merchants receive the GatePay asynchronous callback notification and get the refund result, they don’t need to call the query interface.

    3. If the refund status notification is not received within 10s, call the (/v1/pay/order/refund/query) interface to query the status of the refund order. For details, please refer to Payment Callback and Order Query Implementation Guidelines.

    # 6.3 Best security practices

    # 6.3.1 Data transmission

    Use HTTPS to ensure network transmission security. Do not use insecure protocols and algorithms such as SSL, it is recommended to use TLS1.2. No self-developed encrypted transmission algorithm is recommended because they will have security issues.

    # 6.3.2 Data storage

    Sensitive information should not be contained in the log. Those that must be used should be desensitized. Sensitive data in the cache and DB needs to be encrypted Key authentication, such as passwords, must be stored in salted encryption.

    # 6.3.3 Data access

    External requests for data access must be authenticated. Internal data access should be strictly controlled to reduce the risk of user information leakage.

    # 6.3.4 Prevent vulnerabilities caused by improper logic processing

    GatePay signature verification is required for the successful payment callback notification to avoid malicious attacks. The judgment logic of the merchant's price is carried out in the background to avoid the client from tampering with the price and therefore causing the merchant's loss. Merchant Securekey should not appear in App or website pages.

    # 7. Frequently asked questions

    # Q: How long is the QR code generated through the pre-order interface valid?

    A: Merchants can specify the order expiration time, the maximum and default validity of the order is one hour.

    # 8. List of supported currencies

    # 8.1 Address payment

    5 currencies are supported for address payment:

    "USD", "USDT", "BTC", "ETH", "GT"
    

    # 8.2 Normal payment

    21 currencies are supported for payment:

    "BTC", "USDT", "USD", "GT", "ETH", "EOS", "DOGE", "DOT", "SHIB", "LTC", "ADA", "BCH", "FIL", "ZEC", "BNB", "UNI", "XRP", "STEPG", "SUPE", "LION", "FROG"