Pārlūkot izejas kodu

fix: 清理孤儿订单加30分钟阈值,避免误取消正常等待中的订单

防止用户二次开门时,前一笔正在等待ORDER回调(几秒内)的正常订单被误取消。
仅清理创建超过30分钟金额仍为空的订单,覆盖回调最大重试窗口。

Co-Authored-By: Claude <noreply@anthropic.com>
skyline 2 dienas atpakaļ
vecāks
revīzija
c68ee27af8

+ 6 - 3
haha-service/src/main/java/com/haha/service/payment/payscore/impl/PayScoreServiceImpl.java

@@ -1127,9 +1127,11 @@ public class PayScoreServiceImpl implements PayScoreService {
             log.error("[支付分服务] 清理DB进行中订单失败 - userId: {}", userId, e);
         }
 
-        // 1.5 取消 DOING/USER_PAYING 状态但金额为空的孤儿订单
-        // 这类订单由回调签名失败等异常造成(用户已确认但金额未写入),新预授权创建时必须清理
+        // 1.5 取消 DOING/USER_PAYING 状态但金额为空且超过30分钟的孤儿订单
+        // 仅清理因回调签名失败等异常造成的遗留订单,正常等待 ORDER 回调的订单不受影响
+        // 30分钟阈值确保覆盖 ORDER 回调的最大重试窗口,不会误取消正常进行中的订单
         try {
+            java.time.LocalDateTime staleThreshold = java.time.LocalDateTime.now().minusMinutes(30);
             List<Order> stuckOrders = orderService.lambdaQuery()
                     .eq(Order::getUserId, userId)
                     .eq(Order::getPayChannel, PaymentChannel.WECHAT_PAYSCORE.getCode())
@@ -1138,10 +1140,11 @@ public class PayScoreServiceImpl implements PayScoreService {
                             PayScoreState.USER_PAYING.getCode()))
                     .isNotNull(Order::getPayScoreOrderId)
                     .and(w -> w.isNull(Order::getTotalAmount).or().eq(Order::getTotalAmount, BigDecimal.ZERO))
+                    .le(Order::getCreateTime, staleThreshold)
                     .list();
 
             if (stuckOrders != null && !stuckOrders.isEmpty()) {
-                log.info("[支付分服务] 清理用户 {} 的 {} 笔已确认但金额为空订单", userId, stuckOrders.size());
+                log.info("[支付分服务] 清理用户 {} 的 {} 笔已确认但金额为空超时订单(>30min)", userId, stuckOrders.size());
                 for (Order order : stuckOrders) {
                     cancelPayScoreOrderByOutOrderNo(order.getPayScoreOrderId(), order.getId());
                 }