JeffreySu/WeiXinMPSDK · error · TenpayApiRequestException
必须小于等于 !
Error message
{nameof(data.coupon_use_rule.fixed_normal_coupon.coupon_amount)} 必须小于等于 {nameof(data.coupon_use_rule.fixed_normal_coupon.transaction_minimum)}! What it means
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.
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
Example fix
// before (invalid): coupon 100 fen > minimum 10 fixed_normal_coupon.coupon_amount = 100; fixed_normal_coupon.transaction_minimum = 10; // after fixed_normal_coupon.coupon_amount = 100; fixed_normal_coupon.transaction_minimum = 1000; // must be >= coupon_amount, in fen
Defensive patterns
Strategy: validation
Validate before calling
var c = data.coupon_use_rule.fixed_normal_coupon;
if (c.coupon_amount > c.transaction_minimum)
throw new InvalidOperationException("coupon_amount must be <= transaction_minimum"); Type guard
bool CouponValueValid(FixedNormalCoupon c) => c.coupon_amount <= c.transaction_minimum;
Try / catch
try { await api.CreateStockAsync(data); }
catch (TenpayApiRequestException ex) when (ex.Message.Contains("transaction_minimum"))
{ logger.LogError(ex, "Coupon amount exceeds transaction minimum"); throw; } Prevention
- Confirm both values are in fen before comparison
- Validate coupon configuration from business config at load time
- Add schema-level validation on coupon settings
When it happens
Trigger: Calling CreateStockAsync where data.coupon_use_rule.fixed_normal_coupon.coupon_amount > data.coupon_use_rule.fixed_normal_coupon.transaction_minimum.
Common situations: 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.
Understand the failure class
Background: "Must be a positive integer", "Invalid value", "Unsupported": the invalid-argument-value error family, when a library rejects the value you pass — this error's family across 35 libraries.
Related errors
AI-assisted analysis of JeffreySu/WeiXinMPSDK@be573f6f94 (2026-09-12).
Data as JSON: /api/errors/71fbf1294723e5ad.
Report an issue: GitHub.
Appendix: source
Thrown at src/Senparc.Weixin.TenPay/Senparc.Weixin.TenPayV3/Apis/Marketing/MarketingApis.Favor.cs:83
/// <param name="data">微信支付需要POST的Data数据</param>
/// <param name="timeOut">超时时间,单位为ms </param>
/// <returns></returns>
public async Task<CreateStockReturnJson> CreateStockAsync(CreateStockRequsetData data, int timeOut = Config.TIME_OUT)
{
const string STOCK_TYPE = "NORMAL";
if (data.stock_type == STOCK_TYPE && data.coupon_use_rule.fixed_normal_coupon == null)
{
throw new TenpayApiRequestException($"当 {nameof(data.stock_type)} 为 {STOCK_TYPE} 时,{nameof(data.coupon_use_rule.fixed_normal_coupon)} 必填!");
}
if (data.stock_use_rule.max_amount != data.stock_use_rule.max_coupons * data.coupon_use_rule.fixed_normal_coupon.coupon_amount)
{
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)}!");
}
if (data.coupon_use_rule.fixed_normal_coupon.coupon_amount > data.coupon_use_rule.fixed_normal_coupon.transaction_minimum)
{
throw new TenpayApiRequestException($"{nameof(data.coupon_use_rule.fixed_normal_coupon.coupon_amount)} 必须小于等于 {nameof(data.coupon_use_rule.fixed_normal_coupon.transaction_minimum)}!");
}
var url = BasePayApis.GetPayApiUrl(Senparc.Weixin.Config.TenPayV3Host + "/{0}v3/marketing/favor/coupon-stocks");
TenPayApiRequest tenPayApiRequest = new(_tenpayV3Setting);
return await tenPayApiRequest.RequestAsync<CreateStockReturnJson>(url, data, timeOut);
}
/// <summary>
/// 激活代金券批次接口
/// <para>制券成功后,通过调用此接口激活批次,如果是预充值代金券,激活时会从商户账户余额中锁定本批次的营销资金</para>
/// <para>更多详细请参考 https://pay.weixin.qq.com/wiki/doc/apiv3/apis/chapter9_1_3.shtml </para>
/// </summary>
/// <param name="stock_id">批次号 微信为每个代金券批次分配的唯一id</param>
/// <param name="data">微信支付需要POST的Data数据</param>
/// <param name="timeOut">超时时间,单位为ms </param>
/// <returns></returns>
public async Task<StartStockReturnJson> StartStockAsync(string stock_id, StartStockRequsetData data, int timeOut = Config.TIME_OUT)
{View on GitHub (pinned to be573f6f94)