mall + pay:

1、初步完成微信扫码支付,暂时缺少状态的处理
This commit is contained in:
YunaiV 2023-07-08 00:08:05 +08:00
parent 3f33ca2d6b
commit d76bc7aa82
7 changed files with 107 additions and 11 deletions

View File

@ -1,6 +1,5 @@
package cn.iocoder.yudao.framework.pay.core.client.dto.order; package cn.iocoder.yudao.framework.pay.core.client.dto.order;
import lombok.AllArgsConstructor;
import lombok.Data; import lombok.Data;
/** /**

View File

@ -5,10 +5,7 @@ import cn.iocoder.yudao.framework.pay.core.client.PayClient;
import cn.iocoder.yudao.framework.pay.core.client.PayClientConfig; import cn.iocoder.yudao.framework.pay.core.client.PayClientConfig;
import cn.iocoder.yudao.framework.pay.core.client.PayClientFactory; import cn.iocoder.yudao.framework.pay.core.client.PayClientFactory;
import cn.iocoder.yudao.framework.pay.core.client.impl.alipay.*; import cn.iocoder.yudao.framework.pay.core.client.impl.alipay.*;
import cn.iocoder.yudao.framework.pay.core.client.impl.weixin.WxLitePayClient; import cn.iocoder.yudao.framework.pay.core.client.impl.weixin.*;
import cn.iocoder.yudao.framework.pay.core.client.impl.weixin.WXNativePayClient;
import cn.iocoder.yudao.framework.pay.core.client.impl.weixin.WxPayClientConfig;
import cn.iocoder.yudao.framework.pay.core.client.impl.weixin.WxPubPayClient;
import cn.iocoder.yudao.framework.pay.core.enums.PayChannelEnum; import cn.iocoder.yudao.framework.pay.core.enums.PayChannelEnum;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
@ -58,11 +55,14 @@ public class PayClientFactoryImpl implements PayClientFactory {
PayChannelEnum channelEnum = PayChannelEnum.getByCode(channelCode); PayChannelEnum channelEnum = PayChannelEnum.getByCode(channelCode);
Assert.notNull(channelEnum, String.format("支付渠道(%s) 为空", channelEnum)); Assert.notNull(channelEnum, String.format("支付渠道(%s) 为空", channelEnum));
// 创建客户端 // 创建客户端
// TODO @芋艿 WX_LITE WX_APP 如果不添加在 项目启动的时候去初始化会报错无法启动所以我手动加了两个具体需要你来配 // TODO @芋艿 WX_APP 如果不添加在 项目启动的时候去初始化会报错无法启动所以我手动加了两个具体需要你来配
switch (channelEnum) { switch (channelEnum) {
// 微信支付
case WX_PUB: return (AbstractPayClient<Config>) new WxPubPayClient(channelId, (WxPayClientConfig) config); case WX_PUB: return (AbstractPayClient<Config>) new WxPubPayClient(channelId, (WxPayClientConfig) config);
case WX_LITE: return (AbstractPayClient<Config>) new WxLitePayClient(channelId, (WxPayClientConfig) config); case WX_LITE: return (AbstractPayClient<Config>) new WxLitePayClient(channelId, (WxPayClientConfig) config);
case WX_APP: return (AbstractPayClient<Config>) new WxPubPayClient(channelId, (WxPayClientConfig) config); case WX_APP: return (AbstractPayClient<Config>) new WxPubPayClient(channelId, (WxPayClientConfig) config);
case WX_BAR: return (AbstractPayClient<Config>) new WxBarPayClient(channelId, (WxPayClientConfig) config);
// 支付宝支付
case WX_NATIVE: return (AbstractPayClient<Config>) new WXNativePayClient(channelId, (WxPayClientConfig) config); case WX_NATIVE: return (AbstractPayClient<Config>) new WXNativePayClient(channelId, (WxPayClientConfig) config);
case ALIPAY_WAP: return (AbstractPayClient<Config>) new AlipayWapPayClient(channelId, (AlipayPayClientConfig) config); case ALIPAY_WAP: return (AbstractPayClient<Config>) new AlipayWapPayClient(channelId, (AlipayPayClientConfig) config);
case ALIPAY_QR: return (AbstractPayClient<Config>) new AlipayQrPayClient(channelId, (AlipayPayClientConfig) config); case ALIPAY_QR: return (AbstractPayClient<Config>) new AlipayQrPayClient(channelId, (AlipayPayClientConfig) config);

View File

@ -0,0 +1,68 @@
package cn.iocoder.yudao.framework.pay.core.client.impl.weixin;
import cn.hutool.core.map.MapUtil;
import cn.hutool.core.util.StrUtil;
import cn.iocoder.yudao.framework.common.util.json.JsonUtils;
import cn.iocoder.yudao.framework.pay.core.client.dto.order.PayOrderUnifiedReqDTO;
import cn.iocoder.yudao.framework.pay.core.client.dto.order.PayOrderUnifiedRespDTO;
import cn.iocoder.yudao.framework.pay.core.client.dto.refund.PayRefundUnifiedReqDTO;
import cn.iocoder.yudao.framework.pay.core.client.dto.refund.PayRefundUnifiedRespDTO;
import cn.iocoder.yudao.framework.pay.core.enums.PayChannelEnum;
import cn.iocoder.yudao.framework.pay.core.enums.PayDisplayModeEnum;
import com.github.binarywang.wxpay.bean.request.WxPayMicropayRequest;
import com.github.binarywang.wxpay.bean.result.WxPayMicropayResult;
import com.github.binarywang.wxpay.constant.WxPayConstants;
import com.github.binarywang.wxpay.exception.WxPayException;
public class WxBarPayClient extends AbstractWxPayClient {
public WxBarPayClient(Long channelId, WxPayClientConfig config) {
super(channelId, PayChannelEnum.WX_BAR.getCode(), config);
}
@Override
protected void doInit() {
super.doInit(WxPayConstants.TradeType.MICROPAY);
}
@Override
protected PayOrderUnifiedRespDTO doUnifiedOrderV2(PayOrderUnifiedReqDTO reqDTO) throws WxPayException {
// 构建 WxPayMicropayRequest 对象
WxPayMicropayRequest request = WxPayMicropayRequest.newBuilder()
.outTradeNo(reqDTO.getMerchantOrderId())
.body(reqDTO.getSubject())
.detail(reqDTO.getBody())
.totalFee(reqDTO.getAmount()) // 单位分
.timeExpire(formatDateV2(reqDTO.getExpireTime()))
.spbillCreateIp(reqDTO.getUserIp())
.authCode(getAuthCode(reqDTO))
.build();
// 执行请求
WxPayMicropayResult response = client.micropay(request);
// 转换结果
// TODO 芋艿这里后面要看看
return new PayOrderUnifiedRespDTO().setDisplayMode(PayDisplayModeEnum.CUSTOM.getMode())
.setDisplayContent(JsonUtils.toJsonString(response));
}
@Override
protected PayOrderUnifiedRespDTO doUnifiedOrderV3(PayOrderUnifiedReqDTO reqDTO) throws WxPayException {
return doUnifiedOrderV2(reqDTO);
}
@Override
protected PayRefundUnifiedRespDTO doUnifiedRefund(PayRefundUnifiedReqDTO reqDTO) {
return null;
}
// ========== 各种工具方法 ==========
static String getAuthCode(PayOrderUnifiedReqDTO reqDTO) {
String authCode = MapUtil.getStr(reqDTO.getChannelExtras(), "authCode");
if (StrUtil.isEmpty(authCode)) {
throw new IllegalArgumentException("支付请求的 authCode 不能为空!");
}
return authCode;
}
}

View File

@ -42,7 +42,8 @@ public class WxPubPayClient extends AbstractWxPayClient {
// 构建 WxPayUnifiedOrderRequest 对象 // 构建 WxPayUnifiedOrderRequest 对象
WxPayUnifiedOrderRequest request = WxPayUnifiedOrderRequest.newBuilder() WxPayUnifiedOrderRequest request = WxPayUnifiedOrderRequest.newBuilder()
.outTradeNo(reqDTO.getMerchantOrderId()) .outTradeNo(reqDTO.getMerchantOrderId())
.body(reqDTO.getBody()) .body(reqDTO.getSubject())
.detail(reqDTO.getBody())
.totalFee(reqDTO.getAmount()) // 单位分 .totalFee(reqDTO.getAmount()) // 单位分
.timeExpire(formatDateV2(reqDTO.getExpireTime())) .timeExpire(formatDateV2(reqDTO.getExpireTime()))
.spbillCreateIp(reqDTO.getUserIp()) .spbillCreateIp(reqDTO.getUserIp())
@ -62,7 +63,7 @@ public class WxPubPayClient extends AbstractWxPayClient {
// 构建 WxPayUnifiedOrderRequest 对象 // 构建 WxPayUnifiedOrderRequest 对象
WxPayUnifiedOrderV3Request request = new WxPayUnifiedOrderV3Request(); WxPayUnifiedOrderV3Request request = new WxPayUnifiedOrderV3Request();
request.setOutTradeNo(reqDTO.getMerchantOrderId()); request.setOutTradeNo(reqDTO.getMerchantOrderId());
request.setDescription(reqDTO.getBody()); request.setDescription(reqDTO.getSubject());
request.setAmount(new WxPayUnifiedOrderV3Request.Amount().setTotal(reqDTO.getAmount())); // 单位分 request.setAmount(new WxPayUnifiedOrderV3Request.Amount().setTotal(reqDTO.getAmount())); // 单位分
request.setTimeExpire(formatDateV3(reqDTO.getExpireTime())); request.setTimeExpire(formatDateV3(reqDTO.getExpireTime()));
request.setPayer(new WxPayUnifiedOrderV3Request.Payer().setOpenid(getOpenid(reqDTO))); request.setPayer(new WxPayUnifiedOrderV3Request.Payer().setOpenid(getOpenid(reqDTO)));

View File

@ -9,7 +9,6 @@ import lombok.Getter;
/** /**
* 支付渠道的编码的枚举 * 支付渠道的编码的枚举
* 枚举值
* *
* @author 芋道源码 * @author 芋道源码
*/ */
@ -21,6 +20,7 @@ public enum PayChannelEnum {
WX_LITE("wx_lite", "微信小程序支付", WxPayClientConfig.class), WX_LITE("wx_lite", "微信小程序支付", WxPayClientConfig.class),
WX_APP("wx_app", "微信 App 支付", WxPayClientConfig.class), WX_APP("wx_app", "微信 App 支付", WxPayClientConfig.class),
WX_NATIVE("wx_native", "微信 native 支付", WxPayClientConfig.class), WX_NATIVE("wx_native", "微信 native 支付", WxPayClientConfig.class),
WX_BAR("wx_bar", "微信付款码支付", WxPayClientConfig.class),
ALIPAY_PC("alipay_pc", "支付宝 PC 网站支付", AlipayPayClientConfig.class), ALIPAY_PC("alipay_pc", "支付宝 PC 网站支付", AlipayPayClientConfig.class),
ALIPAY_WAP("alipay_wap", "支付宝 Wap 网站支付", AlipayPayClientConfig.class), ALIPAY_WAP("alipay_wap", "支付宝 Wap 网站支付", AlipayPayClientConfig.class),

View File

@ -17,7 +17,7 @@ public enum PayOrderStatusEnum implements IntArrayValuable {
WAITING(0, "未支付"), WAITING(0, "未支付"),
SUCCESS(10, "支付成功"), SUCCESS(10, "支付成功"),
CLOSED(20, "支付关闭"), // 未付款交易超时关闭或支付完成后全额退款 TODO 芋艿需要优化下 CLOSED(20, "支付关闭"), // 未付款交易超时关闭或支付完成后全额退款
; ;
private final Integer status; private final Integer status;

View File

@ -1,4 +1,4 @@
### /pay/create 提交支付订单 ### /pay/create 提交支付订单【alipay_pc】
POST {{appApi}}/pay/order/submit POST {{appApi}}/pay/order/submit
Content-Type: application/json Content-Type: application/json
Authorization: Bearer {{appToken}} Authorization: Bearer {{appToken}}
@ -8,3 +8,31 @@ tenant-id: {{appTenentId}}
"id": 174, "id": 174,
"channelCode": "alipay_pc" "channelCode": "alipay_pc"
} }
### /pay/create 提交支付订单【wx_bar】
POST {{appApi}}/pay/order/submit
Content-Type: application/json
Authorization: Bearer {{appToken}}
tenant-id: {{appTenentId}}
{
"id": 202,
"channelCode": "wx_bar",
"channelExtras": {
"authCode": "132527737910208222"
}
}
### /pay/create 提交支付订单【wx_pub】
POST {{appApi}}/pay/order/submit
Content-Type: application/json
Authorization: Bearer {{appToken}}
tenant-id: {{appTenentId}}
{
"id": 202,
"channelCode": "wx_pub",
"channelExtras": {
"openid": "ockUAwIZ-0OeMZl9ogcZ4ILrGba0"
}
}