跳到主要内容

3、回调

当订单处理完成后,系统会向商户配置的回调地址发送通知消息。

回调地址配置​

下单时可通过 notifyUrl 参数指定本次订单专属回调地址,该地址将覆盖商户后台配置的默认回调地址。


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

如果下单时未传入 notifyUrl,系统将回调商户后台配置的默认回调地址。 默认回调地址由商户创建时提供,并可在运营管理后台进行维护。

回调请求方式​

HTTP Method

POST

Content-Type

application/json

回调数据示例​

{
"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"
}

为满足业务发展需要,回调参数未来可能新增字段。新增字段默认参与签名计算(除签名规则中特别说明的字段外),因此商户系统应具备向前兼容能力,避免因字段扩展导致验签失败。

回调参数说明​

参数名称类型参与签名参数含义参数说明
amountdecimal是订单金额
bizTypeenum是订单类型订单类型说明如下
blockchainobject是链交易信息链上交易信息,仅当 isBlockchain=true 时返回
└networkString是主网
└receiverAddressString是接收地址
└senderAddressdecimal是发送地址
└txIdString是交易ID区块链交易哈希
└txIndexString是交易索引交易索引(批量转账场景)
currencyString是币种订单币种
keyString是商户 key
localOrderIdString是商户订单号
merchantActualAmountdecimal是商户实际收付金额
merchantCurrencyString是商户结算币种
merchantIdString是商户号
merchantPaidAmountdecimal是商户应收或应付金额
merchantUserIdString是商户用户 ID
notifyTimelong是回调时间回调通知时间
orderCreateTimelong是订单创建时间
orderIdString是订单号平台订单号(唯一)
statusString是支付状态SUCCESS 、 FAIL(说明如下)
typeString是订单类型PAYMENT 、WITHDRAW(说明如下)
userAmountdecimal是用户实收或实付金额
userCurrencyString是用户币种
userMinerFeeString是矿工费
userReceivableAmountString是用户应付或应收金额
isReissueBoolean是是否补发是否补发回调
ratestring是汇率
rateExpressionstring是汇率表达式
signString否签名值md5 签名(详情看签名算法)

status 状态说明​

状态值说明
SUCCESS已完成
FAIL已失败

type 类型说明​

类型值说明
PAYMENT支付
WITHDRAW提款

bizType 业务类型说明​

bizType说明
PAYMENT_WALLET_SCANMINPAY 钱包扫码支付
PAYMENT_TRANSFER数字货币绑定地址直充
PAYMENT_ANY_DIGITAL_SCAN数字货币任意金额扫码支付
PAYMENT_FIXED_DIGITAL_SCAN数字货币固定金额扫码支付
WITHDRAW_WALLET提现至 MINPAY 钱包
WITHDRAW_ANY_DIGITAL_WALLET提现至任意数字钱包
BATCH_PAY批量代付

回调响应要求​

商户成功处理回调后,必须返回以下内容:

success

系统收到字符串 success 后,视为回调处理成功,不再重复发送。

回调重试机制​

如果出现以下情况:

  • 未收到响应
  • 返回内容不是 success
  • HTTP 请求异常
  • 服务超时

系统将自动重试发送回调通知。

最大重试次数​

14次

重试间隔​

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

建议商户系统按照 orderId 实现幂等处理,避免因重复回调导致业务数据重复处理。

签名校验

收到回调通知后,商户必须先进行签名验证,验证通过后再执行业务逻辑。 签名算法与下单请求签名规则完全一致,请参考《2. 如何签名》。

验签流程​

  1. 获取回调参数中的 sign
  2. 从参数中移除 sign
  3. 将商户 key 放入参数
  4. 使用商户 secret 按签名规则重新计算签名
  5. 比较计算结果与回调中的 sign 是否一致

只有验签成功后,才应处理订单业务。

Java 验签示例​

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("签名验证失败");
    }
    // 业务处理逻辑
}