JeffreySu/WeiXinMPSDK · error · TenpayApiRequestException
tenPayV3Info 参数不能为空!
Error message
tenPayV3Info 参数不能为空!
What it means
This obsolete overload of GetJsApiUiPackage (deprecated since v2.4.0 in favor of the overload taking JsApiAppType) requires a populated TenPayV3Info configuration object containing appid, mch_id, key etc. to compute the JsApi pay-sign package. It throws when the tenPayV3Info argument is null, since no signature can be produced without the merchant's V3 credentials. The fix is for callers to pass a valid TenPayV3Info instance (e.g. TenPayV3InfoCollection.Data).
Solutions
- Ensure TenPayV3Info is registered/obtained before the call: TenPayV3InfoCollection.Register(...) and fetch from TenPayV3InfoCollection.Data[registerKey]
- Add a null check or assertion at the call site
- Pass the TenPayV3Info instance from DI or a config-backed factory instead of a local variable
Example fix
// before TenPayV3Info info = null; var package = TenPaySignHelper.GetJsApiUiPackage(prepayId, info); // after var info = TenPayV3InfoCollection.Data[TenPayHelper.GetRegisterKey(mchId, subMchId)]; var package = TenPaySignHelper.GetJsApiUiPackage(prepayId, info);
Defensive patterns
Strategy: validation
Validate before calling
if (tenPayV3Info == null)
throw new InvalidOperationException("TenPayV3Info 未初始化:请先 TenPayV3InfoCollection.Register"); Type guard
bool HasTenpayInfo(string mchId, string subMchId) => TenPayV3InfoCollection.Data.ContainsKey(TenPayHelper.GetRegisterKey(mchId, subMchId));
Try / catch
try { var pkg = TenPaySignHelper.GetJsApiUiPackage(prepayId, info); }
catch (TenpayApiRequestException ex) { log.Error("tenPayV3Info 为空", ex); throw new AppConfigException("商户信息未注册", ex); } Prevention
- Register all merchants at app startup with TenPayV3InfoCollection.Register
- Fetch TenPayV3Info from TenPayV3InfoCollection.Data by register key, never pass ad-hoc nulls
- Enable nullable reference types so null passing is caught at compile time
When it happens
Trigger: Calling GetJsApiUiPackage(prepayId, null) — usually because TenPayV3InfoCollection.Data[key] lookup returned nothing or a variable holding TenPayV3Info was never initialized.
Common situations: Merchant info not registered via TenPayV3InfoCollection.Register; using the wrong mchId register key so the lookup path produces null; refactoring code where the info object was removed.
Related errors
AI-assisted analysis of JeffreySu/WeiXinMPSDK@be573f6f94 (2026-09-12).
Data as JSON: /api/errors/d8eb2744e9f0a1fc.
Report an issue: GitHub.
Appendix: source
Thrown at src/Senparc.Weixin.TenPay/Senparc.Weixin.TenPayV3/Helpers/TenPaySignHelper.cs:315
/// <param name="prepayId">预支付交易会话标识。</param>
/// <param name="tenPayV3Info">微信支付 V3 配置信息。</param>
/// <returns></returns>
[Obsolete("v2.4.0 起该方法已过时,请使用 GetJsApiUiPackage(string prepayId, TenPayV3Info tenPayV3Info, JsApiAppType? appType) 方法。")]
public static JsApiUiPackage GetJsApiUiPackage(string prepayId, TenPayV3Info tenPayV3Info)
=> GetJsApiUiPackage(prepayId, tenPayV3Info, JsApiAppType.WxOpen);
/// <summary>
/// 获取给 JsApi UI 使用的打包签名信息
/// </summary>
/// <param name="prepayId">预支付交易会话标识。</param>
/// <param name="tenPayV3Info">微信支付 V3 配置信息。</param>
/// <param name="appType">应用类型(小程序或原生 App)。</param>
/// <returns></returns>
public static JsApiUiPackage GetJsApiUiPackage(string prepayId, TenPayV3Info tenPayV3Info, JsApiAppType appType = JsApiAppType.WxOpen)
{
if (tenPayV3Info == null)
{
throw new Senparc.Weixin.TenPayV3.TenpayApiRequestException("tenPayV3Info 参数不能为空!");
}
var timeStamp = TenPayV3Util.GetTimestamp();
var nonceStr = TenPayV3Util.GetNoncestr();
var prepayIdPackage = GetPrepayIdPackage(prepayId, appType);
var sign = TenPaySignHelper.CreatePaySign(timeStamp, nonceStr, prepayIdPackage, tenPayV3Info);
JsApiUiPackage jsApiUiPackage = new(tenPayV3Info.AppId, timeStamp, nonceStr, prepayIdPackage, sign);
return jsApiUiPackage;
}
/// <summary>
/// 根据微信小程序或原生 APP 定义不同格式的 prepayId 签名字符串
/// </summary>
/// <param name="prepayId"></param>
/// <param name="appType"></param>
/// <returns></returns>
private static string GetPrepayIdPackage(string prepayId, JsApiAppType appType)View on GitHub (pinned to be573f6f94)