Skip to main content

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_SCANVPAY 钱包扫码支付
PAYMENT_TRANSFER数字货币绑定地址直充
PAYMENT_ANY_DIGITAL_SCAN数字货币任意金额扫码支付
PAYMENT_FIXED_DIGITAL_SCAN数字货币固定金额扫码支付
WITHDRAW_WALLET提现至 VPAY 钱包
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("签名验证失败");
    }
    // 业务处理逻辑
}