mirror of
				https://github.com/YunaiV/ruoyi-vue-pro.git
				synced 2025-10-31 18:49:06 +08:00 
			
		
		
		
	1. 微信 App 支付 WxAppPayClient 实现
2. 优化微信支付的下单逻辑,增加 build request 公用方法
This commit is contained in:
		| @ -113,6 +113,41 @@ public abstract class AbstractWxPayClient extends AbstractPayClient<WxPayClientC | |||||||
|     protected abstract PayOrderRespDTO doUnifiedOrderV3(PayOrderUnifiedReqDTO reqDTO) |     protected abstract PayOrderRespDTO doUnifiedOrderV3(PayOrderUnifiedReqDTO reqDTO) | ||||||
|             throws WxPayException; |             throws WxPayException; | ||||||
|  |  | ||||||
|  |     /** | ||||||
|  |      * 【V2】创建微信下单请求 | ||||||
|  |      * | ||||||
|  |      * @param reqDTO 下信息 | ||||||
|  |      * @return 下单请求 | ||||||
|  |      */ | ||||||
|  |     protected WxPayUnifiedOrderRequest buildPayUnifiedOrderRequestV2(PayOrderUnifiedReqDTO reqDTO) { | ||||||
|  |         return WxPayUnifiedOrderRequest.newBuilder() | ||||||
|  |                 .outTradeNo(reqDTO.getOutTradeNo()) | ||||||
|  |                 .body(reqDTO.getSubject()) | ||||||
|  |                 .detail(reqDTO.getBody()) | ||||||
|  |                 .totalFee(reqDTO.getPrice()) // 单位分 | ||||||
|  |                 .timeExpire(formatDateV2(reqDTO.getExpireTime())) | ||||||
|  |                 .spbillCreateIp(reqDTO.getUserIp()) | ||||||
|  |                 .notifyUrl(reqDTO.getNotifyUrl()) | ||||||
|  |                 .build(); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     /** | ||||||
|  |      * 【V3】创建微信下单请求 | ||||||
|  |      * | ||||||
|  |      * @param reqDTO 下信息 | ||||||
|  |      * @return 下单请求 | ||||||
|  |      */ | ||||||
|  |     protected WxPayUnifiedOrderV3Request buildPayUnifiedOrderRequestV3(PayOrderUnifiedReqDTO reqDTO) { | ||||||
|  |         WxPayUnifiedOrderV3Request request = new WxPayUnifiedOrderV3Request(); | ||||||
|  |         request.setOutTradeNo(reqDTO.getOutTradeNo()); | ||||||
|  |         request.setDescription(reqDTO.getSubject()); | ||||||
|  |         request.setAmount(new WxPayUnifiedOrderV3Request.Amount().setTotal(reqDTO.getPrice())); // 单位分 | ||||||
|  |         request.setTimeExpire(formatDateV3(reqDTO.getExpireTime())); | ||||||
|  |         request.setSceneInfo(new WxPayUnifiedOrderV3Request.SceneInfo().setPayerClientIp(reqDTO.getUserIp())); | ||||||
|  |         request.setNotifyUrl(reqDTO.getNotifyUrl()); | ||||||
|  |         return request; | ||||||
|  |     } | ||||||
|  |  | ||||||
|     @Override |     @Override | ||||||
|     public PayOrderRespDTO doParseOrderNotify(Map<String, String> params, String body) throws WxPayException { |     public PayOrderRespDTO doParseOrderNotify(Map<String, String> params, String body) throws WxPayException { | ||||||
|         switch (config.getApiVersion()) { |         switch (config.getApiVersion()) { | ||||||
|  | |||||||
| @ -3,10 +3,28 @@ package cn.iocoder.yudao.framework.pay.core.client.impl.weixin; | |||||||
| import cn.iocoder.yudao.framework.pay.core.client.dto.order.PayOrderRespDTO; | import cn.iocoder.yudao.framework.pay.core.client.dto.order.PayOrderRespDTO; | ||||||
| import cn.iocoder.yudao.framework.pay.core.client.dto.order.PayOrderUnifiedReqDTO; | import cn.iocoder.yudao.framework.pay.core.client.dto.order.PayOrderUnifiedReqDTO; | ||||||
| import cn.iocoder.yudao.framework.pay.core.enums.channel.PayChannelEnum; | import cn.iocoder.yudao.framework.pay.core.enums.channel.PayChannelEnum; | ||||||
|  | import cn.iocoder.yudao.framework.pay.core.enums.order.PayOrderDisplayModeEnum; | ||||||
|  | import com.github.binarywang.wxpay.bean.order.WxPayMpOrderResult; | ||||||
|  | import com.github.binarywang.wxpay.bean.request.WxPayUnifiedOrderRequest; | ||||||
|  | import com.github.binarywang.wxpay.bean.request.WxPayUnifiedOrderV3Request; | ||||||
|  | import com.github.binarywang.wxpay.bean.result.WxPayUnifiedOrderV3Result; | ||||||
|  | import com.github.binarywang.wxpay.bean.result.enums.TradeTypeEnum; | ||||||
| import com.github.binarywang.wxpay.constant.WxPayConstants; | import com.github.binarywang.wxpay.constant.WxPayConstants; | ||||||
| import com.github.binarywang.wxpay.exception.WxPayException; | import com.github.binarywang.wxpay.exception.WxPayException; | ||||||
|  | import lombok.extern.slf4j.Slf4j; | ||||||
|  |  | ||||||
| // TODO 芋艿:未实现 | import static cn.iocoder.yudao.framework.common.util.json.JsonUtils.toJsonString; | ||||||
|  |  | ||||||
|  | /** | ||||||
|  |  * 微信支付【App 支付】的 PayClient 实现类 | ||||||
|  |  * | ||||||
|  |  * 文档:<a href="https://pay.weixin.qq.com/wiki/doc/apiv3/open/pay/chapter2_5_3.shtml">App 支付</a> | ||||||
|  |  * | ||||||
|  |  * // TODO 芋艿:未详细测试,因为手头没 App | ||||||
|  |  * | ||||||
|  |  * @author 芋道源码 | ||||||
|  |  */ | ||||||
|  | @Slf4j | ||||||
| public class WxAppPayClient extends AbstractWxPayClient { | public class WxAppPayClient extends AbstractWxPayClient { | ||||||
|  |  | ||||||
|     public WxAppPayClient(Long channelId, WxPayClientConfig config) { |     public WxAppPayClient(Long channelId, WxPayClientConfig config) { | ||||||
| @ -20,12 +38,26 @@ public class WxAppPayClient extends AbstractWxPayClient { | |||||||
|  |  | ||||||
|     @Override |     @Override | ||||||
|     protected PayOrderRespDTO doUnifiedOrderV2(PayOrderUnifiedReqDTO reqDTO) throws WxPayException { |     protected PayOrderRespDTO doUnifiedOrderV2(PayOrderUnifiedReqDTO reqDTO) throws WxPayException { | ||||||
|         return null; |         // 构建 WxPayUnifiedOrderRequest 对象 | ||||||
|  |         WxPayUnifiedOrderRequest request = buildPayUnifiedOrderRequestV2(reqDTO); | ||||||
|  |         // 执行请求 | ||||||
|  |         WxPayMpOrderResult response = client.createOrder(request); | ||||||
|  |  | ||||||
|  |         // 转换结果 | ||||||
|  |         return PayOrderRespDTO.waitingOf(PayOrderDisplayModeEnum.APP.getMode(), toJsonString(response), | ||||||
|  |                 reqDTO.getOutTradeNo(), response); | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     @Override |     @Override | ||||||
|     protected PayOrderRespDTO doUnifiedOrderV3(PayOrderUnifiedReqDTO reqDTO) throws WxPayException { |     protected PayOrderRespDTO doUnifiedOrderV3(PayOrderUnifiedReqDTO reqDTO) throws WxPayException { | ||||||
|         return null; |         // 构建 WxPayUnifiedOrderV3Request 对象 | ||||||
|  |         WxPayUnifiedOrderV3Request request = buildPayUnifiedOrderRequestV3(reqDTO); | ||||||
|  |         // 执行请求 | ||||||
|  |         WxPayUnifiedOrderV3Result.JsapiResult response = client.createOrderV3(TradeTypeEnum.APP, request); | ||||||
|  |  | ||||||
|  |         // 转换结果 | ||||||
|  |         return PayOrderRespDTO.waitingOf(PayOrderDisplayModeEnum.APP.getMode(), toJsonString(response), | ||||||
|  |                 reqDTO.getOutTradeNo(), response); | ||||||
|     } |     } | ||||||
|  |  | ||||||
| } | } | ||||||
|  | |||||||
| @ -34,16 +34,7 @@ public class WxNativePayClient extends AbstractWxPayClient { | |||||||
|     @Override |     @Override | ||||||
|     protected PayOrderRespDTO doUnifiedOrderV2(PayOrderUnifiedReqDTO reqDTO) throws WxPayException { |     protected PayOrderRespDTO doUnifiedOrderV2(PayOrderUnifiedReqDTO reqDTO) throws WxPayException { | ||||||
|         // 构建 WxPayUnifiedOrderRequest 对象 |         // 构建 WxPayUnifiedOrderRequest 对象 | ||||||
|         WxPayUnifiedOrderRequest request = WxPayUnifiedOrderRequest.newBuilder() |         WxPayUnifiedOrderRequest request = buildPayUnifiedOrderRequestV2(reqDTO); | ||||||
|                 .outTradeNo(reqDTO.getOutTradeNo()) |  | ||||||
|                 .body(reqDTO.getSubject()) |  | ||||||
|                 .detail(reqDTO.getBody()) |  | ||||||
|                 .totalFee(reqDTO.getPrice()) // 单位分 |  | ||||||
|                 .productId(reqDTO.getOutTradeNo()) |  | ||||||
|                 .timeExpire(formatDateV2(reqDTO.getExpireTime())) |  | ||||||
|                 .spbillCreateIp(reqDTO.getUserIp()) |  | ||||||
|                 .notifyUrl(reqDTO.getNotifyUrl()) |  | ||||||
|                 .build(); |  | ||||||
|         // 执行请求 |         // 执行请求 | ||||||
|         WxPayNativeOrderResult response = client.createOrder(request); |         WxPayNativeOrderResult response = client.createOrder(request); | ||||||
|  |  | ||||||
| @ -54,14 +45,8 @@ public class WxNativePayClient extends AbstractWxPayClient { | |||||||
|  |  | ||||||
|     @Override |     @Override | ||||||
|     protected PayOrderRespDTO doUnifiedOrderV3(PayOrderUnifiedReqDTO reqDTO) throws WxPayException { |     protected PayOrderRespDTO doUnifiedOrderV3(PayOrderUnifiedReqDTO reqDTO) throws WxPayException { | ||||||
|         // 构建 WxPayUnifiedOrderRequest 对象 |         // 构建 WxPayUnifiedOrderV3Request 对象 | ||||||
|         WxPayUnifiedOrderV3Request request = new WxPayUnifiedOrderV3Request() |         WxPayUnifiedOrderV3Request request = buildPayUnifiedOrderRequestV3(reqDTO); | ||||||
|                 .setOutTradeNo(reqDTO.getOutTradeNo()) |  | ||||||
|                 .setDescription(reqDTO.getSubject()) |  | ||||||
|                 .setAmount(new WxPayUnifiedOrderV3Request.Amount().setTotal(reqDTO.getPrice())) // 单位分 |  | ||||||
|                 .setTimeExpire(formatDateV3(reqDTO.getExpireTime())) |  | ||||||
|                 .setSceneInfo(new WxPayUnifiedOrderV3Request.SceneInfo().setPayerClientIp(reqDTO.getUserIp())) |  | ||||||
|                 .setNotifyUrl(reqDTO.getNotifyUrl()); |  | ||||||
|         // 执行请求 |         // 执行请求 | ||||||
|         String response = client.createOrderV3(TradeTypeEnum.NATIVE, request); |         String response = client.createOrderV3(TradeTypeEnum.NATIVE, request); | ||||||
|  |  | ||||||
|  | |||||||
| @ -4,7 +4,6 @@ import cn.hutool.core.map.MapUtil; | |||||||
| import cn.hutool.core.util.StrUtil; | import cn.hutool.core.util.StrUtil; | ||||||
| import cn.iocoder.yudao.framework.pay.core.client.dto.order.PayOrderRespDTO; | import cn.iocoder.yudao.framework.pay.core.client.dto.order.PayOrderRespDTO; | ||||||
| import cn.iocoder.yudao.framework.pay.core.client.dto.order.PayOrderUnifiedReqDTO; | import cn.iocoder.yudao.framework.pay.core.client.dto.order.PayOrderUnifiedReqDTO; | ||||||
| import cn.iocoder.yudao.framework.pay.core.client.dto.refund.PayRefundRespDTO; |  | ||||||
| import cn.iocoder.yudao.framework.pay.core.enums.channel.PayChannelEnum; | import cn.iocoder.yudao.framework.pay.core.enums.channel.PayChannelEnum; | ||||||
| import cn.iocoder.yudao.framework.pay.core.enums.order.PayOrderDisplayModeEnum; | import cn.iocoder.yudao.framework.pay.core.enums.order.PayOrderDisplayModeEnum; | ||||||
| import com.github.binarywang.wxpay.bean.order.WxPayMpOrderResult; | import com.github.binarywang.wxpay.bean.order.WxPayMpOrderResult; | ||||||
| @ -45,16 +44,8 @@ public class WxPubPayClient extends AbstractWxPayClient { | |||||||
|     @Override |     @Override | ||||||
|     protected PayOrderRespDTO doUnifiedOrderV2(PayOrderUnifiedReqDTO reqDTO) throws WxPayException { |     protected PayOrderRespDTO doUnifiedOrderV2(PayOrderUnifiedReqDTO reqDTO) throws WxPayException { | ||||||
|         // 构建 WxPayUnifiedOrderRequest 对象 |         // 构建 WxPayUnifiedOrderRequest 对象 | ||||||
|         WxPayUnifiedOrderRequest request = WxPayUnifiedOrderRequest.newBuilder() |         WxPayUnifiedOrderRequest request = buildPayUnifiedOrderRequestV2(reqDTO) | ||||||
|                 .outTradeNo(reqDTO.getOutTradeNo()) |                 .setOpenid(getOpenid(reqDTO)); | ||||||
|                 .body(reqDTO.getSubject()) |  | ||||||
|                 .detail(reqDTO.getBody()) |  | ||||||
|                 .totalFee(reqDTO.getPrice()) // 单位分 |  | ||||||
|                 .timeExpire(formatDateV2(reqDTO.getExpireTime())) |  | ||||||
|                 .spbillCreateIp(reqDTO.getUserIp()) |  | ||||||
|                 .openid(getOpenid(reqDTO)) |  | ||||||
|                 .notifyUrl(reqDTO.getNotifyUrl()) |  | ||||||
|                 .build(); |  | ||||||
|         // 执行请求 |         // 执行请求 | ||||||
|         WxPayMpOrderResult response = client.createOrder(request); |         WxPayMpOrderResult response = client.createOrder(request); | ||||||
|  |  | ||||||
| @ -66,14 +57,8 @@ public class WxPubPayClient extends AbstractWxPayClient { | |||||||
|     @Override |     @Override | ||||||
|     protected PayOrderRespDTO doUnifiedOrderV3(PayOrderUnifiedReqDTO reqDTO) throws WxPayException { |     protected PayOrderRespDTO doUnifiedOrderV3(PayOrderUnifiedReqDTO reqDTO) throws WxPayException { | ||||||
|         // 构建 WxPayUnifiedOrderRequest 对象 |         // 构建 WxPayUnifiedOrderRequest 对象 | ||||||
|         WxPayUnifiedOrderV3Request request = new WxPayUnifiedOrderV3Request(); |         WxPayUnifiedOrderV3Request request = buildPayUnifiedOrderRequestV3(reqDTO) | ||||||
|         request.setOutTradeNo(reqDTO.getOutTradeNo()); |                 .setPayer(new WxPayUnifiedOrderV3Request.Payer().setOpenid(getOpenid(reqDTO))); | ||||||
|         request.setDescription(reqDTO.getSubject()); |  | ||||||
|         request.setAmount(new WxPayUnifiedOrderV3Request.Amount().setTotal(reqDTO.getPrice())); // 单位分 |  | ||||||
|         request.setTimeExpire(formatDateV3(reqDTO.getExpireTime())); |  | ||||||
|         request.setPayer(new WxPayUnifiedOrderV3Request.Payer().setOpenid(getOpenid(reqDTO))); |  | ||||||
|         request.setSceneInfo(new WxPayUnifiedOrderV3Request.SceneInfo().setPayerClientIp(reqDTO.getUserIp())); |  | ||||||
|         request.setNotifyUrl(reqDTO.getNotifyUrl()); |  | ||||||
|         // 执行请求 |         // 执行请求 | ||||||
|         WxPayUnifiedOrderV3Result.JsapiResult response = client.createOrderV3(TradeTypeEnum.JSAPI, request); |         WxPayUnifiedOrderV3Result.JsapiResult response = client.createOrderV3(TradeTypeEnum.JSAPI, request); | ||||||
|  |  | ||||||
|  | |||||||
| @ -212,6 +212,16 @@ export default { | |||||||
|         return; |         return; | ||||||
|       } |       } | ||||||
|  |  | ||||||
|  |       // 微信公众号、小程序支付,无法在 PC 网页中进行 | ||||||
|  |       if (channelCode === PayChannelEnum.WX_PUB.code) { | ||||||
|  |         this.$message.error('微信公众号支付:不支持 PC 网站'); | ||||||
|  |         return; | ||||||
|  |       } | ||||||
|  |       if (channelCode === PayChannelEnum.WX_LITE.code) { | ||||||
|  |         this.$message.error('微信小程序:不支持 PC 网站'); | ||||||
|  |         return; | ||||||
|  |       } | ||||||
|  |  | ||||||
|       // 默认的提交处理 |       // 默认的提交处理 | ||||||
|       this.submit0(channelCode) |       this.submit0(channelCode) | ||||||
|     }, |     }, | ||||||
| @ -292,7 +302,10 @@ export default { | |||||||
|     /** 提交支付后(App) */ |     /** 提交支付后(App) */ | ||||||
|     displayApp(channelCode, data) { |     displayApp(channelCode, data) { | ||||||
|       if (channelCode === PayChannelEnum.ALIPAY_APP.code) { |       if (channelCode === PayChannelEnum.ALIPAY_APP.code) { | ||||||
|         this.$message.error('支付宝 App 无法在网页支付!'); |         this.$message.error('支付宝 App 支付:无法在网页支付!'); | ||||||
|  |       } | ||||||
|  |       if (channelCode === PayChannelEnum.WX_APP.code) { | ||||||
|  |         this.$message.error('微信 App 支付:无法在网页支付!'); | ||||||
|       } |       } | ||||||
|       this.submitLoading = false |       this.submitLoading = false | ||||||
|     }, |     }, | ||||||
|  | |||||||
		Reference in New Issue
	
	Block a user
	 YunaiV
					YunaiV