JeffreySu/WeiXinMPSDK · error · ArgumentNullException

sessionKey

Error message

sessionKey

What it means

XPayApi.GenerateSignature throws ArgumentNullException when sessionKey is null, empty, or whitespace. The sessionKey (from wx.login code2session) is the HMAC key used to sign request data for virtual payment APIs.

Solutions

  1. Re-run the code2session flow (jscode2session API) to obtain a fresh session_key before signing
  2. Cache the sessionKey per openid and refresh on null/empty
  3. Verify the login flow stores session_key and not just openid

Example fix

// before
var sign = XPayApi.GenerateSignature(sessionCache.Get(openid), data); // may be null
// after
var sessionKey = sessionCache.Get(openid) ?? await GetNewSessionKeyAsync(code);
var sign = XPayApi.GenerateSignature(sessionKey, data);
Defensive patterns

Strategy: validation

Validate before calling

if (string.IsNullOrWhiteSpace(sessionKey)) await RefreshSessionKeyAsync(openid, code);

Type guard

bool HasValidSessionKey(string sessionKey) => !string.IsNullOrWhiteSpace(sessionKey);

Try / catch

try { return XPayApi.GenerateSignature(sessionKey, data); }
catch (ArgumentNullException) { var fresh = await GetSessionKeyAsync(code); return XPayApi.GenerateSignature(fresh, data); }

Prevention

When it happens

Trigger: Calling GenerateSignature with a null/empty sessionKey — typically because code2session was never called, failed, or the cached session key expired and was evicted.

Common situations: Session key cache miss on a fresh server instance; user session expired and code2session was not re-run; storing the key in a session store that lost the entry.

Related errors


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

Appendix: source

Thrown at src/Senparc.Weixin.WxOpen/src/Senparc.Weixin.WxOpen/Senparc.Weixin.WxOpen/AdvancedAPIs/XPay/XPayApi.cs:1316

            {
                var hashBytes = hmac.ComputeHash(dataBytes);
                return BitConverter.ToString(hashBytes).Replace("-", "").ToLower();
            }
        }

        /// <summary>
        /// 生成signature
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="sessionKey"></param>
        /// <param name="data"></param>
        /// <returns></returns>
        /// <exception cref="System.ArgumentNullException"></exception>
        public static string GenerateSignature<T>(string sessionKey, T data)
        {
            if (string.IsNullOrWhiteSpace(sessionKey))
            {
                throw new ArgumentNullException("sessionKey");
            }
            if (data == null)
            {
                throw new ArgumentNullException("data");
            }

            var signData = JsonConvert.SerializeObject(data);
            var keyBytes = Encoding.UTF8.GetBytes(sessionKey);
            var dataBytes = Encoding.UTF8.GetBytes(signData);

            using (var hmac = new HMACSHA256(keyBytes))
            {
                var hashBytes = hmac.ComputeHash(dataBytes);
                return BitConverter.ToString(hashBytes).Replace("-", "").ToLower();
            }
        }
        /// <summary>
        /// 生成 iOS 会员订阅(wx.requestAppleSubscribeSign)所需的 pay_sig

View on GitHub (pinned to be573f6f94)