{"record":{"id":"e85d77780bf1a0d7","repo":"JeffreySu/WeiXinMPSDK","slug":"requestasync-tenpayhttpclient","errorCode":null,"errorMessage":"RequestAsync 签名验证失败：","messagePattern":"RequestAsync 签名验证失败：","errorType":"exception","errorClass":"TenpayApiRequestException","httpStatus":null,"severity":"error","filePath":"src/Senparc.Weixin.TenPay/Senparc.Weixin.TenPayV3/TenPayHttpClient/TenPayHttpClient.cs","lineNumber":295,"sourceCode":"        {\n            return VerifyResponseMessage(responseMessage, content, CancellationToken.None);\n        }\n\n        protected async Task<bool> VerifyResponseMessage(HttpResponseMessage responseMessage, string content, CancellationToken cancellationToken)\n        {\n            var wechatpayTimestamp = responseMessage.Headers.GetValues(\"Wechatpay-Timestamp\").First();\n            var wechatpayNonce = responseMessage.Headers.GetValues(\"Wechatpay-Nonce\").First();\n            var wechatpaySignatureBase64 = responseMessage.Headers.GetValues(\"Wechatpay-Signature\").First();//后续需要base64解码\n            var wechatpaySerial = responseMessage.Headers.GetValues(\"Wechatpay-Serial\").First();\n\n            try\n            {\n                var pubKey = await TenPayV3InfoCollection.GetAPIv3PublicKeyAsync(this._tenpayV3Setting, wechatpaySerial, cancellationToken).ConfigureAwait(false);\n                return _verifier.Verify(wechatpayTimestamp, wechatpayNonce, wechatpaySignatureBase64, content, pubKey, this._tenpayV3Setting.TenPayV3_TenPayPubKeyEnable);\n            }\n            catch (Exception ex)\n            {\n                throw new TenpayApiRequestException(\"RequestAsync 签名验证失败：\" + ex.Message, ex);\n            }\n        }\n\n        /// <summary>\n        /// 获取实例\n        /// </summary>\n        /// <typeparam name=\"T\"></typeparam>\n        /// <param name=\"throwIfFaild\"></param>\n        /// <returns></returns>\n        private T GetInstance<T>(bool throwIfFaild)\n            where T : ReturnJsonBase\n        {\n            if (typeof(T).IsClass)\n            {\n                return Senparc.CO2NET.Helpers.ReflectionHelper.CreateInstance<T>(typeof(T).FullName, typeof(T).Assembly.GetName().Name);\n            }\n            else if (throwIfFaild)\n            {","sourceCodeStart":277,"sourceCodeEnd":313,"githubUrl":"https://github.com/JeffreySu/WeiXinMPSDK/blob/be573f6f94bdbf718dd5f6cdecb137fbc7ff651e/src/Senparc.Weixin.TenPay/Senparc.Weixin.TenPayV3/TenPayHttpClient/TenPayHttpClient.cs#L277-L313","documentation":"VerifyResponseMessage verifies the Wechatpay-Signature on the API response using the public key resolved for the Wechatpay-Serial. Any failure inside that process (missing/unknown serial, bad public key, signature mismatch, network error fetching the key) is wrapped into a TenpayApiRequestException with the prefix 'RequestAsync 签名验证失败：' followed by the inner exception message.","triggerScenarios":"Calling any TenPayV3 API through SendAsync where the response signature cannot be verified: the Wechatpay-Serial does not match a known key, GetAPIv3PublicKeyAsync fails or returns the wrong key, the response body was altered/proxied, or the timestamp/nonce headers were missing.","commonSituations":"A reverse proxy or gateway rewrites the response (breaking the signature); merchant switched between platform certificates and public key mode so the serial lookup fails; expired platform certificate after WeChat rotation; clock skew making timestamp verification fail.","solutions":["Read the inner exception message to identify the root cause (unknown serial vs. signature mismatch).","Update/download the current WeChat Pay platform certificates or public key so the serial in Wechatpay-Serial can be resolved.","Ensure no proxy rewrites the response body or strips Wechatpay-* headers; bypass intermediaries to test.","If TenPayV3_TenPayPubKeyEnable is toggled, confirm it matches your merchant platform mode (public key mode vs certificate mode)."],"exampleFix":"// before (catching generic)\ncatch (Exception ex) { log(ex.Message); }\n// after\ncatch (TenpayApiRequestException ex)\n{\n    log(\"Response signature verify failed: \" + ex.InnerException?.Message);\n    // refresh platform certs / public key, then retry\n}","handlingStrategy":"try-catch","validationCode":"// Ensure key material is current before the call\nvar serial = response.Headers.TryGetValues(\"Wechatpay-Serial\", out var v) ? v.First() : null;\nif (serial != null && !await keyStore.ContainsSerialAsync(serial)) await keyStore.RefreshAsync();","typeGuard":null,"tryCatchPattern":"try { var result = await client.SendAsync(...); }\ncatch (TenpayApiRequestException ex) when (ex.Message.StartsWith(\"RequestAsync 签名验证失败\"))\n{ logger.LogWarning(ex.InnerException, \"Response signature verification failed\"); /* refresh certs, retry once */ }","preventionTips":["Periodically refresh WeChat Pay platform certificates/public keys.","Ensure proxies don't rewrite response bodies or strip Wechatpay-* headers.","Keep server clocks synchronized (NTP) to avoid timestamp checks failing."],"tags":["wechat-pay","signature-verification","http","security"],"backgroundTag":"signature-verification-failed","analyzedSha":"be573f6f94bdbf718dd5f6cdecb137fbc7ff651e","analyzedAt":"2026-09-12T10:01:50.733Z","contentChangedAt":"2026-09-12T10:01:50.733Z","schemaVersion":2},"datasetVersion":"2026-09-16T04:17:20.429Z"}