JeffreySu/WeiXinMPSDK · critical · Senparc.Weixin.Exceptions.WeixinException

没有设置证书加密类型(EncryptionType)

Error message

没有设置证书加密类型(EncryptionType)

What it means

CreatePayPackage (MedicalInsuranceApis.cs:180) builds the JS/mini-program pay package and must sign it, which requires knowing the certificate encryption type (RSA or SM). If _tenpayV3Setting.EncryptionType is null — i.e. the TenPayV3 settings never specified EncryptionType — a WeixinException is thrown before the package can be produced.

Solutions

  1. Set EncryptionType on the TenPayV3Setting (e.g. Senparc.Weixin.TenPay.TenPayV3Type.RSA) at configuration/startup time
  2. Check your config source (appsettings/env) is actually bound to the EncryptionType field
  3. Rebuild the TenPayV3Setting used by MedicalInsuranceApis so it includes EncryptionType before creating pay packages

Example fix

// before
var setting = new TenPayV3Setting { TenPayV3_AppId = appId, ... }; // EncryptionType unset

// after
var setting = new TenPayV3Setting {
    ...,
    EncryptionType = TenPayV3Type.RSA
};
Defensive patterns

Strategy: validation

Validate before calling

if (!_tenpayV3Setting.EncryptionType.HasValue)
    throw new InvalidOperationException("TenPayV3 EncryptionType must be configured (RSA for new merchants) before creating pay packages");

Type guard

bool ReadyForPayPackage(TenPayV3Setting s) => s != null && s.EncryptionType.HasValue;

Try / catch

try { var pkg = api.CreateJsApiPayPackage(prepayId); }
catch (WeixinException ex) when (ex.Message.Contains("EncryptionType"))
{ logger.LogCritical(ex, "TenPayV3 EncryptionType missing in configuration"); throw; }

Prevention

When it happens

Trigger: Calling CreatePayPackage (directly or via CreateMiniProgramPayPackage / CreateJsApiPayPackage) with a TenPayV3Setting whose EncryptionType property has no value.

Common situations: Newly registered WeChat Pay merchants on H5/mini-program platforms must use RSA (older app/product profiles allowed SM), and the setting was left unset; migrating config files where the EncryptionType key was dropped; constructing TenPayV3Setting manually in code without setting the property.

Understand the failure class

Background: "is required", "must be set", "missing required field": configuration validation errors across open-source libraries — this error's family across 36 libraries.

Related errors


AI-assisted analysis of JeffreySu/WeiXinMPSDK@be573f6f94 (2026-09-12). Data as JSON: /api/errors/f0dcfdb2deac5a33. Report an issue: GitHub.

Appendix: source

Thrown at src/Senparc.Weixin.TenPay/Senparc.Weixin.TenPayV3/Apis/MedicalInsurance/MedicalInsuranceApis.cs:180

                effectiveAppId = !string.IsNullOrWhiteSpace(_tenpayV3Setting.TenPayV3_SubAppId)
                    ? _tenpayV3Setting.TenPayV3_SubAppId
                    : _tenpayV3Setting.TenPayV3_AppId;
            }

            var result = new MedicalInsurancePayPackage
            {
                mixTradeNo = mixTradeNo,
                appid = includeAppId ? effectiveAppId : null
            };

            if (string.IsNullOrWhiteSpace(prepayId))
            {
                return result;
            }

            if (!_tenpayV3Setting.EncryptionType.HasValue)
            {
                throw new Senparc.Weixin.Exceptions.WeixinException(
                    "没有设置证书加密类型(EncryptionType)");
            }

            result.timeStamp = DateTimeOffset.UtcNow.ToUnixTimeSeconds().ToString();
            result.nonceStr = Guid.NewGuid().ToString("N");
            result.package = $"prepay_id={prepayId}";
            result.signType = "RSA";
            result.paySign = TenPaySignHelper.CreatePaySign(result.timeStamp, result.nonceStr,
                result.package, effectiveAppId, _tenpayV3Setting.TenPayV3_PrivateKey,
                _tenpayV3Setting.EncryptionType.Value);
            return result;
        }

        private static string BuildSubMchIdQuery(string subMchId)
        {
            return string.IsNullOrWhiteSpace(subMchId)
                ? string.Empty
                : $"?sub_mchid={Escape(subMchId)}";

View on GitHub (pinned to be573f6f94)