Browse Source

新增退款中状态

zhangchen 1 month ago
parent
commit
4dc45312ab

+ 1 - 1
alien-entity/src/main/java/shop/alien/entity/store/MerchantPaymentOrder.java

@@ -62,7 +62,7 @@ public class MerchantPaymentOrder {
     @TableField("pay_amount")
     @TableField("pay_amount")
     private BigDecimal payAmount;
     private BigDecimal payAmount;
 
 
-    @ApiModelProperty(value = "支付状态: 0-待支付, 1-已支付, 2-已关闭, 3-已退款")
+    @ApiModelProperty(value = "支付状态: 0-待支付, 1-已支付, 2-已关闭, 3-已退款, 4-退款中")
     @TableField("pay_status")
     @TableField("pay_status")
     private Integer payStatus;
     private Integer payStatus;
 
 

+ 1 - 1
alien-entity/src/main/java/shop/alien/entity/store/RefundRecord.java

@@ -54,7 +54,7 @@ public class RefundRecord extends Model<RefundRecord> {
     @TableField("pay_type")
     @TableField("pay_type")
     private String payType;
     private String payType;
 
 
-    @ApiModelProperty(value = "退款状态:SUCCESS-退款成功, CLOSED-退款关闭, PROCESSING-退款处理中, ABNORMAL-退款异常")
+    @ApiModelProperty(value = "退款状态:SUCCESS-退款成功, CLOSED-退款关闭, PROCESSING-退款处理中, ABNORMAL-退款异常, FAIL-退款失败")
     @TableField("refund_status")
     @TableField("refund_status")
     private String refundStatus;
     private String refundStatus;
 
 

+ 1 - 1
alien-entity/src/main/java/shop/alien/entity/store/UserReservationOrder.java

@@ -46,7 +46,7 @@ public class UserReservationOrder {
     @TableField("order_status")
     @TableField("order_status")
     private Integer orderStatus;
     private Integer orderStatus;
 
 
-    @ApiModelProperty(value = "支付状态 0:未支付 1:已支付 2:已退款 3:部分退款")
+    @ApiModelProperty(value = "支付状态 0:未支付 1:已支付 2:已退款 3:部分退款 4:退款中")
     @TableField("payment_status")
     @TableField("payment_status")
     private Integer paymentStatus;
     private Integer paymentStatus;
 
 

+ 49 - 3
alien-store/src/main/java/shop/alien/store/strategy/merchantPayment/impl/MerchantAlipayPaymentStrategyImpl.java

@@ -62,11 +62,16 @@ public class MerchantAlipayPaymentStrategyImpl implements MerchantPaymentStrateg
     private static final String REDIS_PREPAY_DEBOUNCE_KEY_PREFIX = "merchant:alipay:prepay:debounce:order:";
     private static final String REDIS_PREPAY_DEBOUNCE_KEY_PREFIX = "merchant:alipay:prepay:debounce:order:";
     /** 防抖有效期(秒),期内重复调用返回请勿重复提交 */
     /** 防抖有效期(秒),期内重复调用返回请勿重复提交 */
     private static final long REDIS_PREPAY_DEBOUNCE_SECONDS = 5;
     private static final long REDIS_PREPAY_DEBOUNCE_SECONDS = 5;
+    /** 支付状态:退款中 */
+    private static final int PAY_STATUS_REFUNDING = 4;
+    /** 退款记录状态:退款失败 */
+    private static final String REFUND_STATUS_FAIL = "FAIL";
 
 
     private final StorePaymentConfigService storePaymentConfigService;
     private final StorePaymentConfigService storePaymentConfigService;
     private final UserReservationOrderService userReservationOrderService;
     private final UserReservationOrderService userReservationOrderService;
     private final MerchantPaymentOrderService merchantPaymentOrderService;
     private final MerchantPaymentOrderService merchantPaymentOrderService;
     private final RefundRecordAsyncService refundRecordAsyncService;
     private final RefundRecordAsyncService refundRecordAsyncService;
+    private final RefundRecordService refundRecordService;
     private final ReservationOrderPaymentTimeoutService reservationOrderPaymentTimeoutService;
     private final ReservationOrderPaymentTimeoutService reservationOrderPaymentTimeoutService;
     private final UserReservationService userReservationService;
     private final UserReservationService userReservationService;
     private final StringRedisTemplate stringRedisTemplate;
     private final StringRedisTemplate stringRedisTemplate;
@@ -324,7 +329,9 @@ public class MerchantAlipayPaymentStrategyImpl implements MerchantPaymentStrateg
             request.setBizModel(model);
             request.setBizModel(model);
             AlipayTradeRefundResponse response = client.certificateExecute(request);
             AlipayTradeRefundResponse response = client.certificateExecute(request);
             if (!response.isSuccess()) {
             if (!response.isSuccess()) {
-                return R.fail("退款失败:" + response.getSubMsg());
+                String failMsg = "退款失败:" + response.getSubMsg();
+                markRefundFailed(order, paymentOrder, failMsg, refundReason, storeId, outTradeNo);
+                return R.fail(failMsg);
             }
             }
             JSONObject responseBody = JSONObject.parseObject(response.getBody());
             JSONObject responseBody = JSONObject.parseObject(response.getBody());
             JSONObject refundResponse = responseBody != null ? responseBody.getJSONObject("alipay_trade_refund_response") : null;
             JSONObject refundResponse = responseBody != null ? responseBody.getJSONObject("alipay_trade_refund_response") : null;
@@ -365,10 +372,49 @@ public class MerchantAlipayPaymentStrategyImpl implements MerchantPaymentStrateg
             return R.data("退款成功");
             return R.data("退款成功");
         } catch (AlipayApiException e) {
         } catch (AlipayApiException e) {
             log.error("商户预订订单退款异常,outTradeNo={}", outTradeNo, e);
             log.error("商户预订订单退款异常,outTradeNo={}", outTradeNo, e);
-            return R.fail("退款失败:" + e.getErrMsg());
+            String errMsg = "退款失败:" + e.getErrMsg();
+            MerchantPaymentOrder payOrder = merchantPaymentOrderService.getByOutTradeNo(outTradeNo);
+            UserReservationOrder resOrder = payOrder != null ? userReservationOrderService.getById(payOrder.getOrderId()) : null;
+            if (resOrder != null && payOrder != null) {
+                markRefundFailed(resOrder, payOrder, errMsg, refundReason, storeId, outTradeNo);
+            }
+            return R.fail(errMsg);
         } catch (Exception e) {
         } catch (Exception e) {
             log.error("构建支付宝配置异常,storeId={}", storeId, e);
             log.error("构建支付宝配置异常,storeId={}", storeId, e);
-            return R.fail("退款失败:" + e.getMessage());
+            String errMsg = "退款失败:" + e.getMessage();
+            MerchantPaymentOrder payOrder = merchantPaymentOrderService.getByOutTradeNo(outTradeNo);
+            UserReservationOrder resOrder = payOrder != null ? userReservationOrderService.getById(payOrder.getOrderId()) : null;
+            if (resOrder != null && payOrder != null) {
+                markRefundFailed(resOrder, payOrder, errMsg, refundReason, storeId, outTradeNo);
+            }
+            return R.fail(errMsg);
+        }
+    }
+
+    /** 退款失败时:订单与支付单置为退款中,并写入退款失败记录 */
+    private void markRefundFailed(UserReservationOrder order, MerchantPaymentOrder paymentOrder,
+                                  String errorMsg, String refundReason, Integer storeId, String outTradeNo) {
+        try {
+            Date now = new Date();
+            order.setPaymentStatus(PAY_STATUS_REFUNDING);
+            order.setUpdatedTime(now);
+            userReservationOrderService.updateById(order);
+            paymentOrder.setPayStatus(PAY_STATUS_REFUNDING);
+            paymentOrder.setUpdatedTime(now);
+            merchantPaymentOrderService.updateById(paymentOrder);
+            RefundRecord record = new RefundRecord();
+            record.setOutTradeNo(outTradeNo);
+            record.setPayType(PaymentEnum.ALIPAY.getType());
+            record.setRefundStatus(REFUND_STATUS_FAIL);
+            record.setOrderId(String.valueOf(order.getId()));
+            record.setStoreId(storeId);
+            record.setUserId(order.getUserId());
+            record.setRefundReason(StringUtils.isNotBlank(refundReason) ? refundReason : "退款失败");
+            record.setErrorMsg(errorMsg != null ? errorMsg : "退款失败");
+            record.setDeleteFlag(0);
+            refundRecordService.save(record);
+        } catch (Exception ex) {
+            log.error("标记退款失败状态异常,outTradeNo={}", outTradeNo, ex);
         }
         }
     }
     }
 
 

+ 51 - 4
alien-store/src/main/java/shop/alien/store/strategy/merchantPayment/impl/MerchantWechatPaymentStrategyImpl.java

@@ -16,6 +16,7 @@ import shop.alien.entity.store.UserReservation;
 import shop.alien.entity.store.UserReservationOrder;
 import shop.alien.entity.store.UserReservationOrder;
 import shop.alien.store.service.MerchantPaymentOrderService;
 import shop.alien.store.service.MerchantPaymentOrderService;
 import shop.alien.store.service.RefundRecordAsyncService;
 import shop.alien.store.service.RefundRecordAsyncService;
+import shop.alien.store.service.RefundRecordService;
 import shop.alien.store.service.StorePaymentConfigService;
 import shop.alien.store.service.StorePaymentConfigService;
 import shop.alien.store.service.ReservationOrderPaymentTimeoutService;
 import shop.alien.store.service.ReservationOrderPaymentTimeoutService;
 import shop.alien.store.service.UserReservationOrderService;
 import shop.alien.store.service.UserReservationOrderService;
@@ -53,6 +54,10 @@ public class MerchantWechatPaymentStrategyImpl implements MerchantPaymentStrateg
     private static final String REDIS_PREPAY_DEBOUNCE_KEY_PREFIX = "merchant:wechat:prepay:debounce:order:";
     private static final String REDIS_PREPAY_DEBOUNCE_KEY_PREFIX = "merchant:wechat:prepay:debounce:order:";
     /** 防抖有效期(秒),期内重复调用返回请勿重复提交 */
     /** 防抖有效期(秒),期内重复调用返回请勿重复提交 */
     private static final long REDIS_PREPAY_DEBOUNCE_SECONDS = 5;
     private static final long REDIS_PREPAY_DEBOUNCE_SECONDS = 5;
+    /** 支付状态:退款中 */
+    private static final int PAY_STATUS_REFUNDING = 4;
+    /** 退款记录状态:退款失败 */
+    private static final String REFUND_STATUS_FAIL = "FAIL";
 
 
     @Value("${payment.wechatPay.host:https://api.mch.weixin.qq.com}")
     @Value("${payment.wechatPay.host:https://api.mch.weixin.qq.com}")
     private String wechatPayApiHost;
     private String wechatPayApiHost;
@@ -71,6 +76,7 @@ public class MerchantWechatPaymentStrategyImpl implements MerchantPaymentStrateg
     private final UserReservationOrderService userReservationOrderService;
     private final UserReservationOrderService userReservationOrderService;
     private final MerchantPaymentOrderService merchantPaymentOrderService;
     private final MerchantPaymentOrderService merchantPaymentOrderService;
     private final RefundRecordAsyncService refundRecordAsyncService;
     private final RefundRecordAsyncService refundRecordAsyncService;
+    private final RefundRecordService refundRecordService;
     private final ReservationOrderPaymentTimeoutService reservationOrderPaymentTimeoutService;
     private final ReservationOrderPaymentTimeoutService reservationOrderPaymentTimeoutService;
     private final UserReservationService userReservationService;
     private final UserReservationService userReservationService;
     private final StringRedisTemplate stringRedisTemplate;
     private final StringRedisTemplate stringRedisTemplate;
@@ -346,6 +352,7 @@ public class MerchantWechatPaymentStrategyImpl implements MerchantPaymentStrateg
                             Thread.sleep(delayMs);
                             Thread.sleep(delayMs);
                         } catch (InterruptedException ie) {
                         } catch (InterruptedException ie) {
                             Thread.currentThread().interrupt();
                             Thread.currentThread().interrupt();
+                            markRefundFailed(order, paymentOrder, "操作过于频繁,请稍后再试", refundReason, storeId, outTradeNo);
                             return R.fail("操作过于频繁,请稍后再试");
                             return R.fail("操作过于频繁,请稍后再试");
                         }
                         }
                     } else {
                     } else {
@@ -360,11 +367,14 @@ public class MerchantWechatPaymentStrategyImpl implements MerchantPaymentStrateg
                 String msg = lastApiException != null && lastApiException.getStatusCode() == 429
                 String msg = lastApiException != null && lastApiException.getStatusCode() == 429
                         ? (StringUtils.isNotBlank(lastApiException.getErrorMessage()) ? lastApiException.getErrorMessage() : "操作过于频繁,请稍后再试")
                         ? (StringUtils.isNotBlank(lastApiException.getErrorMessage()) ? lastApiException.getErrorMessage() : "操作过于频繁,请稍后再试")
                         : "退款失败";
                         : "退款失败";
+                markRefundFailed(order, paymentOrder, msg, refundReason, storeId, outTradeNo);
                 return R.fail(msg);
                 return R.fail(msg);
             }
             }
             String status = response.status != null ? response.status.name() : "";
             String status = response.status != null ? response.status.name() : "";
             if (!"SUCCESS".equals(status) && !"PROCESSING".equals(status)) {
             if (!"SUCCESS".equals(status) && !"PROCESSING".equals(status)) {
-                return R.fail("退款失败:" + status);
+                String failMsg = "退款失败:" + status;
+                markRefundFailed(order, paymentOrder, failMsg, refundReason, storeId, outTradeNo);
+                return R.fail(failMsg);
             }
             }
 
 
             Date now = new Date();
             Date now = new Date();
@@ -403,16 +413,53 @@ public class MerchantWechatPaymentStrategyImpl implements MerchantPaymentStrateg
             return R.data("退款成功");
             return R.data("退款成功");
         } catch (WXPayUtility.ApiException e) {
         } catch (WXPayUtility.ApiException e) {
             log.error("商户预订订单微信退款异常,outTradeNo={}", outTradeNo, e);
             log.error("商户预订订单微信退款异常,outTradeNo={}", outTradeNo, e);
-            if (e.getStatusCode() == 429) {
-                return R.fail(StringUtils.isNotBlank(e.getErrorMessage()) ? e.getErrorMessage() : "操作过于频繁,请稍后再试");
+            String errMsg = e.getStatusCode() == 429
+                    ? (StringUtils.isNotBlank(e.getErrorMessage()) ? e.getErrorMessage() : "操作过于频繁,请稍后再试")
+                    : "退款失败:" + e.getMessage();
+            MerchantPaymentOrder payOrder = merchantPaymentOrderService.getByOutTradeNo(outTradeNo);
+            UserReservationOrder resOrder = payOrder != null ? userReservationOrderService.getById(payOrder.getOrderId()) : null;
+            if (resOrder != null && payOrder != null) {
+                markRefundFailed(resOrder, payOrder, errMsg, refundReason, storeId, outTradeNo);
             }
             }
-            return R.fail("退款失败:" + e.getMessage());
+            return R.fail(errMsg);
         } catch (Exception e) {
         } catch (Exception e) {
             log.error("商户微信退款异常,storeId={}", storeId, e);
             log.error("商户微信退款异常,storeId={}", storeId, e);
+            MerchantPaymentOrder payOrder = merchantPaymentOrderService.getByOutTradeNo(outTradeNo);
+            UserReservationOrder resOrder = payOrder != null ? userReservationOrderService.getById(payOrder.getOrderId()) : null;
+            if (resOrder != null && payOrder != null) {
+                markRefundFailed(resOrder, payOrder, "退款失败:" + e.getMessage(), refundReason, storeId, outTradeNo);
+            }
             return R.fail("退款失败:" + e.getMessage());
             return R.fail("退款失败:" + e.getMessage());
         }
         }
     }
     }
 
 
+    /** 退款失败时:订单与支付单置为退款中,并写入退款失败记录 */
+    private void markRefundFailed(UserReservationOrder order, MerchantPaymentOrder paymentOrder,
+                                  String errorMsg, String refundReason, Integer storeId, String outTradeNo) {
+        try {
+            Date now = new Date();
+            order.setPaymentStatus(PAY_STATUS_REFUNDING);
+            order.setUpdatedTime(now);
+            userReservationOrderService.updateById(order);
+            paymentOrder.setPayStatus(PAY_STATUS_REFUNDING);
+            paymentOrder.setUpdatedTime(now);
+            merchantPaymentOrderService.updateById(paymentOrder);
+            RefundRecord record = new RefundRecord();
+            record.setOutTradeNo(outTradeNo);
+            record.setPayType(PaymentEnum.WECHAT_PAY.getType());
+            record.setRefundStatus(REFUND_STATUS_FAIL);
+            record.setOrderId(String.valueOf(order.getId()));
+            record.setStoreId(storeId);
+            record.setUserId(order.getUserId());
+            record.setRefundReason(StringUtils.isNotBlank(refundReason) ? refundReason : "退款失败");
+            record.setErrorMsg(errorMsg != null ? errorMsg : "退款失败");
+            record.setDeleteFlag(0);
+            refundRecordService.save(record);
+        } catch (Exception ex) {
+            log.error("标记退款失败状态异常,outTradeNo={}", outTradeNo, ex);
+        }
+    }
+
     @Override
     @Override
     public String getType() {
     public String getType() {
         return PaymentEnum.WECHAT_PAY.getType();
         return PaymentEnum.WECHAT_PAY.getType();