JeffreySu/WeiXinMPSDK · critical · InvalidOperationException
品牌 API 响应的微信支付公钥 ID 与配置不匹配。
Error message
品牌 API 响应的微信支付公钥 ID 与配置不匹配。
What it means
When brand API credentials are configured, the multipart response's Wechatpay-Serial header is compared with _brandApiCredentials.WechatpayPublicKeyId using an ordinal comparison; on mismatch the library throws InvalidOperationException because the response could not be verified with the configured public key. This guards against MITM or misconfigured platform credentials.
Solutions
- Update WechatpayPublicKeyId in TenPayBrandApiCredentials to the current serial returned in the response's Wechatpay-Serial header.
- Confirm you are using brand API credentials only for brand API endpoints (non-brand endpoints use a different verification path).
- Re-download the current WeChat Pay platform public key and reconfigure both key and key ID.
- Log the response's serial value and compare it with your configured ID to spot the mismatch.
Example fix
// before var creds = new TenPayBrandApiCredentials(mchId, serial: "PUB_KEY_ID_OLD", publicKeyPem, privateKey); // after — use the serial from the latest Wechatpay-Serial header var creds = new TenPayBrandApiCredentials(mchId, serial: "PUB_KEY_ID_0114xxxxxxxx", publicKeyPem, privateKey);
Defensive patterns
Strategy: try-catch
Validate before calling
// Compare expected serial with what the platform advertises before sending
var expectedSerial = brandCredentials.WechatpayPublicKeyId;
if (string.IsNullOrWhiteSpace(expectedSerial)) throw new InvalidOperationException("Brand public key ID not configured."); Try / catch
try { /* multipart request */ }
catch (InvalidOperationException ex) when (ex.Message.Contains("公钥 ID"))
{
logger.LogError(ex, "Brand key ID mismatch: configured={Expected}", brandCredentials.WechatpayPublicKeyId);
throw; // rotate/refresh credentials before retrying
} Prevention
- Track WeChat Pay key-rotation announcements and update WechatpayPublicKeyId promptly.
- Use ordinal-exact serial values copied from the Wechatpay-Serial response header.
- Keep brand credentials only on handlers used for brand API endpoints.
- Alert on VerifySignSuccess=false / key mismatch in production.
When it happens
Trigger: RequestMultipart* call against a brand API endpoint where the response's Wechatpay-Serial differs from the configured WechatpayPublicKeyId (rotated key not updated in config, wrong public key ID configured, or environment mismatch).
Common situations: WeChat Pay rotated its platform public key and the app still holds the old ID; copying credentials from sandbox to production; typos or whitespace in the configured key ID.
Understand the failure class
Background: Checksum mismatch errors: "checksum verification failed", "digest mismatch", "expected vs actual checksum" — what they mean and how to fix them — this error's family across 41 libraries.
Related errors
AI-assisted analysis of JeffreySu/WeiXinMPSDK@be573f6f94 (2026-09-12).
Data as JSON: /api/errors/649cbb5703cce1a8.
Report an issue: GitHub.
Appendix: source
Thrown at src/Senparc.Weixin.TenPay/Senparc.Weixin.TenPayV3/HttpHandlers/TenPayApiRequest.cs:492
{
result = new T { VerifySignSuccess = true };
}
else
{
result = content.GetObject<T>();
if (checkSign)
{
var timestamp = responseMessage.Headers.GetValues("Wechatpay-Timestamp").First();
var nonce = responseMessage.Headers.GetValues("Wechatpay-Nonce").First();
var signature = responseMessage.Headers.GetValues("Wechatpay-Signature").First();
var serial = responseMessage.Headers.GetValues("Wechatpay-Serial").First();
if (_brandApiCredentials != null)
{
if (!string.Equals(serial,
_brandApiCredentials.WechatpayPublicKeyId,
StringComparison.Ordinal))
{
throw new InvalidOperationException(
"品牌 API 响应的微信支付公钥 ID 与配置不匹配。");
}
result.VerifySignSuccess =
TenPaySignHelper.VerifyTenpaySign(
CertType.RSA, timestamp, nonce,
signature, content,
_brandApiCredentials.WechatpayPublicKey,
true);
}
else
{
var publicKey = await TenPayV3InfoCollection
.GetAPIv3PublicKeyAsync(_tenpayV3Setting,
serial, cancellationToken)
.ConfigureAwait(false);
if (_tenpayV3Setting.EncryptionType == CertType.SM)View on GitHub (pinned to be573f6f94)