Skip to main content

3- 3. Callback

When the order is processed, the system will send a notification message to the callback address configured by the merchant.

Callback address configuration

When placing an order, you can specify the exclusive callback address for this order through the notifyUrl parameter. This address will override the default callback address configured in the merchant's backend.


param.put("notifyUrl", "http://{domain}/callback/notifyUrl");

If notifyUrl is not entered when placing an order, the system will call back the default callback address configured in the merchant's backend. The default callback address is provided by the merchant when it is created and can be maintained in the operation management background.

Callback request method

HTTP Method

POST

Content-Type

application/json

Callback data example

{
"amount": "100",
"bizType": "WITHDRAW_ANY_DIGITAL_WALLET",
"blockchain": {
"network": "TRON",
"receiverAddress": "THcJ2FeNBkuzd4PZBpRans6tx9QGg9KHRt",
"senderAddress": "TE35TrUfHjbGEBsVS6zVXdHS8HxXCWwC2y",
"txIndex": "2",
"txId": "d848e4b62ec6925b8b3ff49dbc4d839f3f88508497c3af525f0c8293cb303ab3"
},
"currency": "CNY",
"localOrderId": "TestOTM0625ROB016",
"merchantActualAmount": "138.12",
"merchantCurrency": "CNY",
"merchantId": 302992856974,
"merchantPaidAmount": "100",
"notifyTime": 1772173006425,
"orderCreateTime": 1772172958082,
"orderId": "472515854147845",
"status": "SUCCESS",
"type": "WITHDRAW",
"userAmount": "14.971722",
"userCurrency": "USDT",
"userMinerFee": "0",
"isReissue": false,
"userReceivableAmount": "14.971722",
"rate": "6.71080951",
"rateExpression": "1USDT≈6.7108CNY",
"sign": "2c27c7e8184cc709a64ad502ee42eab7",
"key": "9yUreYgTRtit39Dy"
}

**To meet business development needs, callback parameters may add new fields in the future. The newly added fields participate in signature calculation by default (except for the fields specifically stated in the signature rules). Therefore, the merchant system should have forward compatibility to avoid signature verification failure due to field expansion. **

Callback parameter description

Parameter nameTypeParticipating signatureParameter meaningParameter description
amountdecimalYesOrder Amount
bizTypeenumYesOrder typeOrder type description is as follows
blockchainobjectYesChain transaction informationOn-chain transaction information, returned only when isBlockchain=true
└networkStringYesMainnet
└receiverAddressStringYesReceiver Address
└senderAddressdecimalYesSending Address
└txIdStringYesTransaction IDBlockchain transaction hash
└txIndexStringYesTransaction IndexTransaction Index (batch transfer scenario)
currencyStringYesCurrencyOrder Currency
keyStringYesMerchant key
localOrderIdStringYesMerchant order number
merchantActualAmountdecimalYesMerchant’s actual payment amount
merchantCurrencyStringYesMerchant settlement currency
merchantIdStringYesMerchant ID
merchantPaidAmountdecimalYesAmount receivable or payable by the merchant
merchantUserIdStringYesMerchant User ID
notifyTimelongYesCallback timeCallback notification time
orderCreateTimelongYesOrder Creation Time
orderIdStringYesOrder numberPlatform order number (unique)
statusStringYesPayment statusSUCCESS, FAIL (description below)
typeStringYesOrder typePAYMENT, WITHDRAW (description below)
userAmountdecimalYesThe amount actually received or paid by the user
userCurrencyStringYesUser currency
userMinerFeeStringYesMining fee
userReceivableAmountStringYesAmount payable or receivable by the user
isReissueBooleanYesWhether to reissueWhether to reissue callback
ratestringYesExchange Rate
rateExpressionstringYesExchange rate expression
signStringNoSignature valuemd5 signature (see signature algorithm for details)

status status description

Status ValueDescription
SUCCESSCompleted
FAILFailed

type type description

Type ValueDescription
PAYMENTPayment
WITHDRAWWithdrawal

bizType business type description

bizTypeDescription
PAYMENT_WALLET_SCANVPAY wallet scan code to pay
PAYMENT_TRANSFERDigital currency binding address direct deposit
PAYMENT_ANY_DIGITAL_SCANScan the QR code to pay any amount of digital currency
PAYMENT_FIXED_DIGITAL_SCANDigital currency fixed amount scan code payment
WITHDRAW_WALLETWithdraw to VPAY wallet
WITHDRAW_ANY_DIGITAL_WALLETWithdraw to any digital wallet
BATCH_PAYBatch payment

Callback response requirements

After the merchant successfully handles the callback, the following content must be returned:

success

After the system receives the string success, it is deemed that the callback processing is successful and will not be sent again.

Callback retry mechanism

If:

  • No response received
  • The returned content is not success
  • HTTP request exception
  • Service timeout

The system will automatically retry sending the callback notification.

Maximum number of retries

14次

Retry interval

15s
15s
30s
180s
600s
1200s
1800s
1800s
1800s
3600s
10800s
10800s
21600s
21600s

It is recommended that the merchant system implements idempotent processing according to orderId to avoid repeated processing of business data due to repeated callbacks.

Signature Verification

After receiving the callback notification, the merchant must first perform signature verification, and then execute the business logic after passing the verification. The signature algorithm is completely consistent with the order request signature rules. Please refer to "2. How to Sign".

Signature Verification Process

  1. Get sign in the callback parameter
  2. Remove sign from parameters
  3. Put the merchant key into the parameters
  4. Use merchant secret to recalculate signature according to signature rules
  5. Compare whether the calculation result is consistent with sign in the callback

Only after the signature verification is successful, the order business should be processed.

Java signature verification example

public void notify(JSONObject data) {

    log.info("收到回调通知:{}", data.toJSONString());

    String key = "your_key";
    String secret = "your_secret";
   
    String sign = data.getString("sign");

    data.put("key", key);
    data.remove("sign");
   
    String calculatedSign = SignUtils.getSign(data, secret);

    if (!calculatedSign.equals(sign)) {
        throw new DxBizException("签名验证失败");
    }
    // 业务处理逻辑
}