mirror of
https://gitee.com/hhyykk/ipms-sjy.git
synced 2025-02-02 03:34:58 +08:00
mall + pay:
1. 实现 WxBarPayClient 的支付功能
This commit is contained in:
parent
4014137a4c
commit
e31b40eefa
@ -169,7 +169,7 @@ public abstract class AbstractWxPayClient extends AbstractPayClient<WxPayClientC
|
|||||||
if (Objects.equals(e.getErrCode(), "PARAM_ERROR")) {
|
if (Objects.equals(e.getErrCode(), "PARAM_ERROR")) {
|
||||||
throw invalidParamException(e.getErrCodeDes());
|
throw invalidParamException(e.getErrCodeDes());
|
||||||
}
|
}
|
||||||
throw exception(PayFrameworkErrorCodeConstants.ORDER_UNIFIED_ERROR, e.getReturnMsg());
|
throw exception(PayFrameworkErrorCodeConstants.ORDER_UNIFIED_ERROR, e.getErrCodeDes());
|
||||||
}
|
}
|
||||||
// 情况二:状态码结果为 FAIL
|
// 情况二:状态码结果为 FAIL
|
||||||
if (Objects.equals(e.getReturnCode(), "FAIL")) {
|
if (Objects.equals(e.getReturnCode(), "FAIL")) {
|
||||||
|
@ -34,6 +34,8 @@ import java.util.Objects;
|
|||||||
/**
|
/**
|
||||||
* 微信 App 支付
|
* 微信 App 支付
|
||||||
*
|
*
|
||||||
|
* TODO 芋艿:待测试,可能实现也不太对;
|
||||||
|
*
|
||||||
* @author zwy
|
* @author zwy
|
||||||
*/
|
*/
|
||||||
@Slf4j
|
@Slf4j
|
||||||
|
@ -1,7 +1,9 @@
|
|||||||
package cn.iocoder.yudao.framework.pay.core.client.impl.weixin;
|
package cn.iocoder.yudao.framework.pay.core.client.impl.weixin;
|
||||||
|
|
||||||
import cn.hutool.core.map.MapUtil;
|
import cn.hutool.core.map.MapUtil;
|
||||||
|
import cn.hutool.core.thread.ThreadUtil;
|
||||||
import cn.hutool.core.util.StrUtil;
|
import cn.hutool.core.util.StrUtil;
|
||||||
|
import cn.iocoder.yudao.framework.common.util.date.LocalDateTimeUtils;
|
||||||
import cn.iocoder.yudao.framework.common.util.json.JsonUtils;
|
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.PayOrderUnifiedReqDTO;
|
||||||
import cn.iocoder.yudao.framework.pay.core.client.dto.order.PayOrderUnifiedRespDTO;
|
import cn.iocoder.yudao.framework.pay.core.client.dto.order.PayOrderUnifiedRespDTO;
|
||||||
@ -9,15 +11,34 @@ import cn.iocoder.yudao.framework.pay.core.client.dto.refund.PayRefundUnifiedReq
|
|||||||
import cn.iocoder.yudao.framework.pay.core.client.dto.refund.PayRefundUnifiedRespDTO;
|
import cn.iocoder.yudao.framework.pay.core.client.dto.refund.PayRefundUnifiedRespDTO;
|
||||||
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 cn.iocoder.yudao.framework.pay.core.enums.order.PayOrderStatusRespEnum;
|
||||||
import com.github.binarywang.wxpay.bean.request.WxPayMicropayRequest;
|
import com.github.binarywang.wxpay.bean.request.WxPayMicropayRequest;
|
||||||
import com.github.binarywang.wxpay.bean.result.WxPayMicropayResult;
|
import com.github.binarywang.wxpay.bean.result.WxPayMicropayResult;
|
||||||
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;
|
||||||
|
|
||||||
|
import java.time.Duration;
|
||||||
|
import java.time.LocalDateTime;
|
||||||
|
import java.util.concurrent.TimeUnit;
|
||||||
|
|
||||||
import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.invalidParamException;
|
import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.invalidParamException;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 微信支付【付款码支付】的 PayClient 实现类
|
||||||
|
*
|
||||||
|
* 文档:<a href="https://pay.weixin.qq.com/wiki/doc/api/micropay.php?chapter=9_10&index=1">付款码支付</a>
|
||||||
|
*
|
||||||
|
* @author 芋道源码
|
||||||
|
*/
|
||||||
|
@Slf4j
|
||||||
public class WxBarPayClient extends AbstractWxPayClient {
|
public class WxBarPayClient extends AbstractWxPayClient {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 微信付款码的过期时间
|
||||||
|
*/
|
||||||
|
private static final Duration AUTH_CODE_EXPIRE = Duration.ofMinutes(3);
|
||||||
|
|
||||||
public WxBarPayClient(Long channelId, WxPayClientConfig config) {
|
public WxBarPayClient(Long channelId, WxPayClientConfig config) {
|
||||||
super(channelId, PayChannelEnum.WX_BAR.getCode(), config);
|
super(channelId, PayChannelEnum.WX_BAR.getCode(), config);
|
||||||
}
|
}
|
||||||
@ -29,23 +50,44 @@ public class WxBarPayClient extends AbstractWxPayClient {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected PayOrderUnifiedRespDTO doUnifiedOrderV2(PayOrderUnifiedReqDTO reqDTO) throws WxPayException {
|
protected PayOrderUnifiedRespDTO doUnifiedOrderV2(PayOrderUnifiedReqDTO reqDTO) throws WxPayException {
|
||||||
|
// 由于付款码需要不断轮询,所以需要在较短的时间完成支付
|
||||||
|
LocalDateTime expireTime = LocalDateTimeUtils.addTime(AUTH_CODE_EXPIRE);
|
||||||
|
if (expireTime.isAfter(reqDTO.getExpireTime())) {
|
||||||
|
expireTime = reqDTO.getExpireTime();
|
||||||
|
}
|
||||||
// 构建 WxPayMicropayRequest 对象
|
// 构建 WxPayMicropayRequest 对象
|
||||||
WxPayMicropayRequest request = WxPayMicropayRequest.newBuilder()
|
WxPayMicropayRequest request = WxPayMicropayRequest.newBuilder()
|
||||||
.outTradeNo(reqDTO.getMerchantOrderId())
|
.outTradeNo(reqDTO.getMerchantOrderId())
|
||||||
.body(reqDTO.getSubject())
|
.body(reqDTO.getSubject())
|
||||||
.detail(reqDTO.getBody())
|
.detail(reqDTO.getBody())
|
||||||
.totalFee(reqDTO.getAmount()) // 单位分
|
.totalFee(reqDTO.getAmount()) // 单位分
|
||||||
.timeExpire(formatDateV2(reqDTO.getExpireTime()))
|
.timeExpire(formatDateV2(expireTime))
|
||||||
.spbillCreateIp(reqDTO.getUserIp())
|
.spbillCreateIp(reqDTO.getUserIp())
|
||||||
.authCode(getAuthCode(reqDTO))
|
.authCode(getAuthCode(reqDTO))
|
||||||
.build();
|
.build();
|
||||||
// 执行请求
|
// 执行请求,重试直到失败(过期),或者成功
|
||||||
WxPayMicropayResult response = client.micropay(request);
|
for (int i = 1; i < Byte.MAX_VALUE; i++) {
|
||||||
|
try {
|
||||||
// 转换结果
|
WxPayMicropayResult response = client.micropay(request);
|
||||||
// TODO 芋艿:这里后面要看看
|
// 支付成功(例如说,用户输入了密码)
|
||||||
return new PayOrderUnifiedRespDTO(PayOrderDisplayModeEnum.CUSTOM.getMode(),
|
return new PayOrderUnifiedRespDTO(PayOrderDisplayModeEnum.BAR_CODE.getMode(),
|
||||||
JsonUtils.toJsonString(response));
|
JsonUtils.toJsonString(response),
|
||||||
|
PayOrderStatusRespEnum.SUCCESS.getStatus());
|
||||||
|
} catch (WxPayException ex) {
|
||||||
|
// 如果不满足这 3 种任一的,则直接抛出 WxPayException 异常,不仅需处理
|
||||||
|
// 1. SYSTEMERROR:接口返回错误:请立即调用被扫订单结果查询API,查询当前订单状态,并根据订单的状态决定下一步的操作。
|
||||||
|
// 2. USERPAYING:用户支付中,需要输入密码:等待 5 秒,然后调用被扫订单结果查询 API,查询当前订单的不同状态,决定下一步的操作。
|
||||||
|
// 3. BANKERROR:银行系统异常:请立即调用被扫订单结果查询 API,查询当前订单的不同状态,决定下一步的操作。
|
||||||
|
if (!StrUtil.equalsAny(ex.getErrCode(), "SYSTEMERROR", "USERPAYING", "BANKERROR")) {
|
||||||
|
throw ex;
|
||||||
|
}
|
||||||
|
// 等待 5 秒,继续下一轮重新发起支付
|
||||||
|
log.info("[doUnifiedOrderV2][发起微信 Bar 支付第({})失败,等待下一轮重试,请求({}),响应({})]", i,
|
||||||
|
JsonUtils.toJsonString(request), ex.getMessage());
|
||||||
|
ThreadUtil.sleep(5, TimeUnit.SECONDS);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
throw new IllegalStateException("微信 Bar 支付,重试多次失败");
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -4,10 +4,12 @@ import cn.iocoder.yudao.framework.pay.core.enums.channel.PayChannelEnum;
|
|||||||
import lombok.extern.slf4j.Slf4j;
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 微信支付(小程序)的 PayClient 实现类
|
* 微信支付【小程序】的 PayClient 实现类
|
||||||
*
|
*
|
||||||
* 由于公众号和小程序的微信支付逻辑一致,所以直接进行继承
|
* 由于公众号和小程序的微信支付逻辑一致,所以直接进行继承
|
||||||
*
|
*
|
||||||
|
* 文档:<a href="https://pay.weixin.qq.com/wiki/doc/apiv3/apis/chapter3_5_1.shtml">JSAPI 下单</>
|
||||||
|
*
|
||||||
* @author zwy
|
* @author zwy
|
||||||
*/
|
*/
|
||||||
@Slf4j
|
@Slf4j
|
||||||
|
@ -23,20 +23,21 @@ public class WxPayClientConfig implements PayClientConfig {
|
|||||||
/**
|
/**
|
||||||
* API 版本 - V2
|
* API 版本 - V2
|
||||||
*
|
*
|
||||||
* https://pay.weixin.qq.com/wiki/doc/api/jsapi.php?chapter=4_1
|
* <a href="https://pay.weixin.qq.com/wiki/doc/api/jsapi.php?chapter=4_1">V2 协议说明</a>
|
||||||
*/
|
*/
|
||||||
public static final String API_VERSION_V2 = "v2";
|
public static final String API_VERSION_V2 = "v2";
|
||||||
/**
|
/**
|
||||||
* API 版本 - V3
|
* API 版本 - V3
|
||||||
*
|
*
|
||||||
* https://pay.weixin.qq.com/wiki/doc/apiv3/wechatpay/wechatpay-1.shtml
|
* <a href="https://pay.weixin.qq.com/wiki/doc/apiv3/wechatpay/wechatpay-1.shtml">V3 协议说明</a>
|
||||||
*/
|
*/
|
||||||
public static final String API_VERSION_V3 = "v3";
|
public static final String API_VERSION_V3 = "v3";
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 公众号或者小程序的 appid
|
* 公众号或者小程序的 appid
|
||||||
|
*
|
||||||
|
* 只有公众号或小程序需要该字段
|
||||||
*/
|
*/
|
||||||
@NotBlank(message = "APPID 不能为空", groups = {V2.class, V3.class})
|
|
||||||
private String appId;
|
private String appId;
|
||||||
/**
|
/**
|
||||||
* 商户号
|
* 商户号
|
||||||
|
@ -23,6 +23,8 @@ import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionU
|
|||||||
/**
|
/**
|
||||||
* 微信支付(公众号)的 PayClient 实现类
|
* 微信支付(公众号)的 PayClient 实现类
|
||||||
*
|
*
|
||||||
|
* 文档:<a href="https://pay.weixin.qq.com/wiki/doc/apiv3/apis/chapter3_1_1.shtml">JSAPI 下单</>
|
||||||
|
*
|
||||||
* @author 芋道源码
|
* @author 芋道源码
|
||||||
*/
|
*/
|
||||||
@Slf4j
|
@Slf4j
|
||||||
|
@ -19,7 +19,7 @@ tenant-id: {{appTenentId}}
|
|||||||
"id": 202,
|
"id": 202,
|
||||||
"channelCode": "wx_bar",
|
"channelCode": "wx_bar",
|
||||||
"channelExtras": {
|
"channelExtras": {
|
||||||
"authCode": "132527737910208222"
|
"authCode": "132990241553789274"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user