支付宝小程序 my.tradePay 排障笔记:9000 不等于支付成功
对接支付宝小程序支付时,最容易踩的坑是把 my.tradePay 的同步返回当成支付结果。下面按返回码和入参错误分开记录。
同步返回 9000 不能判定支付成功
my.tradePay 的同步返回中:
- 订单处理成功(
resultCode 9000)。 - 不建议根据
my.tradePay接口同步返回判断是否支付成功,9000 不能判定就是支付成功。 - 正确判断依据:以异步通知(
notify_url)返回的trade_status(交易状态)为TRADE_SUCCESS,并且以alipay.trade.query接口查询订单是否支付成功实际返回的支付状态为准。
也就是说,resultCode == 9000 只代表这次调用被正常受理,最终结果要回查。
同理,正在处理中(8000)表示支付结果未知(有可能已经支付成功),需要查询商户订单列表中订单的支付状态,不能直接当作失败处理。网络连接出错时同理:处理结果未知(有可能已经成功),查商户订单列表中订单状态。
返回码对照
| 返回码 | 含义 | 处理方式 |
|---|---|---|
| 9000 | 订单处理成功 | 不能判定支付成功,以 notify_url 的 trade_status=TRADE_SUCCESS + alipay.trade.query 实际返回状态为准 |
| 8000 | 正在处理中,支付结果未知(有可能已经支付成功) | 查询商户订单列表中订单的支付状态 |
| 4000 | 订单处理失败 | 按失败处理 |
| 6001 | 用户中途取消 | 见下方 6001 排查 |
| — | 网络连接出错 | 处理结果未知(有可能已经成功),查商户订单列表中订单状态 |
参数错误、打开失败:tradeNO 与 orderStr 二选一
tradeNO 调用小程序支付时必填,orderStr 调用资金授权时必填,二选一,根据具体接入的开放能力选择参数。
小程序支付场景
- 检查入参字段
tradeNO是否编写正确,"NO"都是大写。 tradeNO的入参数据是alipay.trade.create接口返回的"trade_no",不是"out_trade_no"。
资金授权场景
orderStr必填。alipay.fund.auth.order.app.freeze接口的参数有误,会导致通过response.sdkExcute(request)方法获取到的orderStr参数有问题。检查入参字段和数据是否符合接口要求,建议只传必传参数测试,避免其他参数干扰。
6001 用户中途取消
- 请用户重新签约 / 支付。
- 检查
tradeNO的入参是否正常入参,参数数据为alipay.trade.create接口返回的"trade_no"。 alipay.trade.create接口在小程序场景中buyer_id参数必填,且入参的buyer_id(用户user_id,2088 开头)必须和前端唤起支付的支付宝账号一致。
第 3 点常被忽略:buyer_id 与唤起支付的账号不一致时,表现可能就是拉起支付后被取消。
其它请求相关错误
请求没有结束就跳转到了另一个页面
建议请求完成后再进行页面跳转,可以在页面加上对应的加载提示(如 my.showLoading)。如需强行做页面跳转,建议加上 RequestTask.abort() 中断请求任务。
无权调用该接口
没有配置请求白名单导致,需在支付宝小程序管理中心 > 设置 > 服务器域名白名单中配置。
JSON parse data error
前后端请求返回数据格式 text 与入参 dataType 值不一致;或响应内容携带了 BOM,可去除 utf-8 BOM 头。
HTTP 错误(404 / 500 / 504)
确认请求 URL 在外网可正常请求(HTTPS 协议)。真机上是线上环境正式请求,不能使用局域网本地请求;SSL 证书不正确也会导致,建议更换 SSL 证书。
小结
判断支付结果只认两条:notify_url 异步通知的 trade_status 为 TRADE_SUCCESS,以及 alipay.trade.query 查询到的实际支付状态。同步 resultCode 9000、8000 都只是调用层结果,不能作为业务发货依据。入参侧重点核对 tradeNO(来源 trade_no,大写 NO)、orderStr(资金授权必填)、buyer_id(2088 开头,与唤起支付账号一致)。
来源:支付宝技术支持中心 常见API错误码大全