支付请求重试必须确保幂等性,核心是服务端用唯一业务ID(如pay_id)识别并拒绝重复执行;需数据库唯一索引或Redis缓存校验状态,前端重试须复用原ID、区分错误类型并配合退避机制,且必须通过回调、轮询等方式异步确认最终结果。

支付请求重试必须确保幂等性,否则重复扣款会直接引发资损。核心思路是:服务端识别重复请求并拒绝执行,而非靠客户端“不重试”来规避问题。
使用唯一业务 ID(如 pay_id 或 out_trade_no)作为幂等键
每次发起支付请求时,客户端生成一个全局唯一、可追溯的业务标识(推荐用 UUID 或雪花 ID),并随请求一起提交给服务端。服务端在处理前先检查该 ID 是否已存在成功记录:
- 若已存在且状态为
success,直接返回原结果(含订单号、支付单号等),不走支付通道 - 若存在但状态为
processing或failed,可选择等待查证或允许重试(需结合状态机设计) - 若不存在,则正常执行支付,并持久化该 ID 与初始状态
服务端需配合实现幂等控制逻辑
仅靠前端生成 ID 不够,关键在服务端落地保障。常见做法包括:
- 在数据库中对
pay_id建立唯一索引,插入前尝试写入(或用 INSERT ... ON CONFLICT DO NOTHING) - 用 Redis 缓存
pay_id → status映射,设置合理过期时间(如 24 小时),兼顾性能与一致性 - 状态更新需原子化:例如用 UPDATE ... WHERE pay_id = ? AND status = 'init' 设置为 'processing',避免并发重复发起
前端重试策略要配合幂等设计,不破坏语义
JavaScript 中的重试不应盲目轮询,而应关注可恢复错误,并保留原始业务 ID:
立即学习“Java免费学习笔记(深入)”;
- 只对网络超时、502/504 等临时性错误重试;400、409、422 等明确失败码不重试
- 重试时复用首次生成的
pay_id,绝不重新生成 - 建议加入退避机制(如指数退避),避免瞬间重压;同时设置最大重试次数(如 3 次)
- 最终失败时,引导用户进入支付结果查询流程(通过
pay_id主动轮询或监听回调)
补充:异步结果确认不可省略
即使请求返回成功,也不代表资金已到账。真实支付链路常有延迟,必须依赖:
- 服务端主动回调(如微信/支付宝 notify)
- 前端定时轮询支付结果接口(传
pay_id查询) - 用户主动跳转至“我的订单”页刷新状态
所有这些路径都依赖同一个幂等 ID 关联上下文,确保状态最终一致。


















