2024-10-09 09:33:13.595 INFO 928036 --- [nio-8085-exec-7] c.l.m.portal.controller.WXPayController : into receivePayNotify method=============================================
2024-10-09 09:33:13.595 INFO 928036 --- [nio-8085-exec-7] c.l.m.portal.controller.WXPayController : request is org.apache.catalina.connector.RequestFacade@20a29b37
2024-10-09 09:33:13.596 INFO 928036 --- [nio-8085-exec-7] c.l.m.p.service.impl.WXPayServiceImpl :
wechatPaySerial is [57184D0BFD9FE4506E06B8D84B8E4E2BE46BDEC5] ,
wechatSignature is [e1xRxe6nQhMjo/TbEA7Z1iwrXYfn3Ozd4iSED/vuQ+E01v+0FWEoBPVHStEla9XbBM3Q6qvrs2OcsR9hD87DAgcawabFdr81FQ8csMhOL0OWdvgyXDlMZS+FGTa5LMLBJ4GPnjAivPAB1iE6RhfVjbIx3jdMGbpxxJOKYkrw32s3kjU+dE7gaLoL9TStAIsRr2jt4y6lY8McMWJGWc/0W8VSs3BkHrFmPS9vQGxlSE76yXlbvyzphKbRvPZeFjXQVLicgAd3qpUmo8NLmbeDE3aciCoNVwzJScBAw2RNQum5hKbGrEAohp9mJe1yktgcpEFnxyTzHddhwqi/ifDBBQ==] ,
wechatTimestamp is [1728437594] ,
wechatpayNonce is [ukDaEPvYjkM5choqNcYJwAjiC64BonHH] ,
requestBody is [{"id":"7b2b145f-9cda-5573-8be2-d2d9eaaffa25","create_time":"2024-10-09T09:33:13+08:00","resource_type":"encrypt-resource","event_type":"TRANSACTION.SUCCESS","summary":"支付成功","resource":{"original_type":"transaction","algorithm":"AEAD_AES_256_GCM","ciphertext":"UmpebugBzDwyzkuS8MuBdtdi42jiaiAdlYNT3UxJkWf80e/Zhjt5FFNNECor58hYRjlIH/4YaSOzfiElbp1jWWyjv5Uwu2wk2IJkkHhYpr7WBiv3+vAY5OkGnMkbawVVr7JV1XNAbZlbmi8MJxu/IwjbjtfY8lJ/tWWMPxRyYFVtGt72w7Wm3wdpYTR9tgLdPGSRJfzpSAubGNeHVl7yJP8ZvulpxcGnbUynkXa4J3f7qwe+7pJk3SLQRd+cpbwMn5Udx/L/nYsszmn8CtUgUPfRrGHC2ZffMeAAE5LONeo13du0JQ6i7DmrkWMYoDIr4e+PU73wBHnTm8tbo0Icbba5UyhmF/leNAnWV2Biz2uK+09JAJka1BaRGfZVHGoswnVrTdVG+KYuaabG+6UBQefVpfMuvcsFudtUvxCObBh1wFSZWP+jCXq2b53/XVBI+0F/udleVfbGjsw9w3amqjZnvUv+pt1eTh5v5BkOVXkgOUQA6sE7NLjMldcVIFdkj11ItI6tUVfNPeX8+9+sFdRqARFRFui36cDEEtNHo/HG26cVEDK2WMO7YIKjlTFguA==","associated_data":"transaction","nonce":"P4WRnf2zIvU2"}}]
2024-10-09 09:33:13.598 DEBUG 928036 --- [nio-8085-exec-7] c.w.p.j.core.auth.WechatPay2Credential : authorization message[GET
/v3/certificates?algorithm_type=RSA
1728437593
rG3ETdPayAcKK4a9lvQBEdHh9N8z5I3i
]
2024-10-09 09:33:13.607 DEBUG 928036 --- [nio-8085-exec-7] c.w.p.j.core.auth.WechatPay2Credential : The generated request signature information is[mchid="1692170120",nonce_str="rG3ETdPayAcKK4a9lvQBEdHh9N8z5I3i",timestamp="1728437593",serial_no="1E30E11D67DF818DE69195225C6C27B781417661",signature="D77+/3g+lA0HCFRirTa3lzhSRFHvXHys/Xb8CHNU8WgMcN1HWVusZ/r/H8xyTTUIV6J/We6rIoE70DST81WdXEkisDdebqor6fDi2IPiI0u024uM4xs9Cxe6d4hpvMekr0n0m32gUSFnJrDNehrDsA8KQ33NJ4r++PA8/EbrMmD56vSbpZuQKZnkWazGbV6yz0nbriykP5MbLaKLPWp5FHU3UpoLZvYazO65uqgJnYyKGJtIoiGpauo1PwCZG1Eob9T8kuEt/ABMzztStLIB2/eGLtS1/HaPqwEHarLJQm3WM12RB8cTjUagIuoyh6VyHoce2RwNk+yrr1HG5bLkIg=="]
2024-10-09 09:33:13.776 ERROR 928036 --- [nio-8085-exec-7] c.l.m.p.service.impl.WXPayServiceImpl : sign verification failed
com.wechat.pay.java.core.exception.ValidationException:
Processing WechatPay notification,
signature verification failed,
signType[WECHATPAY2-SHA256-RSA2048]
serial[57184D0BFD9FE4506E06B8D84B8E4E2BE46BDEC5]
message[1728437594
ukDaEPvYjkM5choqNcYJwAjiC64BonHH
{"id":"7b2b145f-9cda-5573-8be2-d2d9eaaffa25","create_time":"2024-10-09T09:33:13+08:00","resource_type":"encrypt-resource",
"event_type":"TRANSACTION.SUCCESS","summary":"支付成功",
"resource":{"original_type":"transaction","algorithm":"AEAD_AES_256_GCM",
"ciphertext":"UmpebugBzDwyzkuS8MuBdtdi42jiaiAdlYNT3UxJkWf80e/Zhjt5FFNNECor58hYRjlIH/4YaSOzfiElbp1jWWyjv5Uwu2wk2IJkkHhYpr7WBiv3+vAY5OkGnMkbawVVr7JV1XNAbZlbmi8MJxu/IwjbjtfY8lJ/tWWMPxRyYFVtGt72w7Wm3wdpYTR9tgLdPGSRJfzpSAubGNeHVl7yJP8ZvulpxcGnbUynkXa4J3f7qwe+7pJk3SLQRd+cpbwMn5Udx/L/nYsszmn8CtUgUPfRrGHC2ZffMeAAE5LONeo13du0JQ6i7DmrkWMYoDIr4e+PU73wBHnTm8tbo0Icbba5UyhmF/leNAnWV2Biz2uK+09JAJka1BaRGfZVHGoswnVrTdVG+KYuaabG+6UBQefVpfMuvcsFudtUvxCObBh1wFSZWP+jCXq2b53/XVBI+0F/udleVfbGjsw9w3amqjZnvUv+pt1eTh5v5BkOVXkgOUQA6sE7NLjMldcVIFdkj11ItI6tUVfNPeX8+9+sFdRqARFRFui36cDEEtNHo/HG26cVEDK2WMO7YIKjlTFguA==",
"associated_data":"transaction","nonce":"P4WRnf2zIvU2"}}
] sign[e1xRxe6nQhMjo/TbEA7Z1iwrXYfn3Ozd4iSED/vuQ+E01v+0FWEoBPVHStEla9XbBM3Q6qvrs2OcsR9hD87DAgcawabFdr81FQ8csMhOL0OWdvgyXDlMZS+FGTa5LMLBJ4GPnjAivPAB1iE6RhfVjbIx3jdMGbpxxJOKYkrw32s3kjU+dE7gaLoL9TStAIsRr2jt4y6lY8McMWJGWc/0W8VSs3BkHrFmPS9vQGxlSE76yXlbvyzphKbRvPZeFjXQVLicgAd3qpUmo8NLmbeDE3aciCoNVwzJScBAw2RNQum5hKbGrEAohp9mJe1yktgcpEFnxyTzHddhwqi/ifDBBQ==]
at com.wechat.pay.java.core.notification.NotificationParser.validateRequest(NotificationParser.java:93) ~[wechatpay-java-core-0.2.14.jar!/:0.2.14]
at com.wechat.pay.java.core.notification.NotificationParser.parse(NotificationParser.java:49) ~[wechatpay-java-core-0.2.14.jar!/:0.2.14]
at com.langke.mall.portal.service.impl.WXPayServiceImpl.receivePayNotify(WXPayServiceImpl.java:222) ~[classes!/:1.0-SNAPSHOT]
at com.langke.mall.portal.controller.WXPayController.receivePayNotify(WXPayController.java:46) [classes!/:1.0-SNAPSHOT]
at com.langke.mall.portal.controller.WXPayController$$FastClassBySpringCGLIB$$b159352.invoke(<generated>) [classes!/:1.0-SNAPSHOT]
at org.springframework.cglib.proxy.MethodProxy.invoke(MethodProxy.java:218) [spring-core-5.3.20.jar!/:5.3.20]
at org.springframework.aop.framework.CglibAopProxy$CglibMethodInvocation.invokeJoinpoint(CglibAopProxy.java:793) [spring-aop-5.3.20.jar!/:5.3.20]
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:163) [spring-aop-5.3.20.jar!/:5.3.20]
at org.springframework.aop.framework.CglibAopProxy$CglibMethodInvocation.proceed(CglibAopProxy.java:763) [spring-aop-5.3.20.jar!/:5.3.20]
at org.springframework.aop.framework.adapter.AfterReturningAdviceInterceptor.invoke(AfterReturningAdviceInterceptor.java:57) [spring-aop-5.3.20.jar!/:5.3.20]
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:186) [spring-aop-5.3.20.jar!/:5.3.20]
at org.springframework.aop.framework.CglibAopProxy$CglibMethodInvocation.proceed(CglibAopProxy.java:763) [spring-aop-5.3.20.jar!/:5.3.20]
at org.springframework.aop.framework.adapter.MethodBeforeAdviceInterceptor.invoke(MethodBeforeAdviceInterceptor.java:58) [spring-aop-5.3.20.jar!/:5.3.20]
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:186) [spring-aop-5.3.20.jar!/:5.3.20]
at org.springframework.aop.framework.CglibAopProxy$CglibMethodInvocation.proceed(CglibAopProxy.java:763) [spring-aop-5.3.20.jar!/:5.3.20]
at org.springframework.aop.aspectj.MethodInvocationProceedingJoinPoint.proceed(MethodInvocationProceedingJoinPoint.java:89) [spring-aop-5.3.20.jar!/:5.3.20]
at com.langke.mall.common.log.WebLogAspect.doAround(WebLogAspect.java:62) [mall-common-1.0-SNAPSHOT.jar!/:1.0-SNAPSHOT]
at sun.reflect.GeneratedMethodAccessor215.invoke(Unknown Source) ~[na:na]
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[na:1.8.0_111]
at java.lang.reflect.Method.invoke(Method.java:498) ~[na:1.8.0_111]
at org.springframework.aop.aspectj.AbstractAspectJAdvice.invokeAdviceMethodWithGivenArgs(AbstractAspectJAdvice.java:634) [spring-aop-5.3.20.jar!/:5.3.20]
at org.springframework.aop.aspectj.AbstractAspectJAdvice.invokeAdviceMethod(AbstractAspectJAdvice.java:624) [spring-aop-5.3.20.jar!/:5.3.20]
at org.springframework.aop.aspectj.AspectJAroundAdvice.invoke(AspectJAroundAdvice.java:72) [spring-aop-5.3.20.jar!/:5.3.20]
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:186) [spring-aop-5.3.20.jar!/:5.3.20]
at org.springframework.aop.framework.CglibAopProxy$CglibMethodInvocation.proceed(CglibAopProxy.java:763) [spring-aop-5.3.20.jar!/:5.3.20]
at org.springframework.aop.interceptor.ExposeInvocationInterceptor.invoke(ExposeInvocationInterceptor.java:97) [spring-aop-5.3.20.jar!/:5.3.20]
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:186) [spring-aop-5.3.20.jar!/:5.3.20]
at org.springframework.aop.framework.CglibAopProxy$CglibMethodInvocation.proceed(CglibAopProxy.java:763) [spring-aop-5.3.20.jar!/:5.3.20]
at org.springframework.aop.framework.CglibAopProxy$DynamicAdvisedInterceptor.intercept(CglibAopProxy.java:708) [spring-aop-5.3.20.jar!/:5.3.20]
at com.langke.mall.portal.controller.WXPayController$$EnhancerBySpringCGLIB$$92a44f53.receivePayNotify(<generated>) [classes!/:1.0-SNAPSHOT]
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[na:1.8.0_111]
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) ~[na:1.8.0_111]
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[na:1.8.0_111]
at java.lang.reflect.Method.invoke(Method.java:498) ~[na:1.8.0_111]
at org.springframework.web.method.support.InvocableHandlerMethod.doInvoke(InvocableHandlerMethod.java:205) [spring-web-5.3.20.jar!/:5.3.20]
at org.springframework.web.method.support.InvocableHandlerMethod.invokeForRequest(InvocableHandlerMethod.java:150) [spring-web-5.3.20.jar!/:5.3.20]
at org.springframework.web.servlet.mvc.method.annotation.ServletInvocableHandlerMethod.invokeAndHandle(ServletInvocableHandlerMethod.java:117) [spring-webmvc-5.3.20.jar!/:5.3.20]
at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.invokeHandlerMethod(RequestMappingHandlerAdapter.java:895) [spring-webmvc-5.3.20.jar!/:5.3.20]
at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.handleInternal(RequestMappingHandlerAdapter.java:808) [spring-webmvc-5.3.20.jar!/:5.3.20]
at org.springframework.web.servlet.mvc.method.AbstractHandlerMethodAdapter.handle(AbstractHandlerMethodAdapter.java:87) [spring-webmvc-5.3.20.jar!/:5.3.20]
at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:1067) [spring-webmvc-5.3.20.jar!/:5.3.20]
at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:963) [spring-webmvc-5.3.20.jar!/:5.3.20]
at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:1006) [spring-webmvc-5.3.20.jar!/:5.3.20]
at org.springframework.web.servlet.FrameworkServlet.doPost(FrameworkServlet.java:909) [spring-webmvc-5.3.20.jar!/:5.3.20]
at javax.servlet.http.HttpServlet.service(HttpServlet.java:681) [tomcat-embed-core-9.0.63.jar!/:na]
at org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:883) [spring-webmvc-5.3.20.jar!/:5.3.20]
at javax.servlet.http.HttpServlet.service(HttpServlet.java:764) [tomcat-embed-core-9.0.63.jar!/:na]
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:227) [tomcat-embed-core-9.0.63.jar!/:na]
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:162) [tomcat-embed-core-9.0.63.jar!/:na]
at org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:53) [tomcat-embed-websocket-9.0.63.jar!/:na]
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:189) [tomcat-embed-core-9.0.63.jar!/:na]
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:162) [tomcat-embed-core-9.0.63.jar!/:na]
at org.springframework.web.filter.RequestContextFilter.doFilterInternal(RequestContextFilter.java:100) [spring-web-5.3.20.jar!/:5.3.20]
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:117) [spring-web-5.3.20.jar!/:5.3.20]
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:189) [tomcat-embed-core-9.0.63.jar!/:na]
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:162) [tomcat-embed-core-9.0.63.jar!/:na]
at org.springframework.web.filter.FormContentFilter.doFilterInternal(FormContentFilter.java:93) [spring-web-5.3.20.jar!/:5.3.20]
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:117) [spring-web-5.3.20.jar!/:5.3.20]
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:189) [tomcat-embed-core-9.0.63.jar!/:na]
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:162) [tomcat-embed-core-9.0.63.jar!/:na]
at org.springframework.boot.actuate.metrics.web.servlet.WebMvcMetricsFilter.doFilterInternal(WebMvcMetricsFilter.java:96) [spring-boot-actuator-2.7.0.jar!/:2.7.0]
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:117) [spring-web-5.3.20.jar!/:5.3.20]
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:189) [tomcat-embed-core-9.0.63.jar!/:na]
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:162) [tomcat-embed-core-9.0.63.jar!/:na]
at org.springframework.web.filter.CharacterEncodingFilter.doFilterInternal(CharacterEncodingFilter.java:201) [spring-web-5.3.20.jar!/:5.3.20]
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:117) [spring-web-5.3.20.jar!/:5.3.20]
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:189) [tomcat-embed-core-9.0.63.jar!/:na]
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:162) [tomcat-embed-core-9.0.63.jar!/:na]
at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:197) [tomcat-embed-core-9.0.63.jar!/:na]
at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:97) [tomcat-embed-core-9.0.63.jar!/:na]
at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:541) [tomcat-embed-core-9.0.63.jar!/:na]
at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:135) [tomcat-embed-core-9.0.63.jar!/:na]
at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:92) [tomcat-embed-core-9.0.63.jar!/:na]
at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:78) [tomcat-embed-core-9.0.63.jar!/:na]
at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:360) [tomcat-embed-core-9.0.63.jar!/:na]
at org.apache.coyote.http11.Http11Processor.service(Http11Processor.java:399) [tomcat-embed-core-9.0.63.jar!/:na]
at org.apache.coyote.AbstractProcessorLight.process(AbstractProcessorLight.java:65) [tomcat-embed-core-9.0.63.jar!/:na]
at org.apache.coyote.AbstractProtocol$ConnectionHandler.process(AbstractProtocol.java:890) [tomcat-embed-core-9.0.63.jar!/:na]
at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1743) [tomcat-embed-core-9.0.63.jar!/:na]
at org.apache.tomcat.util.net.SocketProcessorBase.run(SocketProcessorBase.java:49) [tomcat-embed-core-9.0.63.jar!/:na]
at org.apache.tomcat.util.threads.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1191) [tomcat-embed-core-9.0.63.jar!/:na]
at org.apache.tomcat.util.threads.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:659) [tomcat-embed-core-9.0.63.jar!/:na]
at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61) [tomcat-embed-core-9.0.63.jar!/:na]
at java.lang.Thread.run(Thread.java:745) [na:1.8.0_111]
解决方案:
//接收回调通知报文
//获取请求头中的报文签名信息,用于后续验证签名
//证书序列号(微信平台) 验签的“微信支付平台证书”所对应的平台证书序列号
String wechatPaySerial = request.getHeader("Wechatpay-Serial");
//微信传递过来的签名 验签的签名值
String wechatSignature = request.getHeader("Wechatpay-Signature");
//验签的时间戳
String wechatTimestamp = request.getHeader("Wechatpay-Timestamp");
//验签的随机字符串
String wechatpayNonce = request.getHeader("Wechatpay-Nonce");
//获取报文
// String requestBody = getRequestBody(request);
BufferedReader reader = request.getReader();
String line;
StringBuilder sb = new StringBuilder();
while ((line = reader.readLine()) != null) {
sb.append(line);
}
String requestBody = sb.toString();
log.info("wechatPaySerial is [{}] , wechatSignature is [{}] , wechatTimestamp is [{}] , wechatpayNonce is [{}] , requestBody is [{}]",wechatPaySerial,wechatSignature,wechatTimestamp,wechatpayNonce,requestBody);
// 构造 RequestParam
RequestParam requestParam = new RequestParam.Builder()
.serialNumber(wechatPaySerial)
.nonce(wechatpayNonce)
.signature(wechatSignature)
.timestamp(wechatTimestamp)
.body(requestBody)
.build();
String wechatpaySerial = config.createEncryptor().getWechatpaySerial();
log.info("wechatPaySerial is [{}] ", wechatpaySerial);
//不要用这个,大坑
// NotificationConfig notificationConfig = new RSAAutoCertificateConfig.Builder()
// .merchantId(merchantId)
// .privateKeyFromPath(privateKeyPath)
// .merchantSerialNumber(wxPlatformSerialNumber)
// .apiV3Key(apiV3Key)
// .build();
log.info("config is : {} ",config);
// 初始化 NotificationParser
NotificationParser parser = new NotificationParser((NotificationConfig) config);
try {
// 以支付通知回调为例,验签、解密并转换成 Transaction
Transaction transaction = parser.parse(requestParam, Transaction.class);
log.info("transaction is {} ",transaction);
} catch (ValidationException e) {
// 签名验证失败,返回 401 UNAUTHORIZED 状态码
log.error("sign verification failed", e);
return ResponseEntity.status(HttpStatus.UNAUTHORIZED);
}
// // 如果处理失败,应返回 4xx/5xx 的状态码,例如 500 INTERNAL_SERVER_ERROR
// if (/* process error */) {
// return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR);
// }
// 处理成功,返回 200 OK 状态码
return ResponseEntity.status(HttpStatus.OK);