diff --git a/pay-mall-app/src/main/resources/application-prod.yml b/pay-mall-app/src/main/resources/application-prod.yml index f4038e3..61feccc 100644 --- a/pay-mall-app/src/main/resources/application-prod.yml +++ b/pay-mall-app/src/main/resources/application-prod.yml @@ -11,7 +11,7 @@ app: api-url: http://group-buying-sys:8091 # 回调给自己,通常要是公网可访问的域名或网关地址 # 如果 pay-mall 服务外部也同 host:8092,可以写: - notify-url: http://group-buying-sys/api/v1/alipay/group_buy_notify + notify-url: http://pay-mall/api/v1/alipay/group_buy_notify notify-type: MQ source: s01 channel: c01 diff --git a/pay-mall-domain/src/main/java/edu/whut/domain/order/service/IOrderService.java b/pay-mall-domain/src/main/java/edu/whut/domain/order/service/IOrderService.java index 2a797d9..ada2a70 100644 --- a/pay-mall-domain/src/main/java/edu/whut/domain/order/service/IOrderService.java +++ b/pay-mall-domain/src/main/java/edu/whut/domain/order/service/IOrderService.java @@ -28,7 +28,7 @@ public interface IOrderService { /** * 营销退单 */ - boolean refundMarketOrder(String userId, String orderId); + boolean preRefundOrder(String userId, String orderId); /** * 接收拼团退单消息 diff --git a/pay-mall-domain/src/main/java/edu/whut/domain/order/service/OrderService.java b/pay-mall-domain/src/main/java/edu/whut/domain/order/service/OrderService.java index f9452f0..d0d9cd4 100644 --- a/pay-mall-domain/src/main/java/edu/whut/domain/order/service/OrderService.java +++ b/pay-mall-domain/src/main/java/edu/whut/domain/order/service/OrderService.java @@ -146,62 +146,114 @@ public class OrderService extends AbstractOrderService{ repository.changeOrderMarketSettlement(outTradeNoList); } + /** + * 预备退单 + */ @Override - public boolean refundMarketOrder(String userId, String orderId) { - // 1. 查询订单信息,验证订单是否存在且属于该用户 + public boolean preRefundOrder(String userId, String orderId) { + // 1. 查单 OrderEntity orderEntity = repository.queryOrderByUserIdAndOrderId(userId, orderId); - if (null == orderEntity) { + if (orderEntity == null) { log.warn("退单失败,订单不存在或不属于该用户 userId:{} orderId:{}", userId, orderId); return false; } - // 2. 检查订单状态,只有create、pay_wait、pay_success、deal_done状态的订单可以退单 String status = orderEntity.getOrderStatusVO().getCode(); + // 已关闭直接拒绝 if (OrderStatusVO.CLOSE.getCode().equals(status)) { log.warn("退单失败,订单已关闭 userId:{} orderId:{} status:{}", userId, orderId, status); return false; } - // 3. 对于营销类型的单子,调用拼团执行组队退单 - port.refundMarketPayOrder(userId, orderId); - - // 4. 执行退单操作 - if (OrderStatusVO.CREATE.getCode().equals(status) || OrderStatusVO.PAY_WAIT.getCode().equals(status)) { - return repository.refundOrder(userId, orderId); - } else { + // 2. 营销锁单走营销通道 + 统一改库 + int marketType = orderEntity.getMarketType(); // 建议后续用枚举替代裸常量 + if (marketType == 1) { + try { + port.refundMarketPayOrder(userId, orderId); + } catch (Exception e) { + // 这里按你的容忍度决定是否直接返回 false + log.error("营销退单通道异常 userId:{} orderId:{} err:{}", userId, orderId, e.getMessage(), e); + return false; + } boolean result = repository.refundMarketOrder(userId, orderId); if (result) { - log.info("退单成功 userId:{} orderId:{}", userId, orderId); + log.info("营销退单成功(已改库) userId:{} orderId:{}", userId, orderId); } else { - log.warn("退单失败 userId:{} orderId:{}", userId, orderId); + log.warn("营销退单失败(改库失败) userId:{} orderId:{}", userId, orderId); } return result; } + + // 3. 普通订单分未付款 / 已付款 + if (OrderStatusVO.CREATE.getCode().equals(status) + || OrderStatusVO.PAY_WAIT.getCode().equals(status)) { + // 未付款:仅改库 + boolean result = repository.refundOrder(userId, orderId); + if (result) { + log.info("普通未付款退单成功(仅改库) userId:{} orderId:{}", userId, orderId); + } else { + log.warn("普通未付款退单失败(改库失败) userId:{} orderId:{}", userId, orderId); + } + return result; + } else { + // 已付款:三方退款 + 改库(用你已有的方法) + return refundPayOrder(userId, orderId); + } } + /** + * 真正的退钱、关闭订单逻辑 + */ @Override - public boolean refundPayOrder(String userId, String orderId) throws AlipayApiException { + public boolean refundPayOrder(String userId, String orderId) /* throws AlipayApiException */ { // 1. 查询订单信息,验证订单是否存在且属于该用户 OrderEntity orderEntity = repository.queryOrderByUserIdAndOrderId(userId, orderId); - if (null == orderEntity) { + if (orderEntity == null) { log.warn("退款失败,订单不存在或不属于该用户 userId:{} orderId:{}", userId, orderId); return false; } - AlipayTradeRefundRequest request = new AlipayTradeRefundRequest(); - AlipayTradeRefundModel refundModel = new AlipayTradeRefundModel(); - refundModel.setOutTradeNo(orderEntity.getOrderId()); - refundModel.setRefundAmount(orderEntity.getPayAmount().toString()); - refundModel.setRefundReason("交易退单"); - request.setBizModel(refundModel); + boolean dbOk = false; // 以落库结果为最终返回 - // 交易退款 - AlipayTradeRefundResponse execute = alipayClient.execute(request); - if (!execute.isSuccess()) return false; + try { + // 2. 调用支付宝退款(沙箱里允许失败) + AlipayTradeRefundRequest request = new AlipayTradeRefundRequest(); + AlipayTradeRefundModel refundModel = new AlipayTradeRefundModel(); + refundModel.setOutTradeNo(orderEntity.getOrderId()); + refundModel.setRefundAmount(orderEntity.getPayAmount().toString()); + refundModel.setRefundReason("交易退单"); + request.setBizModel(refundModel); - // 状态变更 - repository.refundOrder(userId, orderId); + AlipayTradeRefundResponse resp = alipayClient.execute(request); + if (resp.isSuccess()) { + log.info("支付宝退款成功 userId:{} orderId:{}", userId, orderId); + } else { + // 不影响后续改库 + log.warn("支付宝退款失败(沙箱忽略) code={}, subCode={}, msg={}", + resp.getCode(), resp.getSubCode(), resp.getSubMsg()); + } + } catch (Exception e) { + // 捕获所有异常,避免抛出导致 MQ 重试 + log.error("调用支付宝退款异常(沙箱忽略) userId:{} orderId:{} err:{}", + userId, orderId, e.getMessage(), e); + } finally { + // 3. 必须执行状态变更(你要求的“必须执行”) + try { + dbOk = repository.refundOrder(userId, orderId); + if (dbOk) { + log.info("订单状态已更新为已退款 userId:{} orderId:{}", userId, orderId); + } else { + log.warn("订单状态更新失败 userId:{} orderId:{}", userId, orderId); + } + } catch (Exception de) { + // 落库异常要打日志并返回 false,交由上层决定是否重试/告警 + log.error("订单状态更新异常 userId:{} orderId:{} err:{}", + userId, orderId, de.getMessage(), de); + dbOk = false; + } + } - return true; + // 返回以数据库落库为准;支付宝失败在沙箱场景被忽略 + return dbOk; } } diff --git a/pay-mall-trigger/src/main/java/edu/whut/trigger/http/AliPayController.java b/pay-mall-trigger/src/main/java/edu/whut/trigger/http/AliPayController.java index aaec30b..3d59d0b 100644 --- a/pay-mall-trigger/src/main/java/edu/whut/trigger/http/AliPayController.java +++ b/pay-mall-trigger/src/main/java/edu/whut/trigger/http/AliPayController.java @@ -103,7 +103,7 @@ public class AliPayController implements IPayService { public String groupBuyNotify(@RequestBody NotifyRequestDTO requestDTO) { log.info("拼团回调,组队完成,结算开始 {}", JSON.toJSONString(requestDTO)); try { - // 营销结算 + // 订单状态更新、模拟发货... orderService.changeOrderMarketSettlement(requestDTO.getOutTradeNoList()); return "success"; } catch (Exception e) { @@ -152,7 +152,7 @@ public class AliPayController implements IPayService { log.info("支付回调,买家付款金额: {}", params.get("buyer_pay_amount")); log.info("支付回调,支付回调,更新订单 {}", tradeNo); - // 后续处理,更新订单状态...进入下一阶段:如发货 + // 付款成功,更新支付商城系统该笔订单的状态,并调用拼团系统中该笔拼团的结算 orderService.changeOrderPaySuccess(tradeNo, new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").parse(params.get("gmt_payment"))); return "success"; } @@ -232,7 +232,7 @@ public class AliPayController implements IPayService { String orderId = requestDTO.getOrderId(); // 执行退单操作 - boolean success = orderService.refundMarketOrder(userId, orderId); + boolean success = orderService.preRefundOrder(userId, orderId); RefundOrderResponseDTO responseDTO = new RefundOrderResponseDTO(); responseDTO.setSuccess(success);