fix(order-pay): 解决支付宝冻结订单重复发起问题

- 已存在 SUCCESS 冻结记录时清空旧 orderStr,避免前端重复调起
- 查询支付宝实际冻结状态,避免同一订单重复发起冻结操作
- 同步本地冻结记录状态,提升本地和支付宝状态一致性
- 日志中增加冻结查询和发起的详细记录,便于排查问题
- 捕获查询和冻结调用异常,防止流程中断并给出友好提示
This commit is contained in:
2026-08-24 12:20:45 +08:00
parent 5c4ccec4f7
commit 92e3ec97e5
@@ -9,6 +9,7 @@ import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.IdUtil; import cn.hutool.core.util.IdUtil;
import cn.hutool.core.util.StrUtil; import cn.hutool.core.util.StrUtil;
import com.alipay.api.AlipayApiException; import com.alipay.api.AlipayApiException;
import com.alipay.api.response.AlipayFundAuthOperationDetailQueryResponse;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper; import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers; import com.baomidou.mybatisplus.core.toolkit.Wrappers;
@@ -216,19 +217,53 @@ public class OrderPayController extends BaseController {
if (cnt > 0) { if (cnt > 0) {
log.info("订单{}已支付支付押金!", orderId); log.info("订单{}已支付支付押金!", orderId);
one.setHasFreeze(1); one.setHasFreeze(1);
// 已存在 SUCCESS 冻结记录,清空旧 orderStr,避免前端用同一笔 orderStr 重复调起
// 支付宝收银台报“订单冻结已成功,请勿重复操作。”
one.setOrderStr(null);
} else { } else {
log.info("订单{}未支付押金!", orderId); log.info("订单{}未支付押金!", orderId);
// fWrapper.clear(); // 冻结已发起但本地未确认时,先查支付宝实际冻结状态,避免用同一
// fWrapper.eq(FreezeOrder::getOutOrderNo, freezeOrderNo) // out_order_no/out_request_no 重复发起冻结,触发支付宝端“订单冻结已成功,请勿重复操作。”提示
// .eq(FreezeOrder::getStatus, "INIT"); boolean frozenAtAlipay = false;
// boolean delRet = freezeOrderService.remove(fWrapper); long initCnt = freezeOrderService.lambdaQuery()
try { .eq(FreezeOrder::getOutOrderNo, freezeOrderNo)
String orderStr = freezeOrderService.freeze(order, eg); .eq(FreezeOrder::getStatus, "INIT")
one.setOrderStr(orderStr); .count();
log.info("订单{}支付请求参数:{}", orderId, orderStr); if (initCnt > 0) {
} catch (AlipayApiException e) { try {
log.error(e.getMessage(), e); AlipayFundAuthOperationDetailQueryResponse queryResp = freezeOrderService.query(order);
return fail("调用芝麻信用出错!"); if (queryResp.isSuccess() && "SUCCESS".equals(queryResp.getStatus())
&& ("FINISH".equals(queryResp.getOrderStatus())
|| "AUTHORIZED".equals(queryResp.getOrderStatus()))) {
order.setIsFreeze(1);
order.setIsCreditAuth("CREDIT_AUTH".equals(queryResp.getPreAuthType()) ? 1 : 2);
orderService.updateById(order);
// 同步本地冻结记录状态,避免下次再远程查询
freezeOrderService.lambdaUpdate()
.set(FreezeOrder::getStatus, "SUCCESS")
.eq(FreezeOrder::getOutOrderNo, freezeOrderNo)
.eq(FreezeOrder::getStatus, "INIT")
.update();
one.setIsFreeze(order.getIsFreeze());
one.setIsCreditAuth(order.getIsCreditAuth());
frozenAtAlipay = true;
log.info("订单{}支付宝侧已冻结成功,跳过重复发起冻结!", orderId);
// 支付宝侧已冻结,同样清空旧 orderStr,避免前端重复调起收银台
one.setOrderStr(null);
}
} catch (AlipayApiException e) {
log.error("查询支付宝冻结状态失败!orderId:{}", orderId, e);
}
}
if (!frozenAtAlipay) {
try {
String orderStr = freezeOrderService.freeze(order, eg);
one.setOrderStr(orderStr);
log.info("订单{}支付请求参数:{}", orderId, orderStr);
} catch (AlipayApiException e) {
log.error(e.getMessage(), e);
return fail("调用芝麻信用出错!");
}
} }
} }
one.setHasFreeze(0); one.setHasFreeze(0);