ソースを参照

商家端 主动退款接口

qinxuyang 1 ヶ月 前
コミット
c568e8b8d2

+ 40 - 0
alien-store/src/main/java/shop/alien/store/controller/StoreReservationController.java

@@ -232,4 +232,44 @@ public class StoreReservationController {
             return R.fail("查询失败:" + e.getMessage());
         }
     }
+
+    @ApiOperationSupport(order = 8)
+    @ApiOperation("商家端主动退款(调用支付退款接口并发送通知和短信)")
+    @ApiImplicitParams({
+            @ApiImplicitParam(name = "storeId", value = "门店ID", required = true, paramType = "query", dataType = "int"),
+            @ApiImplicitParam(name = "outTradeNo", value = "商户订单号", required = true, paramType = "query", dataType = "String"),
+            @ApiImplicitParam(name = "refundAmount", value = "退款金额(元)", required = true, paramType = "query", dataType = "String"),
+            @ApiImplicitParam(name = "refundType", value = "退款类型 0:用户取消 1:商家退款 2:部分退款等 3.扫码核销成功", required = false, paramType = "query", dataType = "int"),
+            @ApiImplicitParam(name = "refundReason", value = "退款原因", paramType = "query", dataType = "String"),
+            @ApiImplicitParam(name = "payType", value = "支付类型 alipay/wechatPay", paramType = "query", dataType = "String")
+    })
+    @PostMapping("/refundByOrder")
+    public R<String> refundByOrder(
+            @RequestParam Integer storeId,
+            @RequestParam String outTradeNo,
+            @RequestParam String refundAmount,
+            @RequestParam(required = false) Integer refundType,
+            @RequestParam(required = false) String refundReason,
+            @RequestParam(defaultValue = "alipay") String payType) {
+        log.info("StoreReservationController.refundByOrder storeId={}, outTradeNo={}, refundAmount={}, refundType={}, refundReason={}, payType={}", 
+                storeId, outTradeNo, refundAmount, refundType, refundReason, payType);
+
+        if (storeId == null) {
+            return R.fail("门店ID不能为空");
+        }
+        if (outTradeNo == null || outTradeNo.trim().isEmpty()) {
+            return R.fail("商户订单号不能为空");
+        }
+        if (refundAmount == null || refundAmount.trim().isEmpty()) {
+            return R.fail("退款金额不能为空");
+        }
+
+        try {
+            R<String> result = storeReservationService.refundByOrder(storeId, outTradeNo, refundAmount, refundReason, refundType, payType);
+            return result;
+        } catch (Exception e) {
+            log.error("商家端主动退款失败", e);
+            return R.fail("退款失败:" + e.getMessage());
+        }
+    }
 }

+ 14 - 0
alien-store/src/main/java/shop/alien/store/service/StoreReservationService.java

@@ -72,4 +72,18 @@ public interface StoreReservationService {
      * @return 是否成功
      */
     boolean refundReservation(Integer reservationId);
+
+    /**
+     * 商家端主动退款(调用支付退款接口并发送通知和短信)
+     *
+     * @param storeId 门店ID
+     * @param outTradeNo 商户订单号
+     * @param refundAmount 退款金额(元)
+     * @param refundReason 退款原因
+     * @param refundType 退款类型 0:用户取消 1:商家退款 2:部分退款等 3.扫码核销成功
+     * @param payType 支付类型 alipay/wechatPay
+     * @return 退款结果
+     */
+    shop.alien.entity.result.R<String> refundByOrder(Integer storeId, String outTradeNo, String refundAmount, 
+                                                       String refundReason, Integer refundType, String payType);
 }

+ 49 - 0
alien-store/src/main/java/shop/alien/store/service/impl/StoreReservationServiceImpl.java

@@ -1276,4 +1276,53 @@ public class StoreReservationServiceImpl extends ServiceImpl<StoreReservationMap
             default: return "未知";
         }
     }
+
+    @Override
+    public shop.alien.entity.result.R<String> refundByOrder(Integer storeId, String outTradeNo, String refundAmount, 
+                                                             String refundReason, Integer refundType, String payType) {
+        log.info("StoreReservationServiceImpl.refundByOrder storeId={}, outTradeNo={}, refundAmount={}, refundType={}, refundReason={}, payType={}", 
+                storeId, outTradeNo, refundAmount, refundType, refundReason, payType);
+
+        try {
+            // 1. 调用支付退款接口
+            MerchantPaymentStrategy strategy = merchantPaymentStrategyFactory.getStrategy(payType);
+            shop.alien.entity.result.R<String> refundResult = strategy.refund(storeId, outTradeNo, refundAmount, refundReason, refundType);
+            
+            // 2. 如果退款成功,发送通知和短信
+            if (refundResult != null && shop.alien.entity.result.R.isSuccess(refundResult)) {
+                log.info("支付退款成功,开始发送通知和短信,outTradeNo={}", outTradeNo);
+                
+                // 通过 outTradeNo 查询订单
+                shop.alien.entity.store.UserReservationOrder order = userReservationOrderService.getByOutTradeNo(outTradeNo);
+                if (order == null) {
+                    log.warn("未找到订单信息,无法发送通知和短信,outTradeNo={}", outTradeNo);
+                    return refundResult;
+                }
+                
+                // 通过订单的 reservationId 获取预约信息
+                Integer reservationId = order.getReservationId();
+                if (reservationId == null) {
+                    log.warn("订单未关联预约信息,无法发送通知和短信,outTradeNo={}, orderId={}", outTradeNo, order.getId());
+                    return refundResult;
+                }
+                
+                UserReservation reservation = this.getById(reservationId);
+                if (reservation == null) {
+                    log.warn("预约信息不存在,无法发送通知和短信,reservationId={}", reservationId);
+                    return refundResult;
+                }
+                
+                // 发送短信和通知
+                sendDepositRefundSmsAndNotice(reservation, order);
+                log.info("退款通知和短信发送完成,outTradeNo={}, reservationId={}", outTradeNo, reservationId);
+            } else {
+                log.warn("支付退款失败,不发送通知和短信,outTradeNo={}, result={}", outTradeNo, refundResult);
+            }
+            
+            return refundResult;
+        } catch (Exception e) {
+            log.error("商家端主动退款异常,outTradeNo={}", outTradeNo, e);
+            return shop.alien.entity.result.R.fail("退款失败:" + e.getMessage());
+        }
+    }
 }