Commit d224b6b9be9ae55755861fba9d306d5557e44e40

Authored by YunaiV
1 parent cbc61184

mall + pay:

1、调整微信 Lite 小程序支付的实现
yudao-framework/yudao-spring-boot-starter-biz-pay/src/main/java/cn/iocoder/yudao/framework/pay/core/client/impl/PayClientFactoryImpl.java
... ... @@ -61,7 +61,7 @@ public class PayClientFactoryImpl implements PayClientFactory {
61 61 // TODO @芋艿 WX_LITE WX_APP 如果不添加在 项目启动的时候去初始化会报错无法启动。所以我手动加了两个,具体需要你来配
62 62 switch (channelEnum) {
63 63 case WX_PUB: return (AbstractPayClient<Config>) new WxPubPayClient(channelId, (WxPayClientConfig) config);
64   - case WX_LITE: return (AbstractPayClient<Config>) new WXLitePayClient(channelId, (WxPayClientConfig) config); //微信小程序请求支付
  64 + case WX_LITE: return (AbstractPayClient<Config>) new WXLitePayClient(channelId, (WxPayClientConfig) config);
65 65 case WX_APP: return (AbstractPayClient<Config>) new WxPubPayClient(channelId, (WxPayClientConfig) config);
66 66 case WX_NATIVE: return (AbstractPayClient<Config>) new WXNativePayClient(channelId, (WxPayClientConfig) config);
67 67 case ALIPAY_WAP: return (AbstractPayClient<Config>) new AlipayWapPayClient(channelId, (AlipayPayClientConfig) config);
... ...
yudao-framework/yudao-spring-boot-starter-biz-pay/src/main/java/cn/iocoder/yudao/framework/pay/core/client/impl/weixin/WXLitePayClient.java
1 1 package cn.iocoder.yudao.framework.pay.core.client.impl.weixin;
2 2  
3   -import cn.hutool.core.bean.BeanUtil;
4   -import cn.hutool.core.date.DateUtil;
5   -import cn.hutool.core.date.LocalDateTimeUtil;
6   -import cn.hutool.core.lang.Assert;
7   -import cn.hutool.core.map.MapUtil;
8   -import cn.hutool.core.util.StrUtil;
9   -import cn.iocoder.yudao.framework.common.util.io.FileUtils;
10   -import cn.iocoder.yudao.framework.pay.core.client.dto.notify.PayNotifyReqDTO;
11   -import cn.iocoder.yudao.framework.pay.core.client.dto.notify.PayOrderNotifyRespDTO;
12   -import cn.iocoder.yudao.framework.pay.core.client.dto.order.PayOrderUnifiedReqDTO;
13   -import cn.iocoder.yudao.framework.pay.core.client.dto.order.PayOrderUnifiedRespDTO;
14   -import cn.iocoder.yudao.framework.pay.core.client.dto.refund.PayRefundUnifiedReqDTO;
15   -import cn.iocoder.yudao.framework.pay.core.client.dto.refund.PayRefundUnifiedRespDTO;
16   -import cn.iocoder.yudao.framework.pay.core.client.impl.AbstractPayClient;
17 3 import cn.iocoder.yudao.framework.pay.core.enums.PayChannelEnum;
18   -import com.github.binarywang.wxpay.bean.notify.WxPayOrderNotifyResult;
19   -import com.github.binarywang.wxpay.bean.notify.WxPayOrderNotifyV3Result;
20   -import com.github.binarywang.wxpay.bean.order.WxPayMpOrderResult;
21   -import com.github.binarywang.wxpay.bean.request.WxPayUnifiedOrderRequest;
22   -import com.github.binarywang.wxpay.bean.request.WxPayUnifiedOrderV3Request;
23   -import com.github.binarywang.wxpay.bean.result.WxPayUnifiedOrderV3Result;
24   -import com.github.binarywang.wxpay.bean.result.enums.TradeTypeEnum;
25   -import com.github.binarywang.wxpay.config.WxPayConfig;
26   -import com.github.binarywang.wxpay.constant.WxPayConstants;
27   -import com.github.binarywang.wxpay.exception.WxPayException;
28   -import com.github.binarywang.wxpay.service.WxPayService;
29   -import com.github.binarywang.wxpay.service.impl.WxPayServiceImpl;
30 4 import lombok.extern.slf4j.Slf4j;
31 5  
32   -import java.time.ZoneId;
33   -import java.util.Date;
34   -import java.util.Objects;
35   -
36 6 /**
37   - * 微信小程序下支付
  7 + * 微信支付(小程序)的 PayClient 实现类
  8 + *
  9 + * 由于公众号和小程序的微信支付逻辑一致,所以直接进行继承
38 10 *
39 11 * @author zwy
40 12 */
41 13 @Slf4j
42   -public class WXLitePayClient extends AbstractPayClient<WxPayClientConfig> {
43   -
44   - private WxPayService client;
  14 +public class WXLitePayClient extends WxPubPayClient {
45 15  
46 16 public WXLitePayClient(Long channelId, WxPayClientConfig config) {
47 17 super(channelId, PayChannelEnum.WX_LITE.getCode(), config);
48 18 }
49 19  
50   - @Override
51   - protected void doInit() {
52   - WxPayConfig payConfig = new WxPayConfig();
53   - BeanUtil.copyProperties(config, payConfig, "privateKeyContent","privateCertContent");
54   - payConfig.setTradeType(WxPayConstants.TradeType.JSAPI); // 设置使用 JS API 支付方式
55   -// if (StrUtil.isNotEmpty(config.getKeyContent())) {
56   -// payConfig.setKeyContent(config.getKeyContent().getBytes(StandardCharsets.UTF_8));
57   -// }
58   - if (StrUtil.isNotEmpty(config.getPrivateKeyContent())) {
59   - // weixin-pay-java 存在 BUG,无法直接设置内容,所以创建临时文件来解决
60   - payConfig.setPrivateKeyPath(FileUtils.createTempFile(config.getPrivateKeyContent()).getPath());
61   - }
62   - if (StrUtil.isNotEmpty(config.getPrivateCertContent())) {
63   - // weixin-pay-java 存在 BUG,无法直接设置内容,所以创建临时文件来解决
64   - payConfig.setPrivateCertPath(FileUtils.createTempFile(config.getPrivateCertContent()).getPath());
65   - }
66   - // 真实客户端
67   - this.client = new WxPayServiceImpl();
68   - client.setConfig(payConfig);
69   - }
70   -
71   - @Override
72   - public PayOrderUnifiedRespDTO doUnifiedOrder(PayOrderUnifiedReqDTO reqDTO) {
73   - throw new UnsupportedOperationException();
74   -// WxPayMpOrderResult response;
75   -// try {
76   -// switch (config.getApiVersion()) {
77   -// case WXPayClientConfig.API_VERSION_V2:
78   -// response = this.unifiedOrderV2(reqDTO);
79   -// break;
80   -// case WXPayClientConfig.API_VERSION_V3:
81   -// WxPayUnifiedOrderV3Result.JsapiResult responseV3 = this.unifiedOrderV3(reqDTO);
82   -// // 将 V3 的结果,统一转换成 V2。返回的字段是一致的
83   -// response = new WxPayMpOrderResult();
84   -// BeanUtil.copyProperties(responseV3, response, true);
85   -// break;
86   -// default:
87   -// throw new IllegalArgumentException(String.format("未知的 API 版本(%s)", config.getApiVersion()));
88   -// }
89   -// } catch (WxPayException e) {
90   -// log.error("[unifiedOrder][request({}) 发起支付失败,原因({})]", toJsonString(reqDTO), e);
91   -// return PayCommonResult.build(ObjectUtils.defaultIfNull(e.getErrCode(), e.getReturnCode(), "CustomErrorCode"),
92   -// ObjectUtils.defaultIfNull(e.getErrCodeDes(), e.getCustomErrorMsg()), null, codeMapping);
93   -// }
94   -// return PayCommonResult.build(CODE_SUCCESS, MESSAGE_SUCCESS, response, codeMapping);
95   - }
96   -
97   - private WxPayMpOrderResult unifiedOrderV2(PayOrderUnifiedReqDTO reqDTO) throws WxPayException {
98   - // 构建 WxPayUnifiedOrderRequest 对象
99   - WxPayUnifiedOrderRequest request = WxPayUnifiedOrderRequest.newBuilder()
100   - .outTradeNo(reqDTO.getMerchantOrderId())
101   - .body(reqDTO.getBody())
102   - .totalFee(reqDTO.getAmount()) // 单位分
103   - .timeExpire(DateUtil.format(reqDTO.getExpireTime(), "yyyyMMddHHmmss")) // v2的时间格式
104   - .spbillCreateIp(reqDTO.getUserIp())
105   - .openid(getOpenid(reqDTO))
106   - .notifyUrl(reqDTO.getNotifyUrl())
107   - .build();
108   - // 执行请求
109   - return client.createOrder(request);
110   - }
111   -
112   - private WxPayUnifiedOrderV3Result.JsapiResult unifiedOrderV3(PayOrderUnifiedReqDTO reqDTO) throws WxPayException {
113   - // 构建 WxPayUnifiedOrderRequest 对象
114   - WxPayUnifiedOrderV3Request request = new WxPayUnifiedOrderV3Request();
115   - request.setOutTradeNo(reqDTO.getMerchantOrderId());
116   -
117   - request.setDescription(reqDTO.getBody());
118   - request.setAmount(new WxPayUnifiedOrderV3Request
119   - .Amount()
120   - .setTotal(reqDTO.getAmount())); // 单位分
121   - request.setTimeExpire(DateUtil.format(Date.from(reqDTO.getExpireTime().atZone(ZoneId.systemDefault()).toInstant()), "yyyy-MM-dd'T'HH:mm:ssXXX")); // v3的时间格式
122   - request.setPayer(new WxPayUnifiedOrderV3Request.Payer().setOpenid(getOpenid(reqDTO)));
123   - request.setSceneInfo(new WxPayUnifiedOrderV3Request.SceneInfo().setPayerClientIp(reqDTO.getUserIp()));
124   - request.setNotifyUrl(reqDTO.getNotifyUrl());
125   - // 执行请求
126   - return client.createOrderV3(TradeTypeEnum.JSAPI, request);
127   - }
128   -
129   - private static String getOpenid(PayOrderUnifiedReqDTO reqDTO) {
130   - String openid = MapUtil.getStr(reqDTO.getChannelExtras(), "openid");
131   - if (StrUtil.isEmpty(openid)) {
132   - throw new IllegalArgumentException("支付请求的 openid 不能为空!");
133   - }
134   - return openid;
135   - }
136   -
137   - /**
138   - *
139   - * 微信支付回调 分 v2 和v3 的处理方式
140   - *
141   - * @param data 通知结果
142   - * @return 支付回调对象
143   - * @throws WxPayException 微信异常类
144   - */
145   -// @Override
146   - public PayOrderNotifyRespDTO parseOrderNotify(PayNotifyReqDTO data) throws WxPayException {
147   - log.info("[parseOrderNotify][微信支付回调data数据:{}]", data.getBody());
148   - // 微信支付 v2 回调结果处理
149   - switch (config.getApiVersion()) {
150   - case WxPayClientConfig.API_VERSION_V2:
151   - return parseOrderNotifyV2(data);
152   - case WxPayClientConfig.API_VERSION_V3:
153   - return parseOrderNotifyV3(data);
154   - default:
155   - throw new IllegalArgumentException(String.format("未知的 API 版本(%s)", config.getApiVersion()));
156   - }
157   - }
158   -
159   - private PayOrderNotifyRespDTO parseOrderNotifyV3(PayNotifyReqDTO data) throws WxPayException {
160   - WxPayOrderNotifyV3Result wxPayOrderNotifyV3Result = client.parseOrderNotifyV3Result(data.getBody(), null);
161   - WxPayOrderNotifyV3Result.DecryptNotifyResult result = wxPayOrderNotifyV3Result.getResult();
162   - // 转换结果
163   - Assert.isTrue(Objects.equals(wxPayOrderNotifyV3Result.getResult().getTradeState(), "SUCCESS"),
164   - "支付结果非 SUCCESS");
165   -
166   - return PayOrderNotifyRespDTO
167   - .builder()
168   - .orderExtensionNo(result.getOutTradeNo())
169   - .channelOrderNo(result.getTransactionId())
170   - .channelUserId(result.getPayer().getOpenid())
171   - .successTime(LocalDateTimeUtil.parse(result.getSuccessTime(), "yyyy-MM-dd'T'HH:mm:ssXXX"))
172   - .build();
173   - }
174   -
175   - private PayOrderNotifyRespDTO parseOrderNotifyV2(PayNotifyReqDTO data) throws WxPayException {
176   - WxPayOrderNotifyResult notifyResult = client.parseOrderNotifyResult(data.getBody());
177   - Assert.isTrue(Objects.equals(notifyResult.getResultCode(), "SUCCESS"), "支付结果非 SUCCESS");
178   - // 转换结果
179   - return PayOrderNotifyRespDTO
180   - .builder()
181   - .orderExtensionNo(notifyResult.getOutTradeNo())
182   - .channelOrderNo(notifyResult.getTransactionId())
183   - .channelUserId(notifyResult.getOpenid())
184   - .successTime(LocalDateTimeUtil.parse(notifyResult.getTimeEnd(), "yyyyMMddHHmmss"))
185   - .build();
186   -
187   - }
188   -
189   - @Override
190   - protected PayRefundUnifiedRespDTO doUnifiedRefund(PayRefundUnifiedReqDTO reqDTO) {
191   - //TODO 需要实现
192   - throw new UnsupportedOperationException();
193   - }
194   -
195 20 }
... ...
yudao-framework/yudao-spring-boot-starter-biz-pay/src/main/java/cn/iocoder/yudao/framework/pay/core/client/impl/weixin/WxPubPayClient.java
... ... @@ -28,6 +28,10 @@ public class WxPubPayClient extends AbstractWxPayClient {
28 28 super(channelId, PayChannelEnum.WX_PUB.getCode(), config);
29 29 }
30 30  
  31 + protected WxPubPayClient(Long channelId, String channelCode, WxPayClientConfig config) {
  32 + super(channelId, channelCode, config);
  33 + }
  34 +
31 35 @Override
32 36 protected void doInit() {
33 37 super.doInit(WxPayConstants.TradeType.JSAPI);
... ...