支付回调
支付成功后,网关向商户配置的回调地址发送 POST 请求。回调是入账的唯一依据。 用户可能付完款就关掉页面,所以页面跳转、前端轮询结果都不能用来入账。
接收回调
各框架取原始请求体的方式:Express 用 express.raw()(并且不要全局挂 express.json(),
会提前吃掉原文),Koa 用 raw-body,FastAPI 用 await request.body(),
Next.js App Router 用 await request.text(),Nest 开启 rawBody: true。
处理步骤
- 验签。
verify抛错时返回 400,不处理业务 - 核对金额。事件里的
amount必须与本地订单金额一致 - 幂等入账。以
out_trade_no建唯一约束,重复回调直接返回 200 - 返回 200。耗时逻辑先落库再异步处理,不要让回调等待
事件类型
订单关闭不推送回调,需要时用查单接口获取。收到 refund.failed 表示这笔退款不会到账,
处理方式见查单与退款。
重试机制
回调返回非 2xx 或 10 秒超时,网关按 1 分钟、5 分钟、10 分钟、30 分钟、1 小时、 3 小时、6 小时、12 小时的间隔重试,共 8 次。
这意味着同一事件一定会重复送达,入账幂等不是可选项。全部重试失败的事件顽兔侧 会告警处理,商户也可以随时用查单接口核对状态。
验签规则
用 SDK 时不需要关心本节。自行验签的参考:
- 请求头:
X-Wantu-Timestamp(秒级时间戳)、X-Wantu-Nonce、X-Wantu-Signature - 签名串三行拼接:
timestamp + "\n" + nonce + "\n" + 请求体原文 - 算法:HMAC-SHA256,输出 hex 小写
- 密钥:配置了
webhook_secret用它,否则用api_secret - 时间戳与当前时间相差超过 300 秒应拒绝