diff --git a/yudao-framework/yudao-spring-boot-starter-biz-pay/src/main/java/cn/iocoder/yudao/framework/pay/core/client/impl/AbstractPayClient.java b/yudao-framework/yudao-spring-boot-starter-biz-pay/src/main/java/cn/iocoder/yudao/framework/pay/core/client/impl/AbstractPayClient.java index f25bb98814..06e8774dd6 100644 --- a/yudao-framework/yudao-spring-boot-starter-biz-pay/src/main/java/cn/iocoder/yudao/framework/pay/core/client/impl/AbstractPayClient.java +++ b/yudao-framework/yudao-spring-boot-starter-biz-pay/src/main/java/cn/iocoder/yudao/framework/pay/core/client/impl/AbstractPayClient.java @@ -70,6 +70,8 @@ public abstract class AbstractPayClient implemen return channelId; } + // ============ 支付相关 ========== + @Override public final PayOrderUnifiedRespDTO unifiedOrder(PayOrderUnifiedReqDTO reqDTO) { Validation.buildDefaultValidatorFactory().getValidator().validate(reqDTO); @@ -91,6 +93,8 @@ public abstract class AbstractPayClient implemen protected abstract PayOrderUnifiedRespDTO doUnifiedOrder(PayOrderUnifiedReqDTO reqDTO) throws Throwable; + // ============ 退款相关 ========== + @Override public PayRefundRespDTO unifiedRefund(PayRefundUnifiedReqDTO reqDTO) { Validation.buildDefaultValidatorFactory().getValidator().validate(reqDTO); diff --git a/yudao-framework/yudao-spring-boot-starter-biz-pay/src/main/java/cn/iocoder/yudao/framework/pay/core/client/impl/weixin/AbstractWxPayClient.java b/yudao-framework/yudao-spring-boot-starter-biz-pay/src/main/java/cn/iocoder/yudao/framework/pay/core/client/impl/weixin/AbstractWxPayClient.java index 98e826c72b..3a02dd7e9f 100644 --- a/yudao-framework/yudao-spring-boot-starter-biz-pay/src/main/java/cn/iocoder/yudao/framework/pay/core/client/impl/weixin/AbstractWxPayClient.java +++ b/yudao-framework/yudao-spring-boot-starter-biz-pay/src/main/java/cn/iocoder/yudao/framework/pay/core/client/impl/weixin/AbstractWxPayClient.java @@ -4,7 +4,6 @@ import cn.hutool.core.bean.BeanUtil; import cn.hutool.core.codec.Base64; import cn.hutool.core.date.LocalDateTimeUtil; import cn.hutool.core.date.TemporalAccessorUtil; -import cn.hutool.core.lang.Assert; import cn.hutool.core.util.StrUtil; import cn.iocoder.yudao.framework.common.util.io.FileUtils; import cn.iocoder.yudao.framework.pay.core.client.dto.order.PayOrderRespDTO; @@ -19,8 +18,11 @@ import cn.iocoder.yudao.framework.pay.core.enums.refund.PayRefundStatusRespEnum; import com.github.binarywang.wxpay.bean.notify.WxPayOrderNotifyResult; import com.github.binarywang.wxpay.bean.notify.WxPayOrderNotifyV3Result; import com.github.binarywang.wxpay.bean.notify.WxPayRefundNotifyResult; +import com.github.binarywang.wxpay.bean.notify.WxPayRefundNotifyV3Result; import com.github.binarywang.wxpay.bean.request.WxPayRefundRequest; +import com.github.binarywang.wxpay.bean.request.WxPayRefundV3Request; import com.github.binarywang.wxpay.bean.result.WxPayRefundResult; +import com.github.binarywang.wxpay.bean.result.WxPayRefundV3Result; import com.github.binarywang.wxpay.config.WxPayConfig; import com.github.binarywang.wxpay.exception.WxPayException; import com.github.binarywang.wxpay.service.WxPayService; @@ -78,6 +80,8 @@ public abstract class AbstractWxPayClient extends AbstractPayClient params, String body) { + try { + // 微信支付 v2 回调结果处理 + switch (config.getApiVersion()) { + case API_VERSION_V2: + return parseOrderNotifyV2(body); + case WxPayClientConfig.API_VERSION_V3: + return parseOrderNotifyV3(body); + default: + throw new IllegalArgumentException(String.format("未知的 API 版本(%s)", config.getApiVersion())); + } + } catch (WxPayException e) { + log.error("[parseNotify][params({}) body({}) 解析失败]", params, body, e); +// throw buildPayException(e); + throw new RuntimeException(e); + // TODO 芋艿:缺一个异常翻译 + } + } + + private PayOrderRespDTO parseOrderNotifyV2(String body) throws WxPayException { + // 1. 解析回调 + WxPayOrderNotifyResult response = client.parseOrderNotifyResult(body); + // 2. 构建结果 + return PayOrderRespDTO.builder() + .outTradeNo(response.getOutTradeNo()) + .channelOrderNo(response.getTransactionId()) + .channelUserId(response.getOpenid()) + .status(Objects.equals(response.getResultCode(), "SUCCESS") ? + PayOrderStatusRespEnum.SUCCESS.getStatus() : PayOrderStatusRespEnum.CLOSED.getStatus()) + .successTime(parseDateV2(response.getTimeEnd())) + .rawData(response) + .build(); + } + + private PayOrderRespDTO parseOrderNotifyV3(String body) throws WxPayException { + // 1. 解析回调 + WxPayOrderNotifyV3Result response = client.parseOrderNotifyV3Result(body, null); + WxPayOrderNotifyV3Result.DecryptNotifyResult responseResult = response.getResult(); + // 2. 构建结果 + return PayOrderRespDTO.builder() + .outTradeNo(responseResult.getOutTradeNo()) + .channelOrderNo(responseResult.getTradeState()) + .channelUserId(responseResult.getPayer() != null ? responseResult.getPayer().getOpenid() : null) + .status(Objects.equals(responseResult.getTradeState(), "SUCCESS") ? + PayOrderStatusRespEnum.SUCCESS.getStatus() : PayOrderStatusRespEnum.CLOSED.getStatus()) + .successTime(parseDateV3(responseResult.getSuccessTime())) + .build(); + } + + // ============ 退款相关 ========== + @Override protected PayRefundRespDTO doUnifiedRefund(PayRefundUnifiedReqDTO reqDTO) throws Throwable { try { @@ -140,73 +196,48 @@ public abstract class AbstractWxPayClient extends AbstractPayClient params, String body) { - try { - // 微信支付 v2 回调结果处理 - switch (config.getApiVersion()) { - case API_VERSION_V2: - return parseOrderNotifyV2(body); - case WxPayClientConfig.API_VERSION_V3: - return parseOrderNotifyV3(body); - default: - throw new IllegalArgumentException(String.format("未知的 API 版本(%s)", config.getApiVersion())); - } - } catch (WxPayException e) { - log.error("[parseNotify][params({}) body({}) 解析失败]", params, body, e); -// throw buildPayException(e); - throw new RuntimeException(e); - // TODO 芋艿:缺一个异常翻译 + // 1. 构建 WxPayRefundRequest 请求 + WxPayRefundV3Request request = new WxPayRefundV3Request() + .setOutTradeNo(reqDTO.getOutTradeNo()) + .setOutRefundNo(reqDTO.getOutRefundNo()) + .setAmount(new WxPayRefundV3Request.Amount().setRefund(reqDTO.getRefundPrice()) + .setTotal(reqDTO.getPayPrice()).setCurrency("CNY")) + .setReason(reqDTO.getReason()) + .setNotifyUrl(reqDTO.getNotifyUrl()); + // 2.1 执行请求 + WxPayRefundV3Result response = client.refundV3(request); + // 2.2 创建返回结果 + PayRefundRespDTO refund = new PayRefundRespDTO() + .setOutRefundNo(reqDTO.getOutRefundNo()) + .setRawData(response); + if (Objects.equals("SUCCESS", response.getStatus())) { + refund.setStatus(PayRefundStatusRespEnum.SUCCESS.getStatus()) + .setChannelRefundNo(response.getRefundId()) + .setSuccessTime(parseDateV3(response.getSuccessTime())); + } else if (Objects.equals("PROCESSING", response.getStatus())) { + refund.setStatus(PayRefundStatusRespEnum.WAITING.getStatus()) + .setChannelRefundNo(response.getRefundId()); + } else { + refund.setStatus(PayRefundStatusRespEnum.FAILURE.getStatus()); } - } - - private PayOrderRespDTO parseOrderNotifyV2(String body) throws WxPayException { - // 1. 解析回调 - WxPayOrderNotifyResult response = client.parseOrderNotifyResult(body); - // 2. 构建结果 - return PayOrderRespDTO.builder() - .outTradeNo(response.getOutTradeNo()) - .channelOrderNo(response.getTransactionId()) - .channelUserId(response.getOpenid()) - .status(Objects.equals(response.getResultCode(), "SUCCESS") ? - PayOrderStatusRespEnum.SUCCESS.getStatus() : PayOrderStatusRespEnum.CLOSED.getStatus()) - .successTime(parseDateV2(response.getTimeEnd())) - .rawData(response) - .build(); - } - - private PayOrderRespDTO parseOrderNotifyV3(String body) throws WxPayException { - WxPayOrderNotifyV3Result notifyResult = client.parseOrderNotifyV3Result(body, null); - WxPayOrderNotifyV3Result.DecryptNotifyResult result = notifyResult.getResult(); - // TODO 芋艿:翻译下 state - // 转换结果 - Assert.isTrue(Objects.equals(notifyResult.getResult().getTradeState(), "SUCCESS"), - "支付结果非 SUCCESS"); - return PayOrderRespDTO.builder() - .outTradeNo(result.getOutTradeNo()) - .channelOrderNo(result.getTradeState()) - .channelUserId(result.getPayer() != null ? result.getPayer().getOpenid() : null) - .successTime(parseDateV3(result.getSuccessTime())) - .build(); + // TODO 芋艿;异常的处理; + return refund; } @Override @@ -229,27 +260,42 @@ public abstract class AbstractWxPayClient extends AbstractPayClient