JeffreySu/WeiXinMPSDK · error · WeixinException

TenPayV3InfoCollection尚未注册Mch:

Error message

TenPayV3InfoCollection尚未注册Mch:{0}

What it means

TenPayV3InfoCollection is a thread-safe registry of TenPayV3 merchant configs keyed by merchant (Mch) name. This WeixinException is thrown by the indexer getter when the requested Mch key has never been registered, so the library refuses to return an unknown/default merchant config.

Solutions

  1. Register the merchant before use: TenPayV3InfoCollection.Register(new TenPayV3Info(...)) with the exact key you later look up
  2. Log/print TenPayV3InfoCollection.GetCollection().Keys (or TryGetValue) to verify the key spelling and registration at startup
  3. Move registration earlier in the app lifecycle (e.g. application start / DI singleton init) so it precedes all payment calls
  4. If a default should always exist, register a default TenPayV3Info and look it up with a constant key

Example fix

// before
var info = TenPayV3InfoCollection["mch_1000"];
// after
if (TenPayV3InfoCollection.TryGet("mch_1000", out var info)) { /* use info */ }
else { TenPayV3InfoCollection.Register(new TenPayV3Info(appId, mchId, key, appSecret, certPath)); }
Defensive patterns

Strategy: validation

Validate before calling

if (TenPayV3InfoCollection.TryGet(mchName, out var info)) { /* proceed */ } else { throw new InvalidOperationException($"Mch '{mchName}' not registered"); }

Type guard

static bool IsMchRegistered(string key) => TenPayV3InfoCollection.GetCollection() is { } c && c.ContainsKey(key);

Try / catch

try { var info = TenPayV3InfoCollection[mchName]; ... } catch (WeixinException ex) { log.Error("Mch config missing: {0}", mchName); throw new ConfigMissingException(ex); }

Prevention

When it happens

Trigger: Calling the indexer (e.g. TenPayV3InfoCollection[mchName]) or any API that resolves config by Mch key before Register()/RegisterCollection() was called with that key, or with a misspelled key.

Common situations: Config load order bugs (using the collection in a startup path that runs before registration), typos or case mismatch in the Mch name, multiple TenPayV3 merchants configured but the wrong key passed, or app restarts wiping the in-memory collection.

Related errors


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

Appendix: source

Thrown at src/Senparc.Weixin.TenPay/Senparc.Weixin.TenPayV3/TenPayV3InfoCollection.cs:136

            var tenpayV3InfoKey = TenPayHelper.GetRegisterKey(senparcWeixinSettingForTenpayV3.TenPayV3_MchId, senparcWeixinSettingForTenpayV3.TenPayV3_SubMchId);
            var pubKey = await Data[tenpayV3InfoKey].GetPublicKeyAsync(tenpaySerialNumber, senparcWeixinSettingForTenpayV3, cancellationToken).ConfigureAwait(false);
            return pubKey;
        }

        /// <summary>
        /// 索引 TenPayV3Info
        /// </summary>
        /// <param name="key"></param>
        /// <returns></returns>
        public new TenPayV3Info this[string key]
        {
            get
            {
                lock (_syncRoot)
                {
                    if (!base.TryGetValue(key, out var value))
                    {
                        throw new WeixinException(string.Format("TenPayV3InfoCollection尚未注册Mch:{0}", key));
                    }

                    return value;
                }
            }
            set
            {
                lock (_syncRoot)
                {
                    base[key] = value;
                }
            }
        }

        /// <summary>
        /// 获取当前注册数量。
        /// </summary>
        public new int Count

View on GitHub (pinned to be573f6f94)