|
@@ -4,16 +4,14 @@ import cn.hutool.core.bean.BeanUtil;
|
|
|
import cn.hutool.core.date.LocalDateTimeUtil;
|
|
|
import cn.hutool.core.date.TemporalAccessorUtil;
|
|
|
import cn.hutool.core.lang.Assert;
|
|
|
-import cn.hutool.core.map.MapUtil;
|
|
|
import cn.hutool.core.util.StrUtil;
|
|
|
import cn.iocoder.yudao.framework.common.util.io.FileUtils;
|
|
|
-import cn.iocoder.yudao.framework.common.util.object.ObjectUtils;
|
|
|
import cn.iocoder.yudao.framework.pay.core.client.dto.notify.PayNotifyReqDTO;
|
|
|
import cn.iocoder.yudao.framework.pay.core.client.dto.notify.PayOrderNotifyRespDTO;
|
|
|
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.exception.PayException;
|
|
|
import cn.iocoder.yudao.framework.pay.core.client.impl.AbstractPayClient;
|
|
|
+import cn.iocoder.yudao.framework.pay.core.enums.PayFrameworkErrorCodeConstants;
|
|
|
import com.github.binarywang.wxpay.bean.notify.WxPayOrderNotifyResult;
|
|
|
import com.github.binarywang.wxpay.bean.notify.WxPayOrderNotifyV3Result;
|
|
|
import com.github.binarywang.wxpay.config.WxPayConfig;
|
|
@@ -26,6 +24,9 @@ import java.time.LocalDateTime;
|
|
|
import java.time.ZoneId;
|
|
|
import java.util.Objects;
|
|
|
|
|
|
+import static cn.hutool.core.date.DatePattern.PURE_DATETIME_PATTERN;
|
|
|
+import static cn.hutool.core.date.DatePattern.UTC_WITH_XXX_OFFSET_PATTERN;
|
|
|
+import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.*;
|
|
|
import static cn.iocoder.yudao.framework.common.util.json.JsonUtils.toJsonString;
|
|
|
|
|
|
/**
|
|
@@ -67,8 +68,7 @@ public abstract class AbstractWxPayClient extends AbstractPayClient<WxPayClientC
|
|
|
}
|
|
|
|
|
|
@Override
|
|
|
- protected PayOrderUnifiedRespDTO doUnifiedOrder(PayOrderUnifiedReqDTO reqDTO)
|
|
|
- throws Throwable {
|
|
|
+ protected PayOrderUnifiedRespDTO doUnifiedOrder(PayOrderUnifiedReqDTO reqDTO) throws Exception {
|
|
|
try {
|
|
|
switch (config.getApiVersion()) {
|
|
|
case WxPayClientConfig.API_VERSION_V2:
|
|
@@ -79,8 +79,7 @@ public abstract class AbstractWxPayClient extends AbstractPayClient<WxPayClientC
|
|
|
throw new IllegalArgumentException(String.format("未知的 API 版本(%s)", config.getApiVersion()));
|
|
|
}
|
|
|
} catch (WxPayException e) {
|
|
|
- log.error("[doUnifiedOrder][request({}) 发起支付失败]", toJsonString(reqDTO), e);
|
|
|
- throw buildPayException(e);
|
|
|
+ throw buildUnifiedOrderException(reqDTO, e);
|
|
|
}
|
|
|
}
|
|
|
|
|
@@ -118,7 +117,9 @@ public abstract class AbstractWxPayClient extends AbstractPayClient<WxPayClientC
|
|
|
}
|
|
|
} catch (WxPayException e) {
|
|
|
log.error("[parseNotify][rawNotify({}) 解析失败]", toJsonString(rawNotify), e);
|
|
|
- throw buildPayException(e);
|
|
|
+// throw buildPayException(e);
|
|
|
+ throw new RuntimeException(e);
|
|
|
+ // TODO 芋艿:缺一个异常翻译
|
|
|
}
|
|
|
}
|
|
|
|
|
@@ -151,33 +152,47 @@ public abstract class AbstractWxPayClient extends AbstractPayClient<WxPayClientC
|
|
|
|
|
|
// ========== 各种工具方法 ==========
|
|
|
|
|
|
- static String getOpenid(PayOrderUnifiedReqDTO reqDTO) {
|
|
|
- String openid = MapUtil.getStr(reqDTO.getChannelExtras(), "openid");
|
|
|
- if (StrUtil.isEmpty(openid)) {
|
|
|
- throw new IllegalArgumentException("支付请求的 openid 不能为空!");
|
|
|
+ /**
|
|
|
+ * 构建统一下单的异常
|
|
|
+ *
|
|
|
+ * 目的:将参数不正确等异常,转换成 {@link cn.iocoder.yudao.framework.common.exception.ServiceException} 业务异常
|
|
|
+ *
|
|
|
+ * @param reqDTO 请求
|
|
|
+ * @param e 微信的支付异常
|
|
|
+ * @return 转换后的异常
|
|
|
+ *
|
|
|
+ */
|
|
|
+ static Exception buildUnifiedOrderException(PayOrderUnifiedReqDTO reqDTO, WxPayException e) {
|
|
|
+ // 情况一:业务结果为 FAIL
|
|
|
+ if (Objects.equals(e.getResultCode(), "FAIL")) {
|
|
|
+ log.error("[buildUnifiedOrderException][request({}) 发起支付失败]", toJsonString(reqDTO), e);
|
|
|
+ if (Objects.equals(e.getErrCode(), "PARAM_ERROR")) {
|
|
|
+ throw invalidParamException(e.getErrCodeDes());
|
|
|
+ }
|
|
|
+ throw exception(PayFrameworkErrorCodeConstants.ORDER_UNIFIED_ERROR, e.getReturnMsg());
|
|
|
}
|
|
|
- return openid;
|
|
|
- }
|
|
|
-
|
|
|
- static PayException buildPayException(WxPayException e) {
|
|
|
- return new PayException(ObjectUtils.defaultIfNull(e.getErrCode(), e.getReturnCode()),
|
|
|
- ObjectUtils.defaultIfNull(e.getErrCodeDes(), e.getCustomErrorMsg()));
|
|
|
+ // 情况二:状态码结果为 FAIL
|
|
|
+ if (Objects.equals(e.getReturnCode(), "FAIL")) {
|
|
|
+ throw exception(PayFrameworkErrorCodeConstants.ORDER_UNIFIED_ERROR, e.getReturnMsg());
|
|
|
+ }
|
|
|
+ // 情况三:系统异常,这里暂时不打,交给上层的 AbstractPayClient 统一打
|
|
|
+ return e;
|
|
|
}
|
|
|
|
|
|
static String formatDateV2(LocalDateTime time) {
|
|
|
- return TemporalAccessorUtil.format(time.atZone(ZoneId.systemDefault()), "yyyyMMddHHmmss");
|
|
|
+ return TemporalAccessorUtil.format(time.atZone(ZoneId.systemDefault()), PURE_DATETIME_PATTERN);
|
|
|
}
|
|
|
|
|
|
static LocalDateTime parseDateV2(String time) {
|
|
|
- return LocalDateTimeUtil.parse(time, "yyyyMMddHHmmss");
|
|
|
+ return LocalDateTimeUtil.parse(time, PURE_DATETIME_PATTERN);
|
|
|
}
|
|
|
|
|
|
static String formatDateV3(LocalDateTime time) {
|
|
|
- return TemporalAccessorUtil.format(time.atZone(ZoneId.systemDefault()), "yyyy-MM-dd'T'HH:mm:ssXXX");
|
|
|
+ return TemporalAccessorUtil.format(time.atZone(ZoneId.systemDefault()), UTC_WITH_XXX_OFFSET_PATTERN);
|
|
|
}
|
|
|
|
|
|
static LocalDateTime parseDateV3(String time) {
|
|
|
- return LocalDateTimeUtil.parse(time, "yyyy-MM-dd'T'HH:mm:ssXXX");
|
|
|
+ return LocalDateTimeUtil.parse(time, UTC_WITH_XXX_OFFSET_PATTERN);
|
|
|
}
|
|
|
|
|
|
}
|