From b984f7f649fc56aea8acf5625168cdd32382cd9c Mon Sep 17 00:00:00 2001 From: duanyuqing <1697807853@qq.com> Date: Thu, 31 Jul 2025 13:57:49 +0800 Subject: [PATCH] =?UTF-8?q?Date:2025-07-31=20author:Duanyuqing=20comment:?= =?UTF-8?q?=E6=B1=87=E4=BB=98=E5=A4=A9=E4=B8=8B=E5=9F=BA=E6=9C=AC=E9=85=8D?= =?UTF-8?q?=E7=BD=AE?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../pay/config/HuifuClientConfig.java | 15 +- .../client/impl/huifu/HuifuPayClient.java | 571 +----------------- .../src/main/resources/application-dev.yaml | 8 + .../src/main/resources/application-local.yaml | 10 +- 4 files changed, 26 insertions(+), 578 deletions(-) diff --git a/hake-module-pay/hake-module-pay-server/src/main/java/cn/iocoder/hake/module/pay/framework/pay/config/HuifuClientConfig.java b/hake-module-pay/hake-module-pay-server/src/main/java/cn/iocoder/hake/module/pay/framework/pay/config/HuifuClientConfig.java index 7d37a81..027c316 100644 --- a/hake-module-pay/hake-module-pay-server/src/main/java/cn/iocoder/hake/module/pay/framework/pay/config/HuifuClientConfig.java +++ b/hake-module-pay/hake-module-pay-server/src/main/java/cn/iocoder/hake/module/pay/framework/pay/config/HuifuClientConfig.java @@ -30,31 +30,30 @@ public class HuifuClientConfig implements PayClientConfig { */ private String prodMode; - //产品编号 - @Value("${huifu.procutId}") + @Value("${hake.huifu.procutId}") private String procutId; //系统编号 - @Value("${huifu.sysId}") + @Value("${hake.huifu.sysId}") private String sysId; //私钥 - @Value("${huifu.rsaPrivateKey}") + @Value("${hake.huifu.rsaPrivateKey}") private String rsaPrivateKey; //公钥 - @Value("${huifu.rsaPublicKey}") + @Value("${hake.huifu.rsaPublicKey}") private String rsaPublicKey; //自定义超时时间 - @Value("${huifu.customConnectTimeout}") + @Value("${hake.huifu.customConnectTimeout}") private String customSocketTimeout; - @Value("${huifu.customConnectTimeout}") + @Value("${hake.huifu.customConnectTimeout}") private String customConnectTimeout; - @Value("${huifu.customConnectionRequestTimeout}") + @Value("${hake.huifu.customConnectionRequestTimeout}") private String customConnectionRequestTimeout; diff --git a/hake-module-pay/hake-module-pay-server/src/main/java/cn/iocoder/hake/module/pay/framework/pay/core/client/impl/huifu/HuifuPayClient.java b/hake-module-pay/hake-module-pay-server/src/main/java/cn/iocoder/hake/module/pay/framework/pay/core/client/impl/huifu/HuifuPayClient.java index 2586a7b..5abfa8e 100644 --- a/hake-module-pay/hake-module-pay-server/src/main/java/cn/iocoder/hake/module/pay/framework/pay/core/client/impl/huifu/HuifuPayClient.java +++ b/hake-module-pay/hake-module-pay-server/src/main/java/cn/iocoder/hake/module/pay/framework/pay/core/client/impl/huifu/HuifuPayClient.java @@ -1,56 +1,19 @@ package cn.iocoder.hake.module.pay.framework.pay.core.client.impl.huifu; -import cn.hutool.core.bean.BeanUtil; -import cn.hutool.core.codec.Base64; -import cn.hutool.core.collection.CollUtil; -import cn.hutool.core.date.LocalDateTimeUtil; -import cn.hutool.core.date.TemporalAccessorUtil; -import cn.hutool.core.util.StrUtil; -import cn.iocoder.hake.framework.common.util.io.FileUtils; -import cn.iocoder.hake.framework.common.util.json.JsonUtils; -import cn.iocoder.hake.framework.common.util.object.ObjectUtils; -import cn.iocoder.hake.module.pay.enums.order.PayOrderStatusEnum; import cn.iocoder.hake.module.pay.framework.pay.config.HuifuClientConfig; -import cn.iocoder.hake.module.pay.framework.pay.core.client.dto.order.PayOrderRespDTO; -import cn.iocoder.hake.module.pay.framework.pay.core.client.dto.order.PayOrderUnifiedReqDTO; -import cn.iocoder.hake.module.pay.framework.pay.core.client.dto.refund.PayRefundRespDTO; -import cn.iocoder.hake.module.pay.framework.pay.core.client.dto.refund.PayRefundUnifiedReqDTO; -import cn.iocoder.hake.module.pay.framework.pay.core.client.dto.transfer.PayTransferRespDTO; -import cn.iocoder.hake.module.pay.framework.pay.core.client.dto.transfer.PayTransferUnifiedReqDTO; -import cn.iocoder.hake.module.pay.framework.pay.core.client.impl.AbstractPayClient; -import com.github.binarywang.wxpay.bean.notify.*; -import com.github.binarywang.wxpay.bean.request.*; -import com.github.binarywang.wxpay.bean.result.*; -import com.github.binarywang.wxpay.bean.transfer.TransferBillsGetResult; -import com.github.binarywang.wxpay.bean.transfer.TransferBillsNotifyResult; -import com.github.binarywang.wxpay.bean.transfer.TransferBillsRequest; -import com.github.binarywang.wxpay.bean.transfer.TransferBillsResult; -import com.github.binarywang.wxpay.config.WxPayConfig; -import com.github.binarywang.wxpay.exception.WxPayException; -import com.github.binarywang.wxpay.service.impl.WxPayServiceImpl; import lombok.extern.slf4j.Slf4j; -import java.time.LocalDateTime; -import java.time.ZoneId; -import java.util.Map; -import java.util.Objects; - -import static cn.hutool.core.date.DatePattern.*; -import static cn.iocoder.hake.module.pay.framework.pay.core.client.impl.weixin.WxPayClientConfig.API_VERSION_V2; -import static cn.iocoder.hake.module.pay.framework.pay.core.client.impl.weixin.WxPayClientConfig.API_VERSION_V3; - /** * 汇付天下支付抽象类 * * @author duanyuqing */ @Slf4j -public abstract class HuifuPayClient extends AbstractPayClient { +public abstract class HuifuPayClient { - protected TradePaymentMicropayRequest client; public HuifuPayClient(Long channelId, String channelCode, HuifuClientConfig config) { - super(channelId, channelCode, config); + } /** @@ -60,538 +23,8 @@ public abstract class HuifuPayClient extends AbstractPayClient params, String body, Map headers) throws WxPayException { - switch (config.getApiVersion()) { - case API_VERSION_V2: - return doParseOrderNotifyV2(body); - case API_VERSION_V3: - return doParseOrderNotifyV3(body, headers); - default: - throw new IllegalArgumentException(String.format("未知的 API 版本(%s)", config.getApiVersion())); - } - } - - private PayOrderRespDTO doParseOrderNotifyV2(String body) throws WxPayException { - // 1. 解析回调 - WxPayOrderNotifyResult response = client.parseOrderNotifyResult(body); - // 2. 构建结果 - // V2 微信支付的回调,只有 SUCCESS 支付成功、CLOSED 支付失败两种情况,无需像支付宝一样解析的比较复杂 - Integer status = Objects.equals(response.getResultCode(), "SUCCESS") ? - PayOrderStatusEnum.SUCCESS.getStatus() : PayOrderStatusEnum.CLOSED.getStatus(); - return PayOrderRespDTO.of(status, response.getTransactionId(), response.getOpenid(), parseDateV2(response.getTimeEnd()), - response.getOutTradeNo(), body); - } - - private PayOrderRespDTO doParseOrderNotifyV3(String body, Map headers) throws WxPayException { - // 1. 解析回调 - SignatureHeader signatureHeader = getRequestHeader(headers); - WxPayNotifyV3Result response = client.parseOrderNotifyV3Result(body, signatureHeader); - WxPayNotifyV3Result.DecryptNotifyResult result = response.getResult(); - // 2. 构建结果 - Integer status = parseStatus(result.getTradeState()); - String openid = result.getPayer() != null ? result.getPayer().getOpenid() : null; - return PayOrderRespDTO.of(status, result.getTransactionId(), openid, parseDateV3(result.getSuccessTime()), - result.getOutTradeNo(), body); - } - - @Override - protected PayOrderRespDTO doGetOrder(String outTradeNo) throws Throwable { - try { - switch (config.getApiVersion()) { - case API_VERSION_V2: - return doGetOrderV2(outTradeNo); - case API_VERSION_V3: - return doGetOrderV3(outTradeNo); - default: - throw new IllegalArgumentException(String.format("未知的 API 版本(%s)", config.getApiVersion())); - } - } catch (WxPayException e) { - if (ObjectUtils.equalsAny(e.getErrCode(), "ORDERNOTEXIST", "ORDER_NOT_EXIST")) { - String errorCode = getErrorCode(e); - String errorMessage = getErrorMessage(e); - return PayOrderRespDTO.closedOf(errorCode, errorMessage, - outTradeNo, e.getXmlString()); - } - throw e; - } - } - - private PayOrderRespDTO doGetOrderV2(String outTradeNo) throws WxPayException { - // 构建 WxPayUnifiedOrderRequest 对象 - WxPayOrderQueryRequest request = WxPayOrderQueryRequest.newBuilder() - .outTradeNo(outTradeNo).build(); - // 执行请求 - WxPayOrderQueryResult response = client.queryOrder(request); - - // 转换结果 - Integer status = parseStatus(response.getTradeState()); - return PayOrderRespDTO.of(status, response.getTransactionId(), response.getOpenid(), parseDateV2(response.getTimeEnd()), - outTradeNo, response); - } - - private PayOrderRespDTO doGetOrderV3(String outTradeNo) throws WxPayException { - fixV3HttpClientConnectionPoolShutDown(); - // 构建 WxPayUnifiedOrderRequest 对象 - WxPayOrderQueryV3Request request = new WxPayOrderQueryV3Request() - .setOutTradeNo(outTradeNo); - // 执行请求 - WxPayOrderQueryV3Result response = client.queryOrderV3(request); - - // 转换结果 - Integer status = parseStatus(response.getTradeState()); - String openid = response.getPayer() != null ? response.getPayer().getOpenid() : null; - return PayOrderRespDTO.of(status, response.getTransactionId(), openid, parseDateV3(response.getSuccessTime()), - outTradeNo, response); - } - - private static Integer parseStatus(String tradeState) { - switch (tradeState) { - case "NOTPAY": - case "USERPAYING": // 支付中,等待用户输入密码(条码支付独有) - return PayOrderStatusEnum.WAITING.getStatus(); - case "SUCCESS": - return PayOrderStatusEnum.SUCCESS.getStatus(); - case "REFUND": - return PayOrderStatusEnum.REFUND.getStatus(); - case "CLOSED": - case "REVOKED": // 已撤销(刷卡支付独有) - case "PAYERROR": // 支付失败(其它原因,如银行返回失败) - return PayOrderStatusEnum.CLOSED.getStatus(); - default: - throw new IllegalArgumentException(StrUtil.format("未知的支付状态({})", tradeState)); - } - } - - // ============ 退款相关 ========== - - @Override - protected PayRefundRespDTO doUnifiedRefund(PayRefundUnifiedReqDTO reqDTO) throws Throwable { - try { - switch (config.getApiVersion()) { - case API_VERSION_V2: - return doUnifiedRefundV2(reqDTO); - case API_VERSION_V3: - return doUnifiedRefundV3(reqDTO); - default: - throw new IllegalArgumentException(String.format("未知的 API 版本(%s)", config.getApiVersion())); - } - } catch (WxPayException e) { - String errorCode = getErrorCode(e); - String errorMessage = getErrorMessage(e); - return PayRefundRespDTO.failureOf(errorCode, errorMessage, - reqDTO.getOutRefundNo(), e.getXmlString()); - } - } - - private PayRefundRespDTO doUnifiedRefundV2(PayRefundUnifiedReqDTO reqDTO) throws Throwable { - // 1. 构建 WxPayRefundRequest 请求 - WxPayRefundRequest request = new WxPayRefundRequest() - .setOutTradeNo(reqDTO.getOutTradeNo()) - .setOutRefundNo(reqDTO.getOutRefundNo()) - .setRefundFee(reqDTO.getRefundPrice()) - .setRefundDesc(reqDTO.getReason()) - .setTotalFee(reqDTO.getPayPrice()) - .setNotifyUrl(reqDTO.getNotifyUrl()); - // 2.1 执行请求 - WxPayRefundResult response = client.refundV2(request); - // 2.2 创建返回结果 - if (Objects.equals("SUCCESS", response.getResultCode())) { // V2 情况下,不直接返回退款成功,而是等待异步通知 - return PayRefundRespDTO.waitingOf(response.getRefundId(), - reqDTO.getOutRefundNo(), response); - } - return PayRefundRespDTO.failureOf(reqDTO.getOutRefundNo(), response); - } - - private PayRefundRespDTO doUnifiedRefundV3(PayRefundUnifiedReqDTO reqDTO) throws Throwable { - fixV3HttpClientConnectionPoolShutDown(); - // 1. 构建 WxPayRefundRequest 请求 - WxPayRefundV3Request request = new WxPayRefundV3Request() - .setOutTradeNo(reqDTO.getOutTradeNo()) - .setOutRefundNo(reqDTO.getOutRefundNo()) - .setAmount(new WxPayRefundV3Request.Amount().setRefund(reqDTO.getRefundPrice()) - .setTotal(reqDTO.getPayPrice()).setCurrency("CNY")) - .setReason(reqDTO.getReason()) - .setNotifyUrl(reqDTO.getNotifyUrl()); - // 2.1 执行请求 - WxPayRefundV3Result response = client.refundV3(request); - // 2.2 创建返回结果 - if (Objects.equals("SUCCESS", response.getStatus())) { - return PayRefundRespDTO.successOf(response.getRefundId(), parseDateV3(response.getSuccessTime()), - reqDTO.getOutRefundNo(), response); - } - if (Objects.equals("PROCESSING", response.getStatus())) { - return PayRefundRespDTO.waitingOf(response.getRefundId(), - reqDTO.getOutRefundNo(), response); - } - return PayRefundRespDTO.failureOf(reqDTO.getOutRefundNo(), response); - } - - @Override - public PayRefundRespDTO doParseRefundNotify(Map params, String body, Map headers) throws WxPayException { - switch (config.getApiVersion()) { - case API_VERSION_V2: - return doParseRefundNotifyV2(body); - case API_VERSION_V3: - return parseRefundNotifyV3(body, headers); - default: - throw new IllegalArgumentException(String.format("未知的 API 版本(%s)", config.getApiVersion())); - } - } - - private PayRefundRespDTO doParseRefundNotifyV2(String body) throws WxPayException { - // 1. 解析回调 - WxPayRefundNotifyResult response = client.parseRefundNotifyResult(body); - WxPayRefundNotifyResult.ReqInfo result = response.getReqInfo(); - // 2. 构建结果 - if (Objects.equals("SUCCESS", result.getRefundStatus())) { - return PayRefundRespDTO.successOf(result.getRefundId(), parseDateV2B(result.getSuccessTime()), - result.getOutRefundNo(), response); - } - return PayRefundRespDTO.failureOf(result.getOutRefundNo(), response); - } - - private PayRefundRespDTO parseRefundNotifyV3(String body, Map headers) throws WxPayException { - // 1. 解析回调 - SignatureHeader signatureHeader = getRequestHeader(headers); - WxPayRefundNotifyV3Result response = client.parseRefundNotifyV3Result(body, signatureHeader); - WxPayRefundNotifyV3Result.DecryptNotifyResult result = response.getResult(); - // 2. 构建结果 - if (Objects.equals("SUCCESS", result.getRefundStatus())) { - return PayRefundRespDTO.successOf(result.getRefundId(), parseDateV3(result.getSuccessTime()), - result.getOutRefundNo(), response); - } - return PayRefundRespDTO.failureOf(result.getOutRefundNo(), response); - } - - @Override - protected PayRefundRespDTO doGetRefund(String outTradeNo, String outRefundNo) throws WxPayException { - try { - switch (config.getApiVersion()) { - case API_VERSION_V2: - return doGetRefundV2(outTradeNo, outRefundNo); - case API_VERSION_V3: - return doGetRefundV3(outTradeNo, outRefundNo); - default: - throw new IllegalArgumentException(String.format("未知的 API 版本(%s)", config.getApiVersion())); - } - } catch (WxPayException e) { - if (ObjectUtils.equalsAny(e.getErrCode(), "REFUNDNOTEXIST", "RESOURCE_NOT_EXISTS")) { - String errorCode = getErrorCode(e); - String errorMessage = getErrorMessage(e); - return PayRefundRespDTO.failureOf(errorCode, errorMessage, - outRefundNo, e.getXmlString()); - } - throw e; - } - } - - private PayRefundRespDTO doGetRefundV2(String outTradeNo, String outRefundNo) throws WxPayException { - // 1. 构建 WxPayRefundRequest 请求 - WxPayRefundQueryRequest request = WxPayRefundQueryRequest.newBuilder() - .outTradeNo(outTradeNo) - .outRefundNo(outRefundNo) - .build(); - // 2.1 执行请求 - WxPayRefundQueryResult response = client.refundQuery(request); - // 2.2 创建返回结果 - if (!Objects.equals("SUCCESS", response.getResultCode())) { - return PayRefundRespDTO.waitingOf(null, - outRefundNo, response); - } - WxPayRefundQueryResult.RefundRecord refund = CollUtil.findOne(response.getRefundRecords(), - record -> record.getOutRefundNo().equals(outRefundNo)); - if (refund == null) { - return PayRefundRespDTO.failureOf(outRefundNo, response); - } - switch (refund.getRefundStatus()) { - case "SUCCESS": - return PayRefundRespDTO.successOf(refund.getRefundId(), parseDateV2B(refund.getRefundSuccessTime()), - outRefundNo, response); - case "PROCESSING": - return PayRefundRespDTO.waitingOf(refund.getRefundId(), - outRefundNo, response); - case "CHANGE": // 退款到银行发现用户的卡作废或者冻结了,导致原路退款银行卡失败,资金回流到商户的现金帐号,需要商户人工干预,通过线下或者财付通转账的方式进行退款 - case "FAIL": - return PayRefundRespDTO.failureOf(outRefundNo, response); - default: - throw new IllegalArgumentException(String.format("未知的退款状态(%s)", refund.getRefundStatus())); - } - } - - private PayRefundRespDTO doGetRefundV3(String outTradeNo, String outRefundNo) throws WxPayException { - fixV3HttpClientConnectionPoolShutDown(); - // 1. 构建 WxPayRefundRequest 请求 - WxPayRefundQueryV3Request request = new WxPayRefundQueryV3Request(); - request.setOutRefundNo(outRefundNo); - // 2.1 执行请求 - WxPayRefundQueryV3Result response = client.refundQueryV3(request); - // 2.2 创建返回结果 - switch (response.getStatus()) { - case "SUCCESS": - return PayRefundRespDTO.successOf(response.getRefundId(), parseDateV3(response.getSuccessTime()), - outRefundNo, response); - case "PROCESSING": - return PayRefundRespDTO.waitingOf(response.getRefundId(), - outRefundNo, response); - case "ABNORMAL": // 退款异常 - case "CLOSED": - return PayRefundRespDTO.failureOf(outRefundNo, response); - default: - throw new IllegalArgumentException(String.format("未知的退款状态(%s)", response.getStatus())); - } - } - - @Override - protected PayTransferRespDTO doUnifiedTransfer(PayTransferUnifiedReqDTO reqDTO) throws WxPayException { - fixV3HttpClientConnectionPoolShutDown(); - // 1. 构建 TransferBillsRequest 请求 - TransferBillsRequest request = TransferBillsRequest.newBuilder() - .appid(this.config.getAppId()) - .outBillNo(reqDTO.getOutTransferNo()) - .transferAmount(reqDTO.getPrice()) - .transferRemark(reqDTO.getSubject()) - .transferSceneId(reqDTO.getChannelExtras().get("sceneId")) - .openid(reqDTO.getUserAccount()) - .userName(reqDTO.getUserName()) - .transferSceneReportInfos(JsonUtils.parseArray(reqDTO.getChannelExtras().get("sceneReportInfos"), - TransferBillsRequest.TransferSceneReportInfo.class)) - .notifyUrl(reqDTO.getNotifyUrl()) - .build(); - // 特殊:微信转账,必须 0.3 元起,才允许传入姓名 - if (reqDTO.getPrice() < 30) { - request.setUserName(null); - } - - // 2.1 执行请求 - try { - TransferBillsResult response = client.getTransferService().transferBills(request); - - // 2.2 创建返回结果 - String state = response.getState(); - if (ObjectUtils.equalsAny(state, "ACCEPTED", "PROCESSING", "WAIT_USER_CONFIRM", "TRANSFERING")) { - return PayTransferRespDTO.processingOf(response.getTransferBillNo(), response.getOutBillNo(), response) - .setChannelPackageInfo(response.getPackageInfo()); // 一般情况下,只有 WAIT_USER_CONFIRM 会有! - } - if (Objects.equals("SUCCESS", state)) { - return PayTransferRespDTO.successOf(response.getTransferBillNo(), parseDateV3(response.getCreateTime()), - response.getOutBillNo(), response); - } - return PayTransferRespDTO.closedOf(state, response.getFailReason(), - response.getOutBillNo(), response); - } catch (WxPayException e) { - log.error("[doUnifiedTransfer][转账({}) 发起微信支付异常", reqDTO, e); - String errorCode = getErrorCode(e); - String errorMessage = getErrorMessage(e); - return PayTransferRespDTO.closedOf(errorCode, errorMessage, - reqDTO.getOutTransferNo(), e.getXmlString()); - } - } - - @Override - protected PayTransferRespDTO doGetTransfer(String outTradeNo) throws WxPayException { - fixV3HttpClientConnectionPoolShutDown(); - // 1. 执行请求 - TransferBillsGetResult response = client.getTransferService().getBillsByOutBillNo(outTradeNo); - - // 2. 创建返回结果 - String state = response.getState(); - if (ObjectUtils.equalsAny(state, "ACCEPTED", "PROCESSING", "WAIT_USER_CONFIRM", "TRANSFERING")) { - return PayTransferRespDTO.processingOf(response.getTransferBillNo(), response.getOutBillNo(), response); - } - if (Objects.equals("SUCCESS", state)) { - return PayTransferRespDTO.successOf(response.getTransferBillNo(), parseDateV3(response.getUpdateTime()), - response.getOutBillNo(), response); - } - return PayTransferRespDTO.closedOf(state, response.getFailReason(), - response.getOutBillNo(), response); - } - - @Override - public PayTransferRespDTO doParseTransferNotify(Map params, String body, Map headers) throws WxPayException { - switch (config.getApiVersion()) { - case API_VERSION_V3: - return parseTransferNotifyV3(body, headers); - case API_VERSION_V2: - throw new UnsupportedOperationException("V2 版本暂不支持,建议使用 V3 版本"); - default: - throw new IllegalArgumentException(String.format("未知的 API 版本(%s)", config.getApiVersion())); - } - } - - private PayTransferRespDTO parseTransferNotifyV3(String body, Map headers) throws WxPayException { - // 1. 解析回调 - SignatureHeader signatureHeader = getRequestHeader(headers); - TransferBillsNotifyResult response = client.getTransferService().parseTransferBillsNotifyResult(body, signatureHeader); - TransferBillsNotifyResult.DecryptNotifyResult result = response.getResult(); - - // 2. 创建返回结果 - String state = result.getState(); - if (ObjectUtils.equalsAny(state, "ACCEPTED", "PROCESSING", "WAIT_USER_CONFIRM", "TRANSFERING")) { - return PayTransferRespDTO.processingOf(result.getTransferBillNo(), result.getOutBillNo(), response); - } - if (Objects.equals("SUCCESS", state)) { - return PayTransferRespDTO.successOf(result.getTransferBillNo(), parseDateV3(result.getUpdateTime()), - result.getOutBillNo(), response); - } - return PayTransferRespDTO.closedOf(state, result.getFailReason(), - result.getOutBillNo(), response); - } - - // ========== 各种工具方法 ========== - - /** - * 组装请求头重的签名信息 - * - * @see 官方示例 - */ - private SignatureHeader getRequestHeader(Map headers) { - return SignatureHeader.builder() - .signature(headers.get("wechatpay-signature")) - .nonce(headers.get("wechatpay-nonce")) - .serial(headers.get("wechatpay-serial")) - .timeStamp(headers.get("wechatpay-timestamp")) - .build(); - } - - // TODO @哈客:可能是 wxjava 的 bug:https://github.com/binarywang/WxJava/issues/1557 - private void fixV3HttpClientConnectionPoolShutDown() { - client.getConfig().setApiV3HttpClient(null); - } - static String formatDateV2(LocalDateTime time) { - return TemporalAccessorUtil.format(time.atZone(ZoneId.systemDefault()), PURE_DATETIME_PATTERN); } - static LocalDateTime parseDateV2(String time) { - return LocalDateTimeUtil.parse(time, PURE_DATETIME_PATTERN); - } - - static LocalDateTime parseDateV2B(String time) { - return LocalDateTimeUtil.parse(time, NORM_DATETIME_PATTERN); - } - - static String formatDateV3(LocalDateTime time) { - return TemporalAccessorUtil.format(time.atZone(ZoneId.systemDefault()), UTC_WITH_XXX_OFFSET_PATTERN); - } - - static LocalDateTime parseDateV3(String time) { - return LocalDateTimeUtil.parse(time, UTC_WITH_XXX_OFFSET_PATTERN); - } - - static String getErrorCode(WxPayException e) { - if (StrUtil.isNotEmpty(e.getErrCode())) { - return e.getErrCode(); - } - if (StrUtil.isNotEmpty(e.getCustomErrorMsg())) { - return "CUSTOM_ERROR"; - } - return e.getReturnCode(); - } - - static String getErrorMessage(WxPayException e) { - if (StrUtil.isNotEmpty(e.getErrCode())) { - return e.getErrCodeDes(); - } - if (StrUtil.isNotEmpty(e.getCustomErrorMsg())) { - return e.getCustomErrorMsg(); - } - return e.getReturnMsg(); - } } diff --git a/hake-module-pay/hake-module-pay-server/src/main/resources/application-dev.yaml b/hake-module-pay/hake-module-pay-server/src/main/resources/application-dev.yaml index 4087431..09891fa 100644 --- a/hake-module-pay/hake-module-pay-server/src/main/resources/application-dev.yaml +++ b/hake-module-pay/hake-module-pay-server/src/main/resources/application-dev.yaml @@ -116,3 +116,11 @@ hake: refund-notify-url: http://yunai.natapp1.cc/admin-api/pay/notify/refund # 支付渠道的【退款】回调地址 transfer-notify-url: http://yunai.natapp1.cc/admin-api/pay/notify/transfer # 支付渠道的【转账】回调地址 demo: false # 关闭演示模式 + huifu: + procutId: PAYUN + sysId: 6666000162367855 + rsaPrivateKey: MIIEvgIBADANBgkqhkiG9w0BAQEFAASCBKgwggSkAgEAAoIBAQCOKQUkTWNZ1lug2yLa+6ESp+XDBN5roQMLQVZPbn7T5Jwo4yK3R8zNjSB8KSLaG23Dkr3xISf5HvFVOmoEtpQrCqzbDrU7hmR00ita/wQIRluh2RAT+RsUHDwCeXPOk3jkugKQtXvhQExxn61LIXAArB07MMkZgl5/HXcEQcLzukpSnQ55WIA1+HFPL20x8hHYEIILtI3zibFJtAoig0VeZPVUDTKbOEILkRriSJ7WQjMlsKw1w/TaFAXrCnQO7GlY8pVxkzW46WDt5xT9m26KNiXcQeS5Je215pgBnFidMAOQLxIlyDyh9/PTe2r0ygoGH52J5HyKHYenLlhv/DyBAgMBAAECggEBAIaxGuwQXsepr9syhU3SCATzC2DBZjO3tHifiTVtTcFZ4xNiUWwyHTvMMTEykJDyWAdrK4ghkAwbYzELTZP1oWE+lhRfVRt29AszblyjLqDgeMVaMj+aUCu3rKvzguQBGhQsoW2WZi8/iq5FSh3bKpGYgYGpcYA342yw8CkaXaoqN8jzH3ohEv9KX3cHIfCAeEg0zNH4+pXDhOjwXc/XIjQ5CoIduYey2JsHt/MyTR/5SrguMcr0VZLqYqJDy5Dd81kL46YlBACq5p1u7effgmVqb64MPGVaVU0FdUFv3CX4cLtEEEG63X1aijxPnKGyy5XEM+k/DFbw25xBBM1UJKECgYEAxCt21DWtS+1g6VVJA+qbpBMSzfA/xblvXyz5owCMmopte3WnzLPlkHdgTxlZSeRHursOPFd3v8hOmovFNw+OBS8Fhdy0b7tLwmb55CEOX7MsLJ5pqsUE+5IjGAVGJNHRlxTtDDXA8fILpeRJouAtAcrheyjmqWz8tsQ1okgWL8UCgYEAuYSZzcwKNHjBwOoMsxxmuh7hM+CXiO5TXnhuFkrVOR23147spKvUaV97z2SHEtbj13k70BTCVMCAyQOrMgL/ro0XHl2dK8zKPSuZvYC23r+AsE69edeJz2uYjDOxXfJJFNL4jqRDfNG/Cbk6VimkVzaeKdfnsf3MYQ5CFZ8eCY0CgYBpDsXy3FRU52oRTEVwPYLhGf3mIJZms+q7VADVlQO3+A6uIdKdxHJbLjN76R1yfzkS/f6fvlA5e3LtPZF+7Wunxwj0KcDQXcQy9qc5z6I9Cl3L/4KjnCQQ/rCguqJYMa5HdUOGWHtel7w5Octd2SUBYr/jD4KIlf+5edcnc+e96QKBgHZtO3GwSuNsIuNvhWPhQYKWq9ReDt4OpZGs9zmr06l+Wxlz14TXW+VYWsTtu3w/SXsHnTMbzWIk8RFhEiv+1hEraBKuV+LZ/FBIQQBD5nkTbqcd3L6m5QZP/TWi2hrKy/RLKPiFy78mdflTEPZn5sz1xMmZVgK9rXZXj8AVrysRAoGBAJJfMtoeNO8bj0TuvC/u+OFUsazjBziTrFRAlrVU6pUkZ+P8huKindNnQSzkH92JpdoPgPPzRsw8yFai3wgRPrExsSosELulEAZMZNnPEn7BxiTQjB7wcCSnRXAmW6g5wUjHhu1wAhGJpV1RSCVMgsfNQy6NOZizQahc6u4Qb77/ + rsaPublicKey: MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAik1dhiQNVn69cTq3WhhUxKKDwRQtdKbbAzRTTvkwcYH2J07iG0EmRZTqmZKTvNqGKizQbz9eNrMh7Awn5B+t8aTc+xe3amj7bngf0zk2jAwK36Hrokv5oOCAiyAWSEt9/M6gWUf0R+av5JS34XZmfDVyhcu2+3PdWBaqKlOx0HX9TphuDJDHqWP13+It5X2Iv1kkiaqcY6yjhBF8RlP1vD+Y77W4p+h9QHIAVCJGykjBDBf51pxHMrOuj1yFOpWCX4UlYQISPfdlgu+FARW38mjqV/J2QwITcseg1sb1aRvA2Bve+zdcQTAwNpUwOnqsfov+p7Vh0+VXUt1vyk0abQIDAQAB + customSocketTimeout: 20000 + customConnectTimeout: 20000 + customConnectionRequestTimeout: 20000 diff --git a/hake-module-pay/hake-module-pay-server/src/main/resources/application-local.yaml b/hake-module-pay/hake-module-pay-server/src/main/resources/application-local.yaml index d47ae82..8240f6d 100644 --- a/hake-module-pay/hake-module-pay-server/src/main/resources/application-local.yaml +++ b/hake-module-pay/hake-module-pay-server/src/main/resources/application-local.yaml @@ -138,4 +138,12 @@ hake: pay: order-notify-url: https://yutou.mynatapp.cc/admin-api/pay/notify/order # 支付渠道的【支付】回调地址 refund-notify-url: https://yutou.mynatapp.cc/admin-api/pay/notify/refund # 支付渠道的【退款】回调地址 - transfer-notify-url: https://yutou.mynatapp.cc/admin-api/pay/notify/transfer # 支付渠道的【转账】回调地址 \ No newline at end of file + transfer-notify-url: https://yutou.mynatapp.cc/admin-api/pay/notify/transfer # 支付渠道的【转账】回调地址 + huifu: + procutId: PAYUN + sysId: 6666000162367855 + rsaPrivateKey: MIIEvgIBADANBgkqhkiG9w0BAQEFAASCBKgwggSkAgEAAoIBAQCOKQUkTWNZ1lug2yLa+6ESp+XDBN5roQMLQVZPbn7T5Jwo4yK3R8zNjSB8KSLaG23Dkr3xISf5HvFVOmoEtpQrCqzbDrU7hmR00ita/wQIRluh2RAT+RsUHDwCeXPOk3jkugKQtXvhQExxn61LIXAArB07MMkZgl5/HXcEQcLzukpSnQ55WIA1+HFPL20x8hHYEIILtI3zibFJtAoig0VeZPVUDTKbOEILkRriSJ7WQjMlsKw1w/TaFAXrCnQO7GlY8pVxkzW46WDt5xT9m26KNiXcQeS5Je215pgBnFidMAOQLxIlyDyh9/PTe2r0ygoGH52J5HyKHYenLlhv/DyBAgMBAAECggEBAIaxGuwQXsepr9syhU3SCATzC2DBZjO3tHifiTVtTcFZ4xNiUWwyHTvMMTEykJDyWAdrK4ghkAwbYzELTZP1oWE+lhRfVRt29AszblyjLqDgeMVaMj+aUCu3rKvzguQBGhQsoW2WZi8/iq5FSh3bKpGYgYGpcYA342yw8CkaXaoqN8jzH3ohEv9KX3cHIfCAeEg0zNH4+pXDhOjwXc/XIjQ5CoIduYey2JsHt/MyTR/5SrguMcr0VZLqYqJDy5Dd81kL46YlBACq5p1u7effgmVqb64MPGVaVU0FdUFv3CX4cLtEEEG63X1aijxPnKGyy5XEM+k/DFbw25xBBM1UJKECgYEAxCt21DWtS+1g6VVJA+qbpBMSzfA/xblvXyz5owCMmopte3WnzLPlkHdgTxlZSeRHursOPFd3v8hOmovFNw+OBS8Fhdy0b7tLwmb55CEOX7MsLJ5pqsUE+5IjGAVGJNHRlxTtDDXA8fILpeRJouAtAcrheyjmqWz8tsQ1okgWL8UCgYEAuYSZzcwKNHjBwOoMsxxmuh7hM+CXiO5TXnhuFkrVOR23147spKvUaV97z2SHEtbj13k70BTCVMCAyQOrMgL/ro0XHl2dK8zKPSuZvYC23r+AsE69edeJz2uYjDOxXfJJFNL4jqRDfNG/Cbk6VimkVzaeKdfnsf3MYQ5CFZ8eCY0CgYBpDsXy3FRU52oRTEVwPYLhGf3mIJZms+q7VADVlQO3+A6uIdKdxHJbLjN76R1yfzkS/f6fvlA5e3LtPZF+7Wunxwj0KcDQXcQy9qc5z6I9Cl3L/4KjnCQQ/rCguqJYMa5HdUOGWHtel7w5Octd2SUBYr/jD4KIlf+5edcnc+e96QKBgHZtO3GwSuNsIuNvhWPhQYKWq9ReDt4OpZGs9zmr06l+Wxlz14TXW+VYWsTtu3w/SXsHnTMbzWIk8RFhEiv+1hEraBKuV+LZ/FBIQQBD5nkTbqcd3L6m5QZP/TWi2hrKy/RLKPiFy78mdflTEPZn5sz1xMmZVgK9rXZXj8AVrysRAoGBAJJfMtoeNO8bj0TuvC/u+OFUsazjBziTrFRAlrVU6pUkZ+P8huKindNnQSzkH92JpdoPgPPzRsw8yFai3wgRPrExsSosELulEAZMZNnPEn7BxiTQjB7wcCSnRXAmW6g5wUjHhu1wAhGJpV1RSCVMgsfNQy6NOZizQahc6u4Qb77/ + rsaPublicKey: MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAik1dhiQNVn69cTq3WhhUxKKDwRQtdKbbAzRTTvkwcYH2J07iG0EmRZTqmZKTvNqGKizQbz9eNrMh7Awn5B+t8aTc+xe3amj7bngf0zk2jAwK36Hrokv5oOCAiyAWSEt9/M6gWUf0R+av5JS34XZmfDVyhcu2+3PdWBaqKlOx0HX9TphuDJDHqWP13+It5X2Iv1kkiaqcY6yjhBF8RlP1vD+Y77W4p+h9QHIAVCJGykjBDBf51pxHMrOuj1yFOpWCX4UlYQISPfdlgu+FARW38mjqV/J2QwITcseg1sb1aRvA2Bve+zdcQTAwNpUwOnqsfov+p7Vh0+VXUt1vyk0abQIDAQAB + customSocketTimeout: 20000 + customConnectTimeout: 20000 + customConnectionRequestTimeout: 20000 \ No newline at end of file