# 回调交易结果
# 回调接口验签
验签目的
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",
"orderActualAmount":"10.11",
"orderId":"OCURRPAID202504290257381745895458641HAMBIT-U0000000401297551",
"orderFee":"3.405",
"orderStatus":"Payment Successful",
"payParam":"QrCodePayment@q-LabgbbxFWS1G_4tiznSMUwv8yxMRz5j8_DCJdglAGsv0J_qsY975gewpUERfxcWCXzTK041R4GyqZ-_aLfOg==",
"externalOrderId":"20250429105736291833",
"payTypeName":"qrcode",
"orderAmount":"10.11",
"orderTime":1745895459000,
"payType":127,
"orderStatusCode":2,
"markStatus":0,
"orderPayTime":1745895483000
}
回调参数说明
参数名 | 类型 | 说明 |
---|---|---|
参数名 | 类型 | 说明 |
currencyType | String | 法币类型(如:BRL INR) |
orderActualAmount | String | 实际订单金额。消费者实际支付的金额,有可能与创建时的订单金额不一致,以消费者实际支付为准。 |
orderAmount | String | 订单原始金额。创建订单时发起的金额。 |
orderFee | String | 订单手续费。按照实际订单金额(orderActualAmount)进行计算。 |
orderId | String | 系统订单号 |
orderStatus | String | 订单状态描述(如 Payment success) |
payParam | String | PIX 支付字符串 |
externalOrderId | String | 商户订单号 |
tradeNote | String | 备注 |
payTypeName | String | 支付方式名称 |
orderTime | int64 | 订单创建时间(毫秒时间戳) |
payType | int64 | 支付类型 |
orderStatusCode | int64 | 订单状态码,枚举值:1、2: 1=待支付; 2=支付成功(终态) |
markStatus | int64 | 标记状态 |
orderPayTime | int64 | 实际支付时间(毫秒时间戳) |
errorMsg | String | 错误信息(可选) |
Tips:手动回调机制说明
商户可在任何时间登录商户后台,手动触发订单回调。
注意事项:
- 请勿在订单未处于终态(如:未支付、处理中)时手动触发回调,以免造成业务逻辑异常。
- 手动回调的返回数据中,订单状态信息为当前实际状态,请在业务侧根据状态判断是否进行处理。
- 若订单尚未处于终态(如状态为处理中),平台在订单状态变更为终态后仍会再次主动发起通知,商户应做好业务冗余处理,确保幂等性,避免重复入账或通知冲突。
- 若订单已经是终态,在商户后台点击手动回调(不建议),平台还会再次发起通知,商户应做好业务冗余处理,确保幂等性,避免重复入账或通知冲突。
# 回调响应
说明
- 所有回调均包含签名字段,建议商户务必对回调进行验签,确保回调内容未被篡改。
- 商户在收到回调数据并处理完成后,需以 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)或无响应,则判定为失败,平台将自动进行重试推送。