From a9f9b36d71d32c1458a59f20b55cdf8298ef97d6 Mon Sep 17 00:00:00 2001 From: crm <852858682@qq.com> Date: Tue, 29 Apr 2025 21:51:17 +0800 Subject: [PATCH] =?UTF-8?q?=E3=80=90=E5=8A=9F=E8=83=BD=E4=BC=98=E5=8C=96?= =?UTF-8?q?=E3=80=91=20=E6=94=AF=E4=BB=98=E5=9B=9E=E8=B0=83=E7=9B=B8?= =?UTF-8?q?=E5=85=B3=E6=8E=A5=E5=8F=A3=E5=A2=9E=E5=8A=A0=E8=AF=B7=E6=B1=82?= =?UTF-8?q?=E5=A4=B4=E5=8F=82=E6=95=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../admin/notify/PayNotifyController.java | 15 +++--- .../framework/pay/core/WalletPayClient.java | 6 +-- .../framework/pay/core/client/PayClient.java | 9 ++-- .../core/client/impl/AbstractPayClient.java | 18 +++---- .../impl/alipay/AbstractAlipayPayClient.java | 6 +-- .../core/client/impl/mock/MockPayClient.java | 6 +-- .../impl/weixin/AbstractWxPayClient.java | 47 ++++++++++++------- 7 files changed, 64 insertions(+), 43 deletions(-) diff --git a/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/controller/admin/notify/PayNotifyController.java b/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/controller/admin/notify/PayNotifyController.java index 7da7fd1d1..e2860f672 100644 --- a/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/controller/admin/notify/PayNotifyController.java +++ b/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/controller/admin/notify/PayNotifyController.java @@ -64,7 +64,8 @@ public class PayNotifyController { @PermitAll public String notifyOrder(@PathVariable("channelId") Long channelId, @RequestParam(required = false) Map params, - @RequestBody(required = false) String body) { + @RequestBody(required = false) String body, + @RequestHeader Map headers) { log.info("[notifyOrder][channelId({}) 回调数据({}/{})]", channelId, params, body); // 1. 校验支付渠道是否存在 PayClient payClient = channelService.getPayClient(channelId); @@ -74,7 +75,7 @@ public class PayNotifyController { } // 2. 解析通知数据 - PayOrderRespDTO notify = payClient.parseOrderNotify(params, body); + PayOrderRespDTO notify = payClient.parseOrderNotify(params, body, headers); orderService.notifyOrder(channelId, notify); return "success"; } @@ -84,7 +85,8 @@ public class PayNotifyController { @PermitAll public String notifyRefund(@PathVariable("channelId") Long channelId, @RequestParam(required = false) Map params, - @RequestBody(required = false) String body) { + @RequestBody(required = false) String body, + @RequestHeader Map headers) { log.info("[notifyRefund][channelId({}) 回调数据({}/{})]", channelId, params, body); // 1. 校验支付渠道是否存在 PayClient payClient = channelService.getPayClient(channelId); @@ -94,7 +96,7 @@ public class PayNotifyController { } // 2. 解析通知数据 - PayRefundRespDTO notify = payClient.parseRefundNotify(params, body); + PayRefundRespDTO notify = payClient.parseRefundNotify(params, body, headers); refundService.notifyRefund(channelId, notify); return "success"; } @@ -104,7 +106,8 @@ public class PayNotifyController { @PermitAll public String notifyTransfer(@PathVariable("channelId") Long channelId, @RequestParam(required = false) Map params, - @RequestBody(required = false) String body) { + @RequestBody(required = false) String body, + @RequestHeader Map headers) { log.info("[notifyTransfer][channelId({}) 回调数据({}/{})]", channelId, params, body); // 1. 校验支付渠道是否存在 PayClient payClient = channelService.getPayClient(channelId); @@ -114,7 +117,7 @@ public class PayNotifyController { } // 2. 解析通知数据 - PayTransferRespDTO notify = payClient.parseTransferNotify(params, body); + PayTransferRespDTO notify = payClient.parseTransferNotify(params, body, headers); payTransferService.notifyTransfer(channelId, notify); return "success"; } diff --git a/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/framework/pay/core/WalletPayClient.java b/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/framework/pay/core/WalletPayClient.java index 63fc92ba3..bfb7d7706 100644 --- a/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/framework/pay/core/WalletPayClient.java +++ b/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/framework/pay/core/WalletPayClient.java @@ -89,7 +89,7 @@ public class WalletPayClient extends AbstractPayClient { } @Override - protected PayOrderRespDTO doParseOrderNotify(Map params, String body) { + protected PayOrderRespDTO doParseOrderNotify(Map params, String body, Map headers) { throw new UnsupportedOperationException("钱包支付无支付回调"); } @@ -144,7 +144,7 @@ public class WalletPayClient extends AbstractPayClient { } @Override - protected PayRefundRespDTO doParseRefundNotify(Map params, String body) { + protected PayRefundRespDTO doParseRefundNotify(Map params, String body, Map headers) { throw new UnsupportedOperationException("钱包支付无退款回调"); } @@ -178,7 +178,7 @@ public class WalletPayClient extends AbstractPayClient { } @Override - protected PayTransferRespDTO doParseTransferNotify(Map params, String body) throws Throwable { + protected PayTransferRespDTO doParseTransferNotify(Map params, String body, Map headers) throws Throwable { throw new UnsupportedOperationException("未实现"); } diff --git a/yudao-module-pay/yudao-spring-boot-starter-biz-pay/src/main/java/cn/iocoder/yudao/framework/pay/core/client/PayClient.java b/yudao-module-pay/yudao-spring-boot-starter-biz-pay/src/main/java/cn/iocoder/yudao/framework/pay/core/client/PayClient.java index 816b6fef7..64a56a5ca 100644 --- a/yudao-module-pay/yudao-spring-boot-starter-biz-pay/src/main/java/cn/iocoder/yudao/framework/pay/core/client/PayClient.java +++ b/yudao-module-pay/yudao-spring-boot-starter-biz-pay/src/main/java/cn/iocoder/yudao/framework/pay/core/client/PayClient.java @@ -39,9 +39,10 @@ public interface PayClient { * * @param params HTTP 回调接口 content type 为 application/x-www-form-urlencoded 的所有参数 * @param body HTTP 回调接口的 request body + * @param headers HTTP 回调接口的 request headers * @return 支付订单信息 */ - PayOrderRespDTO parseOrderNotify(Map params, String body); + PayOrderRespDTO parseOrderNotify(Map params, String body, Map headers); /** * 获得支付订单信息 @@ -66,9 +67,10 @@ public interface PayClient { * * @param params HTTP 回调接口 content type 为 application/x-www-form-urlencoded 的所有参数 * @param body HTTP 回调接口的 request body + * @param headers HTTP 回调接口的 request headers * @return 支付订单信息 */ - PayRefundRespDTO parseRefundNotify(Map params, String body); + PayRefundRespDTO parseRefundNotify(Map params, String body, Map headers); /** * 获得退款订单信息 @@ -103,8 +105,9 @@ public interface PayClient { * * @param params HTTP 回调接口 content type 为 application/x-www-form-urlencoded 的所有参数 * @param body HTTP 回调接口的 request body + * @param headers HTTP 回调接口的 request headers * @return 转账信息 */ - PayTransferRespDTO parseTransferNotify(Map params, String body); + PayTransferRespDTO parseTransferNotify(Map params, String body, Map headers); } diff --git a/yudao-module-pay/yudao-spring-boot-starter-biz-pay/src/main/java/cn/iocoder/yudao/framework/pay/core/client/impl/AbstractPayClient.java b/yudao-module-pay/yudao-spring-boot-starter-biz-pay/src/main/java/cn/iocoder/yudao/framework/pay/core/client/impl/AbstractPayClient.java index 5c4750402..753cfbd7d 100644 --- a/yudao-module-pay/yudao-spring-boot-starter-biz-pay/src/main/java/cn/iocoder/yudao/framework/pay/core/client/impl/AbstractPayClient.java +++ b/yudao-module-pay/yudao-spring-boot-starter-biz-pay/src/main/java/cn/iocoder/yudao/framework/pay/core/client/impl/AbstractPayClient.java @@ -101,9 +101,9 @@ public abstract class AbstractPayClient implemen throws Throwable; @Override - public final PayOrderRespDTO parseOrderNotify(Map params, String body) { + public final PayOrderRespDTO parseOrderNotify(Map params, String body, Map headers) { try { - return doParseOrderNotify(params, body); + return doParseOrderNotify(params, body, headers); } catch (ServiceException ex) { // 业务异常,都是实现类已经翻译,所以直接抛出即可 throw ex; } catch (Throwable ex) { @@ -113,7 +113,7 @@ public abstract class AbstractPayClient implemen } } - protected abstract PayOrderRespDTO doParseOrderNotify(Map params, String body) + protected abstract PayOrderRespDTO doParseOrderNotify(Map params, String body, Map headers) throws Throwable; @Override @@ -155,9 +155,9 @@ public abstract class AbstractPayClient implemen protected abstract PayRefundRespDTO doUnifiedRefund(PayRefundUnifiedReqDTO reqDTO) throws Throwable; @Override - public final PayRefundRespDTO parseRefundNotify(Map params, String body) { + public final PayRefundRespDTO parseRefundNotify(Map params, String body, Map headers) { try { - return doParseRefundNotify(params, body); + return doParseRefundNotify(params, body, headers); } catch (ServiceException ex) { // 业务异常,都是实现类已经翻译,所以直接抛出即可 throw ex; } catch (Throwable ex) { @@ -167,7 +167,7 @@ public abstract class AbstractPayClient implemen } } - protected abstract PayRefundRespDTO doParseRefundNotify(Map params, String body) + protected abstract PayRefundRespDTO doParseRefundNotify(Map params, String body, Map headers) throws Throwable; @Override @@ -220,9 +220,9 @@ public abstract class AbstractPayClient implemen } @Override - public final PayTransferRespDTO parseTransferNotify(Map params, String body) { + public final PayTransferRespDTO parseTransferNotify(Map params, String body, Map headers) { try { - return doParseTransferNotify(params, body); + return doParseTransferNotify(params, body, headers); } catch (ServiceException ex) { // 业务异常,都是实现类已经翻译,所以直接抛出即可 throw ex; } catch (Throwable ex) { @@ -232,7 +232,7 @@ public abstract class AbstractPayClient implemen } } - protected abstract PayTransferRespDTO doParseTransferNotify(Map params, String body) + protected abstract PayTransferRespDTO doParseTransferNotify(Map params, String body, Map headers) throws Throwable; @Override diff --git a/yudao-module-pay/yudao-spring-boot-starter-biz-pay/src/main/java/cn/iocoder/yudao/framework/pay/core/client/impl/alipay/AbstractAlipayPayClient.java b/yudao-module-pay/yudao-spring-boot-starter-biz-pay/src/main/java/cn/iocoder/yudao/framework/pay/core/client/impl/alipay/AbstractAlipayPayClient.java index b3075eb03..6b1251f58 100644 --- a/yudao-module-pay/yudao-spring-boot-starter-biz-pay/src/main/java/cn/iocoder/yudao/framework/pay/core/client/impl/alipay/AbstractAlipayPayClient.java +++ b/yudao-module-pay/yudao-spring-boot-starter-biz-pay/src/main/java/cn/iocoder/yudao/framework/pay/core/client/impl/alipay/AbstractAlipayPayClient.java @@ -79,7 +79,7 @@ public abstract class AbstractAlipayPayClient extends AbstractPayClient params, String body) throws Throwable { + public PayOrderRespDTO doParseOrderNotify(Map params, String body, Map headers) throws Throwable { // 1. 校验回调数据 Map bodyObj = HttpUtil.decodeParamMap(body, StandardCharsets.UTF_8); AlipaySignature.rsaCheckV1(bodyObj, config.getAlipayPublicKey(), @@ -175,7 +175,7 @@ public abstract class AbstractAlipayPayClient extends AbstractPayClient params, String body) { + public PayRefundRespDTO doParseRefundNotify(Map params, String body, Map headers) { // 补充说明:支付宝退款时,没有回调,这点和微信支付是不同的。并且,退款分成部分退款、和全部退款。 // ① 部分退款:是会有回调,但是它回调的是订单状态的同步回调,不是退款订单的回调 // ② 全部退款:Wap 支付有订单状态的同步回调,但是 PC/扫码又没有 @@ -327,7 +327,7 @@ public abstract class AbstractAlipayPayClient extends AbstractPayClient params, String body) throws Throwable { + protected PayTransferRespDTO doParseTransferNotify(Map params, String body, Map headers) throws Throwable { throw new UnsupportedOperationException("未实现"); } diff --git a/yudao-module-pay/yudao-spring-boot-starter-biz-pay/src/main/java/cn/iocoder/yudao/framework/pay/core/client/impl/mock/MockPayClient.java b/yudao-module-pay/yudao-spring-boot-starter-biz-pay/src/main/java/cn/iocoder/yudao/framework/pay/core/client/impl/mock/MockPayClient.java index 34b1d5db6..11496eb9c 100644 --- a/yudao-module-pay/yudao-spring-boot-starter-biz-pay/src/main/java/cn/iocoder/yudao/framework/pay/core/client/impl/mock/MockPayClient.java +++ b/yudao-module-pay/yudao-spring-boot-starter-biz-pay/src/main/java/cn/iocoder/yudao/framework/pay/core/client/impl/mock/MockPayClient.java @@ -58,17 +58,17 @@ public class MockPayClient extends AbstractPayClient { } @Override - protected PayTransferRespDTO doParseTransferNotify(Map params, String body) throws Throwable { + protected PayTransferRespDTO doParseTransferNotify(Map params, String body, Map headers) throws Throwable { throw new UnsupportedOperationException("未实现"); } @Override - protected PayRefundRespDTO doParseRefundNotify(Map params, String body) { + protected PayRefundRespDTO doParseRefundNotify(Map params, String body, Map headers) { throw new UnsupportedOperationException("模拟支付无退款回调"); } @Override - protected PayOrderRespDTO doParseOrderNotify(Map params, String body) { + protected PayOrderRespDTO doParseOrderNotify(Map params, String body, Map headers) { throw new UnsupportedOperationException("模拟支付无支付回调"); } diff --git a/yudao-module-pay/yudao-spring-boot-starter-biz-pay/src/main/java/cn/iocoder/yudao/framework/pay/core/client/impl/weixin/AbstractWxPayClient.java b/yudao-module-pay/yudao-spring-boot-starter-biz-pay/src/main/java/cn/iocoder/yudao/framework/pay/core/client/impl/weixin/AbstractWxPayClient.java index 374afccad..7d54928a2 100644 --- a/yudao-module-pay/yudao-spring-boot-starter-biz-pay/src/main/java/cn/iocoder/yudao/framework/pay/core/client/impl/weixin/AbstractWxPayClient.java +++ b/yudao-module-pay/yudao-spring-boot-starter-biz-pay/src/main/java/cn/iocoder/yudao/framework/pay/core/client/impl/weixin/AbstractWxPayClient.java @@ -18,10 +18,7 @@ import cn.iocoder.yudao.framework.pay.core.client.dto.transfer.WxPayTransferPart import cn.iocoder.yudao.framework.pay.core.client.impl.AbstractPayClient; import cn.iocoder.yudao.framework.pay.core.enums.order.PayOrderStatusRespEnum; import cn.iocoder.yudao.framework.pay.core.enums.transfer.PayTransferTypeEnum; -import com.github.binarywang.wxpay.bean.notify.WxPayNotifyV3Result; -import com.github.binarywang.wxpay.bean.notify.WxPayOrderNotifyResult; -import com.github.binarywang.wxpay.bean.notify.WxPayRefundNotifyResult; -import com.github.binarywang.wxpay.bean.notify.WxPayRefundNotifyV3Result; +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.QueryTransferBatchesRequest; @@ -157,12 +154,12 @@ public abstract class AbstractWxPayClient extends AbstractPayClient params, String body) throws WxPayException { + public PayOrderRespDTO doParseOrderNotify(Map params, String body, Map headers) throws WxPayException { switch (config.getApiVersion()) { case API_VERSION_V2: return doParseOrderNotifyV2(body); case API_VERSION_V3: - return doParseOrderNotifyV3(body); + return doParseOrderNotifyV3(body, headers); default: throw new IllegalArgumentException(String.format("未知的 API 版本(%s)", config.getApiVersion())); } @@ -179,9 +176,10 @@ public abstract class AbstractWxPayClient extends AbstractPayClient headers) throws WxPayException { // 1. 解析回调 - WxPayNotifyV3Result response = client.parseOrderNotifyV3Result(body, null); + SignatureHeader header = getRequestHeader(headers); + WxPayNotifyV3Result response = client.parseOrderNotifyV3Result(body, header); WxPayNotifyV3Result.DecryptNotifyResult result = response.getResult(); // 2. 构建结果 Integer status = parseStatus(result.getTradeState()); @@ -190,6 +188,21 @@ public abstract class AbstractWxPayClient extends AbstractPayClient headers) { + // 获取通知签名 + String signature = headers.get("wechatpay-signature"); + String nonce = headers.get("wechatpay-nonce"); + String serial = headers.get("wechatpay-serial"); + String timestamp = headers.get("wechatpay-timestamp"); + + SignatureHeader signatureHeader = new SignatureHeader(); + signatureHeader.setSignature(signature); + signatureHeader.setNonce(nonce); + signatureHeader.setSerial(serial); + signatureHeader.setTimeStamp(timestamp); + return signatureHeader; + } + @Override protected PayOrderRespDTO doGetOrder(String outTradeNo) throws Throwable { try { @@ -321,12 +334,12 @@ public abstract class AbstractWxPayClient extends AbstractPayClient params, String body) throws WxPayException { + 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); + return parseRefundNotifyV3(body, headers); default: throw new IllegalArgumentException(String.format("未知的 API 版本(%s)", config.getApiVersion())); } @@ -344,9 +357,10 @@ public abstract class AbstractWxPayClient extends AbstractPayClient headers) throws WxPayException { // 1. 解析回调 - WxPayRefundNotifyV3Result response = client.parseRefundNotifyV3Result(body, null); + SignatureHeader header = getRequestHeader(headers); + WxPayRefundNotifyV3Result response = client.parseRefundNotifyV3Result(body, header); WxPayRefundNotifyV3Result.DecryptNotifyResult result = response.getResult(); // 2. 构建结果 if (Objects.equals("SUCCESS", result.getRefundStatus())) { @@ -357,10 +371,10 @@ public abstract class AbstractWxPayClient extends AbstractPayClient params, String body) throws WxPayException { + public PayTransferRespDTO doParseTransferNotify(Map params, String body, Map headers) throws WxPayException { switch (config.getApiVersion()) { case API_VERSION_V3: - return parseTransferNotifyV3(body); + return parseTransferNotifyV3(body, headers); case API_VERSION_V2: throw new UnsupportedOperationException("V2 版本暂不支持,建议使用 V3 版本"); default: @@ -368,10 +382,11 @@ public abstract class AbstractWxPayClient extends AbstractPayClient headers) throws WxPayException { // 1. 解析回调 + SignatureHeader header = getRequestHeader(headers); // TODO @luchi:这个可以复用 wxjava 里的类么? - WxPayTransferPartnerNotifyV3Result response = client.baseParseOrderNotifyV3Result(body, null, WxPayTransferPartnerNotifyV3Result.class, WxPayTransferPartnerNotifyV3Result.TransferNotifyResult.class); + WxPayTransferPartnerNotifyV3Result response = client.baseParseOrderNotifyV3Result(body, header, WxPayTransferPartnerNotifyV3Result.class, WxPayTransferPartnerNotifyV3Result.TransferNotifyResult.class); WxPayTransferPartnerNotifyV3Result.TransferNotifyResult result = response.getResult(); // 2. 构建结果 if (Objects.equals("FINISHED", result.getBatchStatus())) {