JeffreySu/WeiXinMPSDK · critical · TenpayApiRequestException
RequestAsync 签名验证失败:
Error message
RequestAsync 签名验证失败:
What it means
The response signature verification block in RequestAsyncCore wraps its work in a try/catch and rethrows any failure (key load errors, signature mismatch, missing headers, key ID mismatch) as TenpayApiRequestException with the prefix 'RequestAsync 签名验证失败:' plus the inner exception message. It signals that WeChat Pay's response could not be authenticated.
Solutions
- Read the InnerException message to identify the precise cause (unknown serial / bad signature / missing header).
- Refresh the WeChat Pay platform certificates (call the certificates download API) so the response serial is known.
- If using brand credentials, confirm WechatpayPublicKeyId matches the response serial exactly.
- Ensure server clock is NTP-synced (timestamp validation is time-sensitive).
- Catch TenpayApiRequestException in your code and fail safely rather than trusting unverified responses.
Example fix
// before
var result = await apiRequest.RequestAsync<JObject>(url, json);
// after
try
{
var result = await apiRequest.RequestAsync<JObject>(url, json);
}
catch (TenpayApiRequestException ex)
{
logger.LogError(ex, "WeChat Pay signature verification failed: {Inner}", ex.InnerException?.Message);
throw; // do not process unverified responses
} Defensive patterns
Strategy: try-catch
Try / catch
try
{
var result = await apiRequest.RequestAsync<TResponse>(url, json);
}
catch (TenpayApiRequestException ex)
{
logger.LogError(ex, "WeChat Pay signature verification failed: {Inner}", ex.InnerException?.Message);
throw; // fail closed on unverified responses
} Prevention
- Periodically refresh WeChat Pay platform certificates so new serials verify.
- Log InnerException messages — they pinpoint unknown-serial vs bad-signature causes.
- Keep server time NTP-synced.
- Treat verification failures as potential MITM and page on-call.
When it happens
Trigger: RequestAsync / RequestWithoutBodyAsync where signature verification throws: missing Wechatpay-* headers, serial not found among known platform certificates/public keys, malformed timestamp/nonce, or signature that doesn't verify against the platform key.
Common situations: Platform certificate not downloaded/refreshed (new serial introduced by WeChat rotation); brand key ID mismatch (see error 144); clock skew making timestamp validation fail; corrupted cached certificates.
Related errors
- 品牌 API 响应的微信支付公钥 ID 与配置不匹配。
- RequestAsync 签名验证失败:
- 证书中未包含 RSA 公钥。
- 文件大小上限必须大于 0。
- 品牌 API 通知的微信支付公钥 ID 与配置不匹配。
AI-assisted analysis of JeffreySu/WeiXinMPSDK@be573f6f94 (2026-09-12).
Data as JSON: /api/errors/51b5ad1ee5a12f23.
Report an issue: GitHub.
Appendix: source
Thrown at src/Senparc.Weixin.TenPay/Senparc.Weixin.TenPayV3/HttpHandlers/TenPayApiRequest.cs:799
var isTenpayPubKey =
TenPaySignHelper.IsPublicKey(
wechatpaySerial);
result.VerifySignSuccess =
TenPaySignHelper
.VerifyTenpaySign(
_tenpayV3Setting
.EncryptionType.Value,
wechatpayTimestamp,
wechatpayNonce,
wechatpaySignatureBase64,
content, pubKey,
isTenpayPubKey);
}
}
}
catch (Exception ex)
{
throw new TenpayApiRequestException("RequestAsync 签名验证失败:" + ex.Message, ex);
}
}
}
}
else
{
result = createDefaultInstance?.Invoke() ?? GetInstance<T>(true);
resultCode.Additional = content;
}
//T result = resultCode.Success ? (await responseMessage.Content.ReadAsStringAsync()).GetObject<T>() : new T();
result.ResultCode = resultCode;
return result;
}
catch (OperationCanceledException)
{
throw;
}View on GitHub (pinned to be573f6f94)