支付宝信用借订单支付报错:外部订单号重复
2022-03-01 更新
通过最近收到的反馈,分析得到了支付宝信用借支付报错 ACQ.DUP_OUT_ORDER 外部订单号重复
的原因:商户订单号(外部订单号)相同而支付参数 subject
不相同,导致支付宝将后面提交的支付参数当成了新的请求,而新的请求商户订单号验证失败了。
支付宝统一收单交易支付接口 甚至都没有显示这个错误码,显然这个错误相当罕见。
结合收到的反馈,自动售出时出现用户账户余额不足、扣款失败的情况,在后台重新发起支付(支付宝支付接口重复提交)时多次出现这种 [外部订单号重复] 的提示信息。而正常的订单借用待支付重新发起支付就没有这种提示信息,猜测两种情况下存在参数差异导致报错,而非订单号本身重复的问题。
对比发现:正常订单借用支付参数中实例参数 $this->body
值与重新支付时参数一致,与自动售出支付参数不相同:
$request->setBizContent("{" .
"\"auth_no\":\"{$auth_no}\"," .
"\"out_trade_no\":\"{$out_order_no}\"," .
"\"product_code\":\"PRE_AUTH_ONLINE\"," .
"\"total_amount\":{$this->alipayMoney}," .
"\"buyer_id\":\"{$this->user_id}\"," .
"\"seller_id\":\"{$seller_id}\"," .
"\"subject\":\"{$this->body}\"," .
"\"body\":\"{$this->body}\"," .
"\"auth_confirm_mode\":\"COMPLETE\"" .
"}");
对比 API 接口请求参数,body
不需要,需要的是 subject
订单标题。所以需要确保支付时的 subject
与重新支付时的参数保持一致。可以将 subject
作为新增字段放到 [支付宝信用单] 表中,之后重新支付时取出填充。但个人感觉不需要那么麻烦,直接将 subject
设置成固定值即可。
修改后的 bizContent
:
$this->subject = 'xxxx';
$request->setBizContent("{" .
"\"auth_no\":\"{$auth_no}\"," .
"\"out_trade_no\":\"{$out_order_no}\"," .
"\"product_code\":\"PRE_AUTH_ONLINE\"," .
"\"total_amount\":{$this->alipayMoney}," .
"\"buyer_id\":\"{$this->user_id}\"," .
"\"seller_id\":\"{$seller_id}\"," .
"\"subject\":\"{$this->subject}\"," .
"\"auth_confirm_mode\":\"COMPLETE\"" .
"}");
在整理历史支付中的订单时,对现有已授权(Authorized)信用单再次支付报错:外部订单号重复
。
这可能是之前测试提交过相同的订单,即当前提交的 out_order_no 已经存在了。这个也好解决,存在了换一个就是了,修改当前订单号在末尾加上一位自定义字符即可。
还遇到了 交易已存在且与本次请求的订单金额不一致
。这种是第一次提交支付失败了,第二次再次提交,提交的金额与第一次尝试支付的金额不一致导致的。这种情况一般不会出现,这边测试提交金额是否可以修改手动更改的。如果实在不记得第一次的支付金额,也可以尝试解冻订单或撤销,未测试是否可以成功。
本作品采用 知识共享署名-相同方式共享 4.0 国际许可协议 进行许可。