# 回调交易结果
# 回调接口验签
验签目的
API 请求在通过公网传输过程中,有被中间人篡改的风险。为确保回调数据的完整性与可信性,平台支持并强烈建议商户在接收回调时进行签名验签。
设置方式
登录【收银台后台】→【开发者中心】→【回调地址】→ 添加/编辑。
验签步骤
验签逻辑与接口请求签名大体一致,区别在于数据来源为接收到的回调内容。
- 获取签名
从 HTTP 请求 Header 中读取签名字段:
sign: {平台生成的签名字符串}
- 获取回调参数体
将回调 Body 中的 JSON 参数以 key-value 形式存入一个 Map(字典)结构中。
- 添加公共参数
从 Header 中再取出以下字段,并一并加入 Map 中参与验签:
access_key
timestamp
nonce
- 构造待签名字符串
将 Map 中的所有 key 按照 ASCII 字典序从小到大排序,并拼接为如下格式的字符串:
key1=value1&key2=value2&...&keyN=valueN
- 执行签名计算
使用商户后台绑定的 secret_key
对上述字符串进行以下处理:
- 使用
HMAC_SHA1
算法加密 - 将结果进行
Base64
编码,得到本地sign
值
- 比对签名
将本地生成的 sign
与 Header 中平台传来的 sign
进行比对:
- ✅ 一致 → 验签通过,可处理业务逻辑
- ❌ 不一致 → 拒绝处理,建议记录日志以供排查
# 兑换回调
当兑换订单进入终态(如成功、失败)后,平台将向商户预设的 notifyUrl
发送如下回调数据。
回调数据示例
{
"currencyType":"INR",
"orderId":"OCURREXCH202505080800451746691245254HAMBIT-U0000000201298031",
"tokenAmount":"1.193602291716400095",
"currencyAmount":"100",
"orderFee":"0.014084507042253522",
"remark":"test",
"chainType":"BSC",
"externalOrderId":"20250508160039180270",
"orderEntryAmount":"1.179517784674146573",
"addressTo":"0xa8666442fA7583F783a169CC9F5449ec660295E8",
"orderCompleteTime":1746691310000,
"orderAmount":"100",
"exchangeRate":"83.78",
"notifyUrl":"https://tofficeapi.hambit.co/api/v1/hambit/hambit-api/test/testNotifySuccess",
"tokenType":"USDT",
"exSymbolType":602
}
回调参数说明
参数名 | 类型 | 说明 |
---|---|---|
currencyType | String | 法币类型 BRL,INR |
orderId | String | 订单ID |
tokenAmount | String | 代币数量 |
currencyAmount | String | 法币金额 |
orderFee | String | 交易手续费(手续费将从结算金额中扣除) |
remark | String | 订单备注 |
chainType | String | 区块链类型 |
externalOrderId | String | 商户订单ID |
orderEntryAmount | String | 实际收到金额(实际收到金额=换算将收到金额-手续费) |
addressTo | String | 收款地址 |
orderCompleteTime | int | 订单完成时间 |
orderAmount | String | 订单金额 |
exchangeRate | String | 汇率 |
notifyUrl | String | 回调URL |
tokenType | String | 代币类型 |
exSymbolType | int | 交易类型(601 表示加密货币转法币,602 表示法币转加密货币) |
# 回调响应
说明
- 所有回调均包含签名字段,建议商户务必对回调进行验签,确保回调内容未被篡改。
- 商户在收到回调数据并处理完成后,需以 JSON格式 响应网关如下数据:
示例响应(成功)
{
"code": 200,
"success": true
}
回调补发机制说明(重要)🔥
为确保回调通知的稳定送达与业务一致性,平台设计了多次重试策略。当商户系统未能成功响应回调时(如网络超时、返回非200状态码等),系统将按以下规则进行回调补发:
回调重试节奏(共 4 次):
尝试次数 | 间隔时间(约) | 说明 |
---|---|---|
第 1 次 | 约 2 分钟后 | 首次失败后触发第一次重试 |
第 2 次 | 约 2 分钟后 | 第一次重试失败后触发第二次重试 |
第 3 次 | 再约 11分钟后 | 第二次重试失败后再次重试 |
第 4 次 | 再约 2分钟后 | 第三次重试失败后进入下一次重试 |
注意:以上间隔时间为系统内部调度间隔,商户后台所记录的“回调时间”包含了商户处理/响应时间,因此显示上可能与实际推送时间存在 1 分钟左右误差。
实际情况提醒
- 当线上订单量较大时,回调可能存在队列延迟,请确保服务端支持高并发处理能力;
- 每次回调均为幂等操作,建议商户侧务必支持幂等判断;
- 最多 4 次重试推送仍失败后,则不再自动重试,建议通过后台手动触发回调。
回调响应参数
Param | Type | Required | Description |
---|---|---|---|
code | int | ✅ | 状态码,成功为 200 |
success | boolean | ✅ | 响应是否成功 |
# 回调通知 URL 配置
支持两种通知地址配置方式:
- 【商户后台】配置统一回调地址
- 可在「商户后台」→「开发者中心」中配置。
- 适用于大部分订单共用的回调处理逻辑。
2.订单级别手动指定回调地址(notifyUrl)
- 在创建订单接口中可传
notifyUrl
字段。 - 若订单中指定了
notifyUrl
参数,则系统将仅使用该地址作为回调通知目标地址。
地址优先级说明
订单中的 notifyUrl
优先级高于统一配置的回调地址。
响应状态码优先级说明
平台以 HTTP 响应状态码 (**status_code
**) 是否为 200
作为通知是否成功的唯一判断标准。
具体规则如下:
- ✅ 只要商户系统返回
HTTP 200
**,平台即认为回调成功**- 此时即使返回内容不是
{ "code": 200, "success": true }
也会被忽略。
- 此时即使返回内容不是
- ❌ 如果返回
status_code ≠ 200
(如 400/500)或无响应,则判定为失败,平台将自动进行重试推送。