在接入微信公众号JSAPI支付时,很多团队在联调阶段会遇到一个隐蔽但高频的问题:前端调用WeixinJSBridge.invoke时提示缺少参数或支付签名错误。排查到最后往往发现,并不是参数值算错,而是参数名的大小写不符合微信的规范。微信支付JSAPI调起所要求的字段,从协议层面全部定义为小写形式,例如appid、timestamp、noncestr、package、signType对应的标准名实际是signtype以外的全小写。理解并严格遵守这一规范,是打通支付链路的基础。

微信JSAPI支付调起参数的标准字段名
微信JSAPI支付在前端调起时,依赖一组固定的输入参数。这些参数由商户后台调用统一下单接口后生成,并经过签名返回给公众号网页。按照微信支付文档的明确要求,传递到JS层的参数对象中,所有键名都必须使用小写。常见的字段包括appid、timeStamp在文档示例里常写作timeStamp便于JS读取,但真实传输协议里是timestamp;nonceStr对应noncestr;package保持原样但值固定为prepay_id=xxx;signType对应signtype;paySign对应paysign。任何大写字母的出现,都会被微信客户端视为未知字段而忽略。
这种全小写约束来源于早期微信支付API的设计习惯。微信服务端在验证签名时,会将接收到的参数字符串拼接为key=value形式,且键名统一按小写处理。如果前端提交的JSON里混用了appId和timeStamp,服务端拼接出的签名原文与商户后台算出的不一致,就会返回签名错误。因此,标准规范的本质是:参数名全小写,参数值区分大小写,签名原文字符串也全小写键名。
下面是一段符合规范的后台返回给前端的参数示例,注意所有键均为小写:
{
"appid": "wx1234567890abcdef",
"timestamp": "1715580000",
"noncestr": "abcde12345",
"package": "prepay_id=wx1234567890",
"signtype": "MD5",
"paysign": "3A8F2C9B1D4E5F60718293A4B5C6D7E8"
}
参数名大小写错误引发的典型故障与排查
实际开发中,最常见的错误是后台工程师直接把统一下单接口的响应字段透传。统一下单返回的是appid、nonce_str等带下划线风格,而前端同事又自行用JS对象{appId: ..., timeStamp: ...}去封装,结果到了WeixinJSBridge.invoke里变成了大写开头。微信浏览器内的JSAPI桥接层并不会做大小写兼容,它只认全小写键名。此时页面会弹窗报错或静默失败,控制台可见“invalid signature”或“缺少参数”提示。
另一个容易踩的坑是签名函数自身。有些商户使用开源SDK,SDK内部将参数名做了驼峰转换方便面向对象使用,但在输出给前端前没有转回小写。排查时建议先在PC浏览器用抓包工具看实际下发的JSON,确认键名全小写;再单独用签名算法验证paysign是否正确。如下是一段Node.js侧生成正确小写参数的代码:
const params = {
appid: config.appId,
timestamp: String(Date.now()),
noncestr: randomStr(16),
package: 'prepay_id=' + prepayId,
signtype: 'MD5'
};
// 签名时拼接串也使用小写键
const stringA = Object.keys(params).sort().map(k => k + '=' + params[k]).join('&');
const signStr = stringA + '&key=' + config.key;
params.paysign = md5(signStr).toUpperCase();
// 此时params所有键均为小写,可直接返回前端
通过上面这种方式,后台保证了输出即规范,前端只需原样传入WeixinJSBridge.invoke('getBrandWCPayRequest', params, cb)即可,不需要任何字段映射。这样能将大小写问题消灭在服务端,降低前端负担,也方便后期审计。
前端调起代码的标准写法与注意事项
当前端拿到全小写参数后,标准的调起代码如下。注意这里没有对键名做任何改写,直接传入从后台接收的对象。如果后台返回的是驼峰命名,前端务必先转成小写,或者要求后台改正,而不是在调起前用delete和重赋值的方式修补,那样容易漏掉字段。
function callPay(payParams) {
if (typeof WeixinJSBridge === 'undefined') {
document.addEventListener('WeixinJSBridgeReady', function() {
WeixinJSBridge.invoke('getBrandWCPayRequest', payParams, onBridgeReady);
}, false);
} else {
WeixinJSBridge.invoke('getBrandWCPayRequest', payParams, onBridgeReady);
}
}
function onBridgeReady(res) {
if (res.err_msg === 'get_brand_wcpay_request:ok') {
alert('支付成功');
} else {
alert('支付失败: ' + res.err_msg);
}
}
在公众号环境里,还必须确保调用callPay时页面已完成微信JS-SDK的config注入,且公众号后台配置了支付授权目录。参数名小写只是基础规范,若授权目录不对,同样会调起失败。因此建议将参数规范检查写入联调清单:第一,后台返回JSON键全小写;第二,package值格式为prepay_id=前缀;第三,paysign由后台算好下发,前端不接触密钥。
总结来说,微信公众号支付JSAPI调起参数名全小写是一条硬性标准,不是可选项。开发团队应在接口约定文档里明确写出字段表,并配合代码校验脚本,在持续集成阶段扫描输出参数,防止误提交驼峰版本。只有把规范落到自动化检查中,才能长期避免因大小写导致的支付事故。