{"record":{"id":"71fbf1294723e5ad","repo":"JeffreySu/WeiXinMPSDK","slug":"nameof-data-coupon-use-rule-fixed-normal-coupon-coupon","errorCode":null,"errorMessage":"{nameof(data.coupon_use_rule.fixed_normal_coupon.coupon_amount)} 必须小于等于 {nameof(data.coupon_use_rule.fixed_normal_coupon.transaction_minimum)}！","messagePattern":"(.+?) 必须小于等于 (.+?)！","errorType":"validation","errorClass":"TenpayApiRequestException","httpStatus":null,"severity":"error","filePath":"src/Senparc.Weixin.TenPay/Senparc.Weixin.TenPayV3/Apis/Marketing/MarketingApis.Favor.cs","lineNumber":83,"sourceCode":"        /// <param name=\"data\">微信支付需要POST的Data数据</param>\n        /// <param name=\"timeOut\">超时时间，单位为ms </param>\n        /// <returns></returns>\n        public async Task<CreateStockReturnJson> CreateStockAsync(CreateStockRequsetData data, int timeOut = Config.TIME_OUT)\n        {\n            const string STOCK_TYPE = \"NORMAL\";\n            if (data.stock_type == STOCK_TYPE && data.coupon_use_rule.fixed_normal_coupon == null)\n            {\n                throw new TenpayApiRequestException($\"当 {nameof(data.stock_type)} 为 {STOCK_TYPE} 时，{nameof(data.coupon_use_rule.fixed_normal_coupon)} 必填！\");\n            }\n\n            if (data.stock_use_rule.max_amount != data.stock_use_rule.max_coupons * data.coupon_use_rule.fixed_normal_coupon.coupon_amount)\n            {\n                throw new TenpayApiRequestException($\"{nameof(data.stock_use_rule.max_amount)} 必须等于 {nameof(data.stock_use_rule.max_coupons)} 乘以 {nameof(data.coupon_use_rule.fixed_normal_coupon.coupon_amount)}！\");\n            }\n\n            if (data.coupon_use_rule.fixed_normal_coupon.coupon_amount > data.coupon_use_rule.fixed_normal_coupon.transaction_minimum)\n            {\n                throw new TenpayApiRequestException($\"{nameof(data.coupon_use_rule.fixed_normal_coupon.coupon_amount)} 必须小于等于 {nameof(data.coupon_use_rule.fixed_normal_coupon.transaction_minimum)}！\");\n            }\n\n            var url = BasePayApis.GetPayApiUrl(Senparc.Weixin.Config.TenPayV3Host + \"/{0}v3/marketing/favor/coupon-stocks\");\n            TenPayApiRequest tenPayApiRequest = new(_tenpayV3Setting);\n            return await tenPayApiRequest.RequestAsync<CreateStockReturnJson>(url, data, timeOut);\n        }\n\n        /// <summary>\n        /// 激活代金券批次接口\n        /// <para>制券成功后，通过调用此接口激活批次，如果是预充值代金券，激活时会从商户账户余额中锁定本批次的营销资金</para>\n        /// <para>更多详细请参考 https://pay.weixin.qq.com/wiki/doc/apiv3/apis/chapter9_1_3.shtml </para>\n        /// </summary>\n        /// <param name=\"stock_id\">批次号 微信为每个代金券批次分配的唯一id</param>\n        /// <param name=\"data\">微信支付需要POST的Data数据</param>\n        /// <param name=\"timeOut\">超时时间，单位为ms </param>\n        /// <returns></returns>\n        public async Task<StartStockReturnJson> StartStockAsync(string stock_id, StartStockRequsetData data, int timeOut = Config.TIME_OUT)\n        {","sourceCodeStart":65,"sourceCodeEnd":101,"githubUrl":"https://github.com/JeffreySu/WeiXinMPSDK/blob/be573f6f94bdbf718dd5f6cdecb137fbc7ff651e/src/Senparc.Weixin.TenPay/Senparc.Weixin.TenPayV3/Apis/Marketing/MarketingApis.Favor.cs#L65-L101","documentation":"CreateStockAsync (MarketingApis.Favor.cs:83) checks that the coupon face value (coupon_amount) never exceeds the minimum spend required to use the coupon (transaction_minimum). A coupon worth more than its threshold makes no sense and WeChat Pay rejects it, so the library throws TenpayApiRequestException before sending the request.","triggerScenarios":"Calling CreateStockAsync where data.coupon_use_rule.fixed_normal_coupon.coupon_amount > data.coupon_use_rule.fixed_normal_coupon.transaction_minimum.","commonSituations":"Mixing units (coupon_amount in fen but transaction_minimum typed in yuan, e.g. amount=100 (1元) vs minimum=10); simply configuring a 100元 coupon with a 50元 threshold during testing; copying a template where minimum was later lowered.","solutions":["Set transaction_minimum >= coupon_amount (both in fen)","Recheck units so both values are in fen before comparing","Adjust the coupon_amount down or the transaction_minimum up to a valid combination"],"exampleFix":"// before (invalid): coupon 100 fen > minimum 10\nfixed_normal_coupon.coupon_amount = 100;\nfixed_normal_coupon.transaction_minimum = 10;\n\n// after\nfixed_normal_coupon.coupon_amount = 100;\nfixed_normal_coupon.transaction_minimum = 1000; // must be >= coupon_amount, in fen","handlingStrategy":"validation","validationCode":"var c = data.coupon_use_rule.fixed_normal_coupon;\nif (c.coupon_amount > c.transaction_minimum)\n    throw new InvalidOperationException(\"coupon_amount must be <= transaction_minimum\");","typeGuard":"bool CouponValueValid(FixedNormalCoupon c) => c.coupon_amount <= c.transaction_minimum;","tryCatchPattern":"try { await api.CreateStockAsync(data); }\ncatch (TenpayApiRequestException ex) when (ex.Message.Contains(\"transaction_minimum\"))\n{ logger.LogError(ex, \"Coupon amount exceeds transaction minimum\"); throw; }","preventionTips":["Confirm both values are in fen before comparison","Validate coupon configuration from business config at load time","Add schema-level validation on coupon settings"],"tags":["tenpay","marketing","validation","coupon"],"backgroundTag":"invalid-argument-value","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"}