XD-OP-08 · DOC
退款与对账
退款按业务单号幂等、按原订单冻结的收款分配快照发起回退;实际到账路径以支付服务方原交易与分账合同为准。本篇给出状态机、补偿与对账骨架。
小豆支付开放平台是面向已有自有系统的商家的支付接入服务:通过服务器对服务器的接口,把支付宝与微信收款接进商家自己的系统,并以签名事件通知回传支付状态;资金由持牌支付公司收付结算。个人也能申请:主体类型选「个人」,身份证 + 本人银行卡即可完成商户进件。央行持牌机构清算,安全可靠的个人和企业支付接口。
1. 退款接口
POST <BASE_URL>/api/open/v1/refunds
{
"outTradeNo": "SHOP20260926A0001",
"outRefundNo": "RF20260926A0001",
"refundAmountFen": 100,
"reason": "买家申请"
}| 项 | 规则 |
|---|---|
| 可退前提 | 仅支付成功的订单可退 |
| 金额 | 累计退款不得超过实付金额;失败的退款不占额度;超限返回 422 OPEN_API_LIMIT_EXCEEDED |
| 幂等 | 同 outRefundNo 同内容 → 200 幂等重放;同号异内容 → 409 |
| 受理后被拒 | 502(支付机构拒绝,平台不向外暴露内部原因) |
| 结果不确定 | 状态 UNKNOWN,不判死,等事件收敛(见 §2) |
退款状态:REQUESTED → PENDING → SUCCEEDED / FAILED(另有 UNKNOWN)。
一个容易踩的
409:退款按下单时冻结的收款分配快照发起回退(实际到账路径以支付服务方原交易与分账合同为准),因此前提是该单有可用的快照。缺少快照(历史单或异常单)时,创建退款返回409OPEN_API_STATE_INVALID——这表示该单不能自助退款,请带outTradeNo与requestId走官网反馈渠道人工处置,不要换号重试。
请只用查询退款接口和自己库里记录的 outRefundNo 判退款最终结果——不要用「发起退款后等待固定时长」这种猜测式判断。
2. 结果不确定(UNKNOWN)时的正确姿势
UNKNOWN 表示「平台与支付机构之间的结果暂时不可知」。正确处理是查证收敛,不是重做动作:
退款 UNKNOWN
├─ 等 REFUND_SUCCEEDED / REFUND_FAILED 事件(唯一自动收敛路径)
├─ 调 GET /api/open/v1/refunds/{outRefundNo} 看当前状态(本地权威读:不会触发外呼、也不会改变状态)
└─ 长时间仍 UNKNOWN → 把该笔挂到「待核」队列,带 outRefundNo + requestId 走官网反馈人工介入
❌ 不要用新的 outRefundNo 再退一次(可能造成重复退款)
❌ 不要把 UNKNOWN 当失败直接回滚交付(可能钱已退)别指望「反复查单」把状态查出来:查询接口是平台本地账本的只读投影,它不会去问支付机构——
UNKNOWN的收敛只发生在支付机构回通知时。人工兜底是最终手段。
订单侧同理:订单 UNKNOWN 时不要重新下单、不要判失败。
3. 对账
最小对账闭环(建议每日跑一次):
- 拉你自己的流水:以你的库为准(订单号、金额、状态)。
- 拉平台侧:逐笔
GET /api/open/v1/payments/{outTradeNo}与GET /api/open/v1/refunds/{outRefundNo}。 - 对齐三类差异:
| 差异 | 处置 |
|---|---|
| 平台成功、你这边未成功 | 你的事件消费漏了 → 按事件 eventId 补齐落账(这就是为什么要接事件 + 查单双路径) |
| 你这边成功、平台未成功 | 你的落账提前了 → 这是误判终态(多半把回跳/页面状态当成了终态),把交付动作回退到「以查单为准」 |
| 金额/费率不一致 | 用该笔的 feeProjection(含 ruleVersion)核对,不要用你库里的费率表 |
ruleVersion对齐:若同一批订单的ruleVersion出现变化,说明期间发生过配置变更——按逐笔口径对,不要按批次统一算。但它只是全局配置版本:平台对单个商家调价不会改变它,所以逐笔核对要以该笔的merchantRateBps/companyServiceFeeRateBps为准,不能只看版本号有没有变。
4. 结算读回
- 逐笔结算状态看门户「资金 / 结算」页(逐笔清单支持翻页);到账周期与口径以门户生效配置为准(见 费率与限额)。
- 对账发现「平台已结算、你未入账」时:先看该笔订单的渠道与结算状态,再带着
outTradeNo+requestId走官网反馈渠道。
5. 退款常见误区
- 用新的
outRefundNo重试UNKNOWN的退款 → 重复退款。 - 把
502直接当成「没退成功」 → 要先查退款状态再决定,502只代表「本次请求被拒」。 - 按「发起时间 + 固定时长」判断到账 → 结算周期与渠道相关,会变。
- 对已关闭/已失败订单发退款 →
409/422,先查单确认订单状态。
内容源:
open-platform/docs/08-refund-and-reconciliation.md · 最后更新 2026-10-17
下载本文 .md
在 GitHub 查看