https://openplatform.gateapi.io
- 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
- 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
- Payment API key, used to request a signature
ClientId
, used to identify the identity and verify the signature together with the payment API key
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 |
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: SUCCESS means processing succeeds, FAIL means 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": {}
}
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.
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
.
For the currencies supported by GatePay, refer to the supported currencies section
Unless otherwise specified, all time fields should be in the form of millisecond-level Unix
timestamps.
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.
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 |
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
See the example of the signature algorithm on the right
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()
Merchant developers can use this tool to troubleshoot the reasons why signature verification fails.
JSON (content-type:application/json)
GET
/v1/pay/balance/query
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. |
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"
}
]
}
}
callback url
provided by the merchant during registration.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 |
Value | Description |
---|---|
PAY | Notification of non-address payment order status change to payment successPAY_SUCCESS Timeout or merchant close the order PAY_CLOSE , Payment error PAY_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 |
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) |
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": ""
}
bizType is either
PAY,
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 |
payCurrency | string | Currency actually paid by the user |
payAmount | string | Actual amount paid by the user |
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"
}
}
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 |
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.
The same notification may be sent to the merchant system multiple times, so the merchant system must be able to handle repeated notifications.
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)
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.
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.
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.
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.
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.
External requests for data access must be authenticated. Internal data access should be strictly controlled to reduce the risk of user information leakage.
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.
A: Merchants can specify the order expiration time, the maximum and default validity of the order is one hour.
5 currencies are supported for address payment:
"USD", "USDT", "BTC", "ETH", "GT"
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"