报错OUT_TRADE_NO_USED,到底在说啥
微信支付提示“商户订单号重复(OUT_TRADE_NO_USED)”,常见原因不是你真“重复下单”了,而是你用同一个out_trade_no多次调“下单/统一下单”,但请求参数有变化。比如上次是1.00元,这次改成0.99元,或body、attach、notify_url、金额、商品信息里有任意一项不一致,就会被判定为“同号不同单”。
还有一种高频场景:用户取消支付后立刻再点一次;或网络超时你做了重试,但重试包体被改了。
订单号怎么生成才稳:规则+示例
建议把out_trade_no当成“你系统里的支付单号”,要求是同一个商户号下唯一,并且长度别超过32位(尽量用数字字母组合,别塞中文和特殊符号)。
- 推荐结构:业务前缀 + 20260211日期 + 秒级时间 + 6位随机数
- 示例:PAY20260211195830A1B2C3(短、可读、冲突概率低)
- 别踩坑:只用“时间戳到秒”很危险,高并发1秒内就撞号
真实案例:某店铺在19:58同一秒创建了20笔订单,只用“20260211195830”当单号,直接20笔全报重复。
幂等重试怎么做:同单号就别乱改参数
你要的效果是:网络抖一下,重试也不会生成新账,也不会报错。
- 超时/无响应重试:继续用同一个out_trade_no,并且body、金额、商品明细、notify_url等保持完全一致
- 确实要改价/改内容:别复用旧单号,立刻换一个新的out_trade_no,再发起下单
- 用户取消后再支付:如果你业务上还是同一笔待支付订单,就用同一个out_trade_no,并确保请求字段不变
遇到重复报错时,订单状态核对教程
别急着换单号,先查这笔单到底在微信那边是什么状态。用“查询订单”接口按out_trade_no查一次:
- 查到SUCCESS:说明已支付,直接走发货/入账,别再发起支付
- 查到NOTPAY:说明未支付,允许用户继续支付,但要保证下单参数一致
- 查不到:多半是你上次下单根本没成功,换新单号再下单更省心
可执行建议:
- 把out_trade_no生成改成“日期+毫秒/随机数”,并做数据库唯一索引
- 支付下单接口加幂等:同out_trade_no重复请求直接返回同一支付参数
- 收到OUT_TRADE_NO_USED时,自动触发一次“订单查询”,再决定复用还是换新单号