1. 微信 App 支付 WxAppPayClient 实现

2. 优化微信支付的下单逻辑,增加 build request 公用方法
This commit is contained in:
YunaiV 2023-07-24 22:07:54 +08:00
parent 0fcc0072c2
commit 3a1694dea3
5 changed files with 91 additions and 41 deletions

View File

@ -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()) {

View File

@ -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);
} }
} }

View File

@ -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);

View File

@ -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);

View File

@ -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
}, },