diff --git a/ebike-payment/src/main/java/com/cdzy/payment/enums/RefundStatus.java b/ebike-payment/src/main/java/com/cdzy/payment/enums/RefundStatus.java index 46607ef..e7872e7 100644 --- a/ebike-payment/src/main/java/com/cdzy/payment/enums/RefundStatus.java +++ b/ebike-payment/src/main/java/com/cdzy/payment/enums/RefundStatus.java @@ -12,17 +12,17 @@ public interface RefundStatus { /** * 退款成功 */ - int APPLYING = 0; + int SUCCESS = 0; /** * 关闭 */ - int PROCESSING = 1; + int CLOSED = 1; /** * 退款中 */ - int PROCESSED = 2; + int PROCESSING = 2; /** * 异常 */ - int CLOSED = 3; + int ABNORMAL = 3; } diff --git a/ebike-payment/src/main/java/com/cdzy/payment/model/vo/EbikeRefundInfoVo.java b/ebike-payment/src/main/java/com/cdzy/payment/model/vo/EbikeRefundInfoVo.java deleted file mode 100644 index 8bb2240..0000000 --- a/ebike-payment/src/main/java/com/cdzy/payment/model/vo/EbikeRefundInfoVo.java +++ /dev/null @@ -1,34 +0,0 @@ -package com.cdzy.payment.model.vo; - -import lombok.AllArgsConstructor; -import lombok.Data; -import lombok.NoArgsConstructor; - -import java.io.Serializable; -import java.math.BigDecimal; - -/** - * 退款信息 - * - * @author yanglei - * @since 2025-10-21 10:26 - */ - -@Data -@NoArgsConstructor -@AllArgsConstructor -public class EbikeRefundInfoVo implements Serializable { - - /** - * 退款金额,单位为元 - */ - private BigDecimal refund; - /** - * 原订单金额,单位为元 - */ - private BigDecimal total; - /** - * 退款币种 (默认CNY) - */ - private String currency = "CNY"; -} diff --git a/ebike-payment/src/main/java/com/cdzy/payment/service/EbikeOrderService.java b/ebike-payment/src/main/java/com/cdzy/payment/service/EbikeOrderService.java index e44108c..9c3764b 100644 --- a/ebike-payment/src/main/java/com/cdzy/payment/service/EbikeOrderService.java +++ b/ebike-payment/src/main/java/com/cdzy/payment/service/EbikeOrderService.java @@ -14,21 +14,21 @@ import com.mybatisflex.core.service.IService; public interface EbikeOrderService extends IService { /** - * 订单退款完成 + * 订单退款完成 由退款中 -> 退款成功 * * @param orderId 订单ID */ void doneRefund(Long orderId); /** - * 订单退款 + * 订单退款 由退款申请中 -> 退款中 * * @param orderId 订单ID */ void refund(Long orderId); /** - * 订单退款失败 + * 订单退款失败 由退款中 -> 退款失败 * * @param orderId 订单ID */ diff --git a/ebike-payment/src/main/java/com/cdzy/payment/service/impl/EbikeOrderServiceImpl.java b/ebike-payment/src/main/java/com/cdzy/payment/service/impl/EbikeOrderServiceImpl.java index 068adb9..d5b48c6 100644 --- a/ebike-payment/src/main/java/com/cdzy/payment/service/impl/EbikeOrderServiceImpl.java +++ b/ebike-payment/src/main/java/com/cdzy/payment/service/impl/EbikeOrderServiceImpl.java @@ -36,7 +36,7 @@ public class EbikeOrderServiceImpl extends ServiceImpl ebikeOrderService.refund(orderId); + // 退款中 + case PROCESSING -> ebikeOrderService.refund(orderId); + // 成功退款 case SUCCESS -> ebikeOrderService.doneRefund(orderId); + // 失败/关闭 → 订单“退款失败” case ABNORMAL -> ebikeOrderService.failRefund(orderId); + default -> log.warn("未知的微信退款状态: {}, orderId: {}", refundNotification.getRefundStatus(), orderId); } return updateById(ebikeRefund); } diff --git a/ebike-payment/src/main/java/com/cdzy/payment/service/impl/EbikeWxPayServiceImpl.java b/ebike-payment/src/main/java/com/cdzy/payment/service/impl/EbikeWxPayServiceImpl.java index 8693103..139b39a 100644 --- a/ebike-payment/src/main/java/com/cdzy/payment/service/impl/EbikeWxPayServiceImpl.java +++ b/ebike-payment/src/main/java/com/cdzy/payment/service/impl/EbikeWxPayServiceImpl.java @@ -1,11 +1,18 @@ package com.cdzy.payment.service.impl; import com.cdzy.common.enums.GlobalConstants; +import com.cdzy.common.ex.EbikeException; import com.cdzy.payment.config.WxPayConfig; import com.cdzy.payment.enums.PaymentMethod; +import com.cdzy.payment.enums.RefundStatus; import com.cdzy.payment.model.entity.EbikePayment; import com.cdzy.payment.model.entity.EbikeRefund; -import com.cdzy.payment.model.vo.*; +import com.cdzy.payment.model.vo.EbikePaymentAmountVo; +import com.cdzy.payment.model.vo.EbikePaymentDetailVo; +import com.cdzy.payment.model.vo.EbikePaymentVo; +import com.cdzy.payment.model.vo.EbikeWxHandleNotifyVo; +import com.cdzy.payment.model.vo.EbikeWxJsapiPromptVo; +import com.cdzy.payment.service.EbikeOrderService; import com.cdzy.payment.service.EbikePaymentService; import com.cdzy.payment.service.EbikeRefundService; import com.cdzy.payment.service.EbikeWxPayService; @@ -27,11 +34,22 @@ import com.wechat.pay.java.core.notification.RequestParam; import com.wechat.pay.java.core.util.NonceUtil; import com.wechat.pay.java.service.payments.jsapi.JsapiService; import com.wechat.pay.java.service.payments.jsapi.model.Amount; +import com.wechat.pay.java.service.payments.jsapi.model.CloseOrderRequest; +import com.wechat.pay.java.service.payments.jsapi.model.Detail; import com.wechat.pay.java.service.payments.jsapi.model.GoodsDetail; -import com.wechat.pay.java.service.payments.jsapi.model.*; +import com.wechat.pay.java.service.payments.jsapi.model.Payer; +import com.wechat.pay.java.service.payments.jsapi.model.PrepayRequest; +import com.wechat.pay.java.service.payments.jsapi.model.PrepayResponse; +import com.wechat.pay.java.service.payments.jsapi.model.QueryOrderByOutTradeNoRequest; +import com.wechat.pay.java.service.payments.jsapi.model.SettleInfo; import com.wechat.pay.java.service.payments.model.Transaction; import com.wechat.pay.java.service.refund.RefundService; -import com.wechat.pay.java.service.refund.model.*; +import com.wechat.pay.java.service.refund.model.AmountReq; +import com.wechat.pay.java.service.refund.model.CreateRequest; +import com.wechat.pay.java.service.refund.model.QueryByOutRefundNoRequest; +import com.wechat.pay.java.service.refund.model.Refund; +import com.wechat.pay.java.service.refund.model.RefundNotification; +import com.wechat.pay.java.service.refund.model.Status; import jakarta.annotation.Resource; import jakarta.servlet.http.HttpServletRequest; import lombok.extern.slf4j.Slf4j; @@ -44,8 +62,13 @@ import java.time.Instant; import java.time.LocalDateTime; import java.util.ArrayList; import java.util.List; +import java.util.Objects; -import static com.wechat.pay.java.core.http.Constant.*; +import static com.wechat.pay.java.core.http.Constant.REQUEST_ID; +import static com.wechat.pay.java.core.http.Constant.WECHAT_PAY_NONCE; +import static com.wechat.pay.java.core.http.Constant.WECHAT_PAY_SERIAL; +import static com.wechat.pay.java.core.http.Constant.WECHAT_PAY_SIGNATURE; +import static com.wechat.pay.java.core.http.Constant.WECHAT_PAY_TIMESTAMP; /** * 微信支付服务类(JSAPI支付),小程序 @@ -81,6 +104,9 @@ public class EbikeWxPayServiceImpl implements EbikeWxPayService { @Resource private ObjectMapper objectMapper; + @Resource + private EbikeOrderService orderService; + @Override public boolean closeOrder(String outTradeNo) { try { @@ -385,31 +411,26 @@ public class EbikeWxPayServiceImpl implements EbikeWxPayService { notifyVo.setSuccess(false); // 检查退款记录是否存在 EbikeRefund ebikeRefund = ebikeRefundService.getById(refundDto.getRefundId()); - if (ebikeRefund == null) { - log.error("退款refund失败,{} 退款申请不存在", refundDto.getRefundId()); - notifyVo.setMessage(String.format("{%s}退款申请不存在", refundDto.getRefundId())); - return notifyVo; + if (Objects.isNull(ebikeRefund)) { + throw new EbikeException("退款订单不存在"); } // 检查退款状态 - if (Status.SUCCESS.ordinal() == ebikeRefund.getRefundStatus()) { - log.error("退款refund失败,{} 退款已经成功,不能重复退款", refundDto.getRefundId()); - notifyVo.setMessage(String.format("{%s}退款已经成功,不能重复退款", refundDto.getRefundId())); - return notifyVo; + if (RefundStatus.SUCCESS == ebikeRefund.getRefundStatus()) { + throw new EbikeException("当前订单已完成退款"); } - if (Status.CLOSED.ordinal() == ebikeRefund.getRefundStatus() || - Status.ABNORMAL.ordinal() == ebikeRefund.getRefundStatus()) { - //重新发起 + if (RefundStatus.CLOSED == ebikeRefund.getRefundStatus() || + RefundStatus.ABNORMAL == ebikeRefund.getRefundStatus()) { + //重新生成退款id并发起退款 String newOrder = StringUtils.generateSnowflakeId("refundId"); ebikeRefund.setRefundOrderId(newOrder); } // 查询支付记录 Long orderId = ebikeRefund.getOrderId(); EbikePayment ebikePayment = ebikePaymentService.getByOrderId(orderId); + if (Objects.isNull(ebikePayment)) { + throw new EbikeException("支付记录不存在"); + } String transactionId = ebikePayment.getTransactionId(); - EbikeRefundInfoVo amount = new EbikeRefundInfoVo(); - amount.setTotal(ebikePayment.getCostPrice()); - amount.setRefund(ebikePayment.getTotal()); - amount.setCurrency(ebikeRefund.getCurrency()); // 发起退款 CreateRequest request = new CreateRequest(); request.setTransactionId(transactionId); @@ -418,43 +439,36 @@ public class EbikeWxPayServiceImpl implements EbikeWxPayService { request.setReason(ebikeRefund.getProblemDescription()); request.setNotifyUrl(wxPayConfig.getRefundNotifyUrl()); AmountReq amountReq = new AmountReq(); - amountReq.setRefund(yuanToCent(amount.getRefund())); - amountReq.setTotal(yuanToCent(amount.getTotal())); - amountReq.setCurrency(amount.getCurrency()); + amountReq.setRefund(yuanToCent(ebikePayment.getTotal())); + amountReq.setTotal(yuanToCent(ebikePayment.getTotal())); + amountReq.setCurrency(ebikePayment.getCurrency()); request.setAmount(amountReq); try { Refund result = wxRefundService.create(request); - // 更新退款信息 - if (result != null) { - ebikeRefund.setOrderId(orderId); - ebikeRefund.setTransactionId(transactionId); - ebikeRefund.setTotal(amount.getTotal()); - ebikeRefund.setRefundStatus(result.getStatus().ordinal()); - ebikeRefund.setCurrency(amount.getCurrency()); - ebikeRefund.setRefund(new BigDecimal(result.getAmount().getRefund()) - .divide(BigDecimal.valueOf(100), 2, RoundingMode.HALF_UP)); - ebikeRefund.setRefundTime(LocalDateTime.now()); - ebikeRefund.setRefundTransactionId(result.getRefundId()); - ebikeRefundService.updateById(ebikeRefund); - notifyVo.setSuccess(true); - notifyVo.setMessage("退款成功"); + if (result == null) { + log.error("调用微信退款接口返回空,订单号: {}", orderId); + notifyVo.setMessage("退款请求失败"); return notifyVo; } - log.error("退款refund失败,订单号:{}", orderId); - notifyVo.setMessage("退款失败"); + orderService.refund(orderId); + // 更新退款信息 + ebikeRefund.setOrderId(orderId); + ebikeRefund.setTransactionId(transactionId); + ebikeRefund.setTotal(ebikePayment.getCostPrice()); + ebikeRefund.setRefundStatus(result.getStatus().ordinal()); + ebikeRefund.setCurrency(ebikePayment.getCurrency()); + ebikeRefund.setRefund(new BigDecimal(result.getAmount().getRefund()) + .divide(BigDecimal.valueOf(100), 2, RoundingMode.HALF_UP)); + ebikeRefund.setRefundTime(LocalDateTime.now()); + ebikeRefund.setRefundTransactionId(result.getRefundId()); + ebikeRefundService.updateById(ebikeRefund); + notifyVo.setSuccess(true); + notifyVo.setMessage("退款已提交"); return notifyVo; } catch (Exception e) { - String err = logError("退款refund", e); - try { - JsonNode jsonNode = objectMapper.readTree(err); - if (jsonNode.has("message")) { - notifyVo.setMessage(jsonNode.get("message").asText()); - } else { - notifyVo.setMessage(err); - } - } catch (Exception ex) { - notifyVo.setMessage(err); - } + log.error("发起退款异常,refundId: {}, orderId: {}, error: {}", + refundDto.getRefundId(), orderId, e.getMessage(), e); + notifyVo.setMessage("退款失败: " + e.getMessage()); return notifyVo; } }