JeffreySu/WeiXinMPSDK · error · TenpayApiRequestException

接收方类型为 MERCHANT_ID 时,name 必填。

Error message

接收方类型为 MERCHANT_ID 时,name 必填。

What it means

When adding profit-sharing receivers to a chain brand, a receiver whose type is MERCHANT_ID must carry a name (merchant name) per WeChat's API contract. CreateOrderAsync iterates the receivers collection and throws TenpayApiRequestException when any MERCHANT_ID receiver has a null/empty/whitespace name.

Solutions

  1. Set the name field on every MERCHANT_ID receiver before calling.
  2. Filter out or fix receivers with missing names in your service layer.
  3. Use PERSONAL type instead of MERCHANT_ID when the receiver is an individual and name is truly unavailable.

Example fix

// before
new ChainBrandProfitsharingReceiverRequestData { type = "MERCHANT_ID", account = mchId, name = null }
// after
new ChainBrandProfitsharingReceiverRequestData { type = "MERCHANT_ID", account = mchId, name = "商户全称" }
Defensive patterns

Strategy: validation

Validate before calling

foreach (var r in receivers.Where(r => r?.type == "MERCHANT_ID"))
    if (string.IsNullOrWhiteSpace(r.name)) throw new ArgumentException($"Receiver {r.account} needs a name.");

Type guard

bool receiverValid(ChainBrandProfitsharingReceiverRequestData r) =>
    r?.type != "MERCHANT_ID" || !string.IsNullOrWhiteSpace(r.name);

Try / catch

try { await apis.CreateOrderAsync(brandId, orderData, receivers); }
catch (TenpayApiRequestException ex) when (ex.Message.Contains("MERCHANT_ID")) { logger.Warn(ex, "Receiver missing name"); throw new BusinessRuleException("Fill merchant name for all MERCHANT_ID receivers."); }

Prevention

When it happens

Trigger: Calling CreateOrderAsync with receivers containing an entry where type == "MERCHANT_ID" and name is null or empty; constructing receiver objects dynamically from DB rows missing the merchant name column.

Common situations: Syncing receivers from an external system where the name field is optional there but mandatory here; template code copying PERSONAL-type receivers (name optional) for MERCHANT_ID.

Understand the failure class

Background: "missing required argument" and "the following required arguments were not provided": what required-argument errors mean and how to fix them — this error's family across 20 libraries.

Related errors


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

Appendix: source

Thrown at src/Senparc.Weixin.TenPay/Senparc.Weixin.TenPayV3/Apis/ChainBrandProfitsharing/ChainBrandProfitsharingApis.cs:75

        /// <para>官方文档:https://pay.weixin.qq.com/doc/v3/partner/4012692975</para>
        /// </summary>
        /// <param name="data">品牌主、出资商户、订单和最多 50 个分账接收方。</param>
        /// <param name="timeOut">代理请求超时时间(毫秒)。</param>
        /// <returns>分账单和各接收方执行结果。</returns>
        public async Task<ChainBrandProfitsharingOrderResultJson>
            CreateOrderAsync(
                ChainBrandProfitsharingCreateOrderRequestData data,
                int timeOut = Config.TIME_OUT)
        {
            _ = data ?? throw new ArgumentNullException(nameof(data));
            var receivers = data.receivers ??
                Array.Empty<ChainBrandProfitsharingReceiverRequestData>();
            foreach (var receiver in receivers)
            {
                if (receiver?.type == "MERCHANT_ID" &&
                    string.IsNullOrWhiteSpace(receiver.name))
                {
                    throw new TenpayApiRequestException(
                        "接收方类型为 MERCHANT_ID 时,name 必填。");
                }
            }

            var request = await CreateSensitiveRequestAsync(receivers
                .Where(receiver => receiver != null &&
                    !string.IsNullOrWhiteSpace(receiver.name))
                .Cast<object>()).ConfigureAwait(false);
            const string path = "v3/brand/profitsharing/orders";
            return await request.RequestAsync<
                ChainBrandProfitsharingOrderResultJson>(GetUrl(path), data,
                timeOut).ConfigureAwait(false);
        }

        /// <summary>
        /// 查询连锁品牌分账结果。
        /// <para>官方文档:https://pay.weixin.qq.com/doc/v3/partner/4012467002</para>
        /// </summary>

View on GitHub (pinned to be573f6f94)