代收退款结果回调通知接口文档
1. 通知接口背景
合作商发起代收退款申请后,退款结果可能无法在同步请求中确定。Adopay 在退款成功或失败后,通过 HTTP 异步回调将退款最终结果通知给合作商。
同一笔退款订单可能因重试收到多次通知。
2. 回调地址和请求方式
| 项目 | 内容 |
|---|---|
| 请求方式 | POST |
| 请求地址 | {cashinRefundNotificationUrl} |
| Content-Type | application/json |
| 接口用途 | 通知代收退款最终结果 |
{cashinRefundNotificationUrl} 优先使用合作商发起退款时上送的 notifyUrl;未上送时,使用合作商已配置且启用的退款通知地址。回调地址必须是完整的 HTTP 或 HTTPS 地址。
3. 请求头字段
| 字段名 | 类型 | 是否必传 | 说明 |
|---|---|---|---|
Content-Type | string | 是 | 固定为 application/json。 |
X-Merchant-Id | string | 是 | 接收通知的一级商户号。 |
X-Timestamp | string | 是 | Unix 秒级时间戳。 |
X-Nonce | string | 是 | 本次请求的随机串,用于防重放;每次重试重新生成。 |
Digest | string | 是 | 原始请求体摘要,格式为 SHA-256=<Base64(SHA256(body_bytes))>。 |
Authorization | string | 是 | ES256 HTTP Signature 签名信息。 |
Digest 和 Authorization 均基于最终发送的原始 JSON 字节计算。合作商验签时不能先对 JSON 重新序列化。
4. 请求体字段
业务状态判断:status 为整数;status = 200 表示业务正常,此时 msg = "sucesso"。非 200 表示业务错误,错误原因见 msg。
| 字段名 | 类型 | 字段长度 | 是否必返 | 说明 |
|---|---|---|---|---|
event | string | 32 | 是 | 退款事件类型,具体取值取决于退款结果,见下方退款事件和状态说明。 |
subMerchantNo | string | 64 | 是 | 二级商户号。 |
attach | string | 128 | 是 | 原收款订单下单时合作商传入的 attach 值;下单时已传入则原样返回,未传入则为空。 |
merchantOrderNo | string | 64 | 是 | 合作商发起退款时传入的商户退款订单号。 |
platOrderNo | string | 64 | 是 | Adopay 平台退款订单号。 |
origMerchantOrderNo | string | 64 | 是 | 原商户代收订单号。 |
origPlatOrderNo | string | 64 | 是 | 原 Adopay 代收平台订单号。 |
origAmount | decimal(25,2) | 25,2 | 是 | 原代收订单金额 |
origTotalRefundAmount | decimal(25,2) | 25,2 | 是 | 截至本次退款处理完成时,原代收订单累计成功退还的本金金额,不包含手续费。 |
origTotalFeeRefundAmount | decimal(25,2) | 25,2 | 是 | 截至本次退款处理完成时,原代收订单累计成功退还的手续费金额,不包含退款本金。 |
amount | decimal(25,2) | 25,2 | 是 | 本次申请退还的本金金额,不包含手续费。 |
refundAmount | decimal(25,2) | 25,2 | 是 | 本次成功退还的本金金额,不包含手续费;本次退还的手续费见 feeRefundAmount。 |
feeRefundAmount | decimal(25,2) | 25,2 | 是 | 本次退款退还的手续费金额;未退还手续费时为 0。 |
currency | string | 3 | 是 | 退款币种,与原订单币种一致,例如 BRL。 |
e2eId | string | 64 | 否 | Pix 端到端交易 ID;渠道未返回时可为空。 |
orderStatus | string | 16 | 是 | 退款结果:SUCCESS 表示退款成功,FAILED 表示退款失败。 |
refundTime | int | 19 | 否 | 退款时间,Unix 秒级时间戳。 |
status | int | - | 是 | 响应码 |
msg | string | 128 | 是 | 与 status 对应 |
退款事件和状态说明
event | orderStatus | 含义 |
|---|---|---|
QR_CODE_COPY_AND_PASTE_REFUNDED | SUCCESS | pix二维码代收/收单-退款成功。 |
QR_CODE_COPY_AND_PASTE_REFUNDED_ERROR | FAILED | pix二维码代收/收单-退款失败。 |
回调仅通知退款终态。退款仍处于 PENDING 时不发送结果通知,合作商可通过退款订单查询接口获取当前状态。
5. 请求示例
以下示例为原订单首次退款成功:退还本金 50.00、手续费 0.30,累计退款本金为 50.00,累计退还的手续费为 0.30。
POST /notify/adopay/cashin/refund HTTP/1.1
Host: merchant.example.com
Content-Type: application/json
X-Merchant-Id: 92315566000120
X-Timestamp: 1786838460
X-Nonce: 4de901987ca14b25acf2639056ac6002
Digest: SHA-256=<REQUEST_BODY_SHA256_BASE64>
Authorization: Signature keyId="v1",alg="ES256",headers="(request-target) x-timestamp x-nonce digest",signature="<ES256_SIGNATURE_BASE64>"
{
"status": 200,
"msg": "sucesso",
"event": "QR_CODE_COPY_AND_PASTE_REFUNDED",
"subMerchantNo": "SUB00000001",
"attach": "order-source=checkout",
"merchantOrderNo": "REFUND202608160001",
"platOrderNo": "RFD202608160000000001",
"origMerchantOrderNo": "CASHIN202608160001",
"origPlatOrderNo": "BAS202608160000000001",
"origAmount": 100.00,
"origTotalRefundAmount": 50.00,
"origTotalFeeRefundAmount": 0.30,
"amount": 50.00,
"refundAmount": 50.00,
"feeRefundAmount": 0.30,
"currency": "BRL",
"e2eId": "E1234567820260816000000000000001",
"orderStatus": "SUCCESS",
"refundTime": 1786887025
}6. 合作商响应要求
合作商完成验签、幂等处理和业务数据落库后,应返回 HTTP 200—299,且响应体严格为纯文本 SUCCESS 或 OK:
HTTP/1.1 200 OK
Content-Type: text/plain
SUCCESS7. 通知场景与重试次数
代收退款成功或退款失败时,Adopay 会向合作商发送回调通知。
每笔通知首次发送失败后,最多重试 9 次,合计最多发送 10 次。合作商成功接收并返回规定的成功响应后,不再重试。
是否重试由 HTTP 状态码和响应体共同决定:
| HTTP 状态码 | 响应体 | 处理结果 |
|---|---|---|
200—299 | 去除首尾空白后严格等于 SUCCESS 或 OK | 通知成功,不再重试 |
200—299 | 空响应体、JSON、其他文本或非规定大小写 | 通知失败,继续重试 |
非 2xx | 任意内容 | 通知失败,继续重试 |
| 未收到 HTTP 响应 | 网络超时或连接失败 | 通知失败,继续重试 |
SUCCESS 和 OK 区分大小写。例如 success、Success 或 {"status":"SUCCESS"} 均不会被识别为成功响应。HTTP 204 虽属于 2xx,但因响应体为空,仍会继续重试。
X-Timestamp、X-Nonce、Digest 和 Authorization 按本次发送重新生成。
8. 接入注意事项
- 建议使用 一级商户号 + 商户退款订单号,或
platOrderNo作为等价唯一键;不能根据通知次数判断是否重复。 - 合作商应先完成验签,再校验一级商户号、二级商户号、原订单号、退款订单号、币种及金额,全部一致后才能更新退款结果。
e2eId及订单号应纳入审计记录;涉及商户、付款人或渠道的敏感信息时,日志中应脱敏或只记录摘要。- 验签、幂等处理和业务数据落库全部成功后再返回规定的成功响应,避免通知被错误确认后无法重试。