{"record":{"id":"bae022e7ac4c1424","repo":"JeffreySu/WeiXinMPSDK","slug":"fundappapis-authorization","errorCode":null,"errorMessage":"未获取到用于加密收款用户姓名的微信支付公钥或平台证书。","messagePattern":"未获取到用于加密收款用户姓名的微信支付公钥或平台证书。","errorType":"exception","errorClass":"TenpayApiRequestException","httpStatus":null,"severity":"error","filePath":"src/Senparc.Weixin.TenPay/Senparc.Weixin.TenPayV3/Apis/FundApp/FundAppApis.Authorization.cs","lineNumber":150,"sourceCode":"            object target, bool containsSensitiveData)\n        {\n            if (!containsSensitiveData)\n            {\n                return new TenPayApiRequest(_tenpayV3Setting);\n            }\n\n            var publicKey = GetConfiguredPaymentPublicKey();\n            if (string.IsNullOrWhiteSpace(publicKey.Key))\n            {\n                var publicKeys = await new BasePayApis(_tenpayV3Setting)\n                    .GetPublicKeysAsync().ConfigureAwait(false);\n                publicKey = SelectPaymentPublicKey(publicKeys);\n            }\n\n            if (string.IsNullOrWhiteSpace(publicKey.Key) ||\n                string.IsNullOrWhiteSpace(publicKey.Value))\n            {\n                throw new TenpayApiRequestException(\n                    \"未获取到用于加密收款用户姓名的微信支付公钥或平台证书。\");\n            }\n\n            SecurityHelper.FieldEncrypt(target, publicKey.Value,\n                _tenpayV3Setting.EncryptionType.Value,\n                _tenpayV3Setting.TenPayV3_TenPayPubKeyEnable);\n            return new TenPayApiRequest(_tenpayV3Setting, httpClient =>\n                httpClient.DefaultRequestHeaders.Add(\"Wechatpay-Serial\", publicKey.Key));\n        }\n\n        private KeyValuePair<string, string> GetConfiguredPaymentPublicKey()\n        {\n            if (!_tenpayV3Setting.TenPayV3_TenPayPubKeyEnable)\n            {\n                return default;\n            }\n\n            return new KeyValuePair<string, string>(","sourceCodeStart":132,"sourceCodeEnd":168,"githubUrl":"https://github.com/JeffreySu/WeiXinMPSDK/blob/be573f6f94bdbf718dd5f6cdecb137fbc7ff651e/src/Senparc.Weixin.TenPay/Senparc.Weixin.TenPayV3/Apis/FundApp/FundAppApis.Authorization.cs#L132-L168","documentation":"This TenpayApiRequestException is thrown by CreateAuthorizationRequestAsync (FundAppApis.Authorization.cs:150) when the library cannot find a WeChat Pay public key or platform certificate to encrypt the payee user's real name before sending the authorization request to the fund/transfer API. WeChat Pay requires sensitive fields like names to be encrypted with a downloaded public key or platform certificate; if neither was loaded from the configured certificates/public keys collection, encryption is impossible and the library aborts instead of sending plaintext.","triggerScenarios":"Calling CreateAuthorizationRequestAsync while _tenpayV3Setting has no usable entry in the publicKeys collection: the loaded platform certificates/public key JSON is empty, SelectPaymentPublicKey returned an entry whose Key or Value is null/whitespace, or certificate download/refresh failed silently before this call.","commonSituations":"TenPayV3 settings missing TenPayV3_CertificatePublicKeys or public key path configured to a nonexistent file; WeChat Pay V3 public key mode (TenPayV3_TenPayPubKeyEnable) enabled but the WeChat Pay public key not downloaded; certificate expired or replaced by WeChat so the cached blob no longer parses; running with an empty platform certificate list in environments without network access to fetch certificates.","solutions":["Configure the TenPayV3 setting with a valid WeChat Pay public key (or platform certificates) so publicKeys contains at least one non-empty Key/Value entry","If using public-key mode, enable TenPayV3_TenPayPubKeyEnable and store the downloaded WeChat Pay public key (pub_key.pem) in the setting","Verify the certificate/public key file path and that the file content parses to a non-empty Key and Value at startup","Re-download or refresh platform certificates if they have expired; log the publicKeys collection before the call to confirm it is populated"],"exampleFix":"// before: no public key configured, call throws\nawait fundAppApis.CreateAuthorizationRequestAsync(request);\n\n// after: ensure encryption material exists first\nif (string.IsNullOrWhiteSpace(_tenpayV3Setting.TenPayV3_CertificatePublicKeys))\n{\n    _tenpayV3Setting.TenPayV3_CertificatePublicKeys = File.ReadAllText(\"pub_key.pem\");\n}\nawait fundAppApis.CreateAuthorizationRequestAsync(request);","handlingStrategy":"validation","validationCode":"var pubKeys = _tenpayV3Setting?.GetPublicKeys?.Invoke();\nif (pubKeys == null || pubKeys.Count == 0 || pubKeys.Values.Any(k => string.IsNullOrWhiteSpace(k.Key) || string.IsNullOrWhiteSpace(k.Value)))\n    throw new InvalidOperationException(\"WeChat Pay public key / platform certificate not configured before calling FundApp APIs.\");","typeGuard":"bool HasEncryptionMaterial(TenPayV3Setting s) =>\n    s != null && s.EncryptionType.HasValue &&\n    s.GetPublicKeys != null && s.GetPublicKeys().Any(k => !string.IsNullOrWhiteSpace(k.Key) && !string.IsNullOrWhiteSpace(k.Value));","tryCatchPattern":"try { await fundAppApis.CreateAuthorizationRequestAsync(request); }\ncatch (TenpayApiRequestException ex) when (ex.Message.Contains(\"公钥或平台证书\"))\n{ logger.LogError(ex, \"Missing WeChat Pay encryption key material; check TenPayV3 settings.\"); throw; }","preventionTips":["Load and verify public key / certificate material at application startup, not at request time","Enable TenPayV3_TenPayPubKeyEnable only after downloading pub_key.pem from WeChat Pay merchant console","Log the number of loaded certificates/keys in health checks","Refresh certificates before expiry"],"tags":["tenpay","encryption","missing-public-key","config"],"backgroundTag":"missing-credentials","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"}