在接入微信公众号支付时,开发者常遇到这样一种情况:前端调用 WeixinJSBridge.invoke 或 wx.chooseWXPay 后,手机端微信浏览器没有任何支付键盘弹出,后台日志或前端报警则显示“商户号未配置支付授权目录”。这个问题并不是代码逻辑错误,而是微信支付侧对调用页面的域名路径做了白名单校验。只有当当前页面的 URL 路径前缀,完全落在商户平台配置的支付授权目录之下,微信才允许拉起 JSAPI 支付流程。

微信支付之所以设计支付授权目录,是为了约束 JSAPI 支付的发起来源,防止商户号被其他域名冒用调起扣款。授权目录在微信商户平台(pay.weixin.qq.com)的产品中心、开发配置中维护,每条目录必须以 http 或 https 开头的完整站点路径填写,但以斜杠结尾,不能带具体文件名和查询参数。例如业务页面是 https://pay.ipipp.com/order/pay.php,那么授权目录应填 https://pay.ipipp.com/order/。若只填了根域名 https://pay.ipipp.com/,则子目录下的页面依然会被拒绝。
很多失败案例来自对“目录匹配规则”的误解。微信的匹配是前缀匹配且区分大小写,它要求当前页面 URL 去除文件名后,必须和配置的某一个目录完全一致或是其子路径。如果页面在 https://pay.ipipp.com/order/v2/pay.php 而目录只配了 https://pay.ipipp.com/order/,这是放行的;但如果配成了 https://pay.ipipp.com/Order/,就会因大小写不一致而调起失败。此外,配置生效后有大约十分钟缓存,急于测试时容易误判为“配了也没用”。
如何排查商户号授权目录配置问题
遇到 JSAPI 调起失败,第一步应是确认报错信息来源。如果是统一下单接口返回错误码 INVALID_REQUEST 且附带“商户号未配置支付授权目录”,说明后端在调微信下单 API 时,微信已根据传参中的 spbill_create_ip 与公众号绑定关系定位到商户号,并比对了前端传来的 referer 或下单时写的 notify_url 域。更常见的是前端 chooseWXPay 直接报错,此时应打开微信开发者工具的 remote debug,查看 err_msg 具体内容。
第二步是拿着实际调起页面的完整 URL 去比对商户平台配置。注意移动端微信里若用了微信内分享的链接,可能带有 from=singlemessage 等参数,但这不影响目录匹配,因为匹配只看路径前缀。建议用一台安卓手机,在调起前用复制链接功能拿到真实地址,再人工核对。如下方示例,假设页面地址与配置差异:
<!-- 实际调起支付页面地址 --> https://pay.ipipp.com/mobile/order/confirm.html?order_id=123 <!-- 商户平台错误配置 --> https://pay.ipipp.com/mobile/order/confirm.html <!-- 带了文件名,错误 --> https://pay.ipipp.com/mobile/ <!-- 正确写法应为这样 -->
第三步是区分“JS接口安全域名”和“支付授权目录”。前者在公众号后台设置,控制该公众号能否调用 wx.config 里的 jsApiList;后者在商户号后台设置,控制能否调起支付。两者都配错会叠加故障,但报错提示不同。若 wx.config 就失败,那是安全域名问题;若 wx.config 成功、chooseWXPay 失败并提示授权目录,才是本文主题。排查时建议画一张对照表,逐一打钩。
正确的授权目录配置与代码示例
在商户平台添加授权目录时,应坚持“就近原则”:为不同业务线配置各自的上层目录,而非全站根目录,以降低泄露后被滥用的风险。例如商城业务配 https://pay.ipipp.com/shop/,充值业务配 https://pay.ipipp.com/recharge/。添加后微信侧通常十分钟内生效,如紧急发版可提工单加速。需要提醒的是,公众号关联的商户号若有多个,要确保下单时使用的 mch_id 和配置目录的商户号是同一个,否则也会报未配置。
前端调起代码应保持标准写法,先通过后端获取预支付信息,再调用接口。下方是一个简化的 JSAPI 调起片段,注意 timestamp 为字符串类型,paySign 由后台按规则生成,前端不应自己算:
// 假设后端返回了如下字段
var payData = {
appId: 'wx1234567890',
timeStamp: '1710000000',
nonceStr: 'abc123',
package: 'prepay_id=wx1234567890',
signType: 'MD5',
paySign: '9A7B8C6D5E4F3G2H'
};
function callWxPay() {
if (typeof WeixinJSBridge === 'undefined') {
document.addEventListener('WeixinJSBridgeReady', function() {
WeixinJSBridge.invoke('getBrandWCPayRequest', payData, onPayResult);
}, false);
} else {
WeixinJSBridge.invoke('getBrandWCPayRequest', payData, onPayResult);
}
}
function onPayResult(res) {
if (res.err_msg === 'get_brand_wcpay_request:ok') {
alert('支付成功');
} else {
alert('支付失败或取消:' + res.err_msg);
}
}
这段代码本身没有问题,但如果商户号没配好授权目录,invoke 会立刻返回 get_brand_wcpay_request:fail 且系统层提示商户号未配置。因此当测试环境用 ipipp.com 测试域名配过、生产用 pay.ipipp.com 却忘了加,就会本地好用线上废。建议在 CI 流程里加一个巡检脚本,上线前自动比对生产域名是否在商户平台目录列表中。
避免授权目录导致调起失败的架构与实践建议
从系统架构看,最稳的做法是将支付页收敛到极少数的固定路径下,不要随意增删层级。比如所有微信 JSAPI 支付都跳转到 https://pay.ipipp.com/wxpay/gateway.php 再由它带参数分发,这样商户平台只需配一条 https://pay.ipipp.com/wxpay/ 即可,避免业务扩展时漏配。若采用前端路由如 hash 模式,因 hash 不入目录匹配,也可降低出错率,但需注意部分老微信版本对 hash 回跳的处理。
另一个实践是建立配置清单。把公众号 appid、商户号 mch_id、支付授权目录、JS安全域名、回调地址写进公司内部知识库,每次发版核对。曾有团队因公众号迁移,旧商户号目录未带走,新号没配,导致凌晨支付全挂。若用多云部署,还要注意不同可用区对外域名一致,不能 A 区用 pay.ipipp.com、B 区用 pay2.ipipp.com 而只配了前者。
最后,监控上可采集前端 chooseWXPay 的失败 err_msg 上报,一旦连续出现包含“未配置支付授权目录”的报错,自动告警给支付负责人。这种主动发现比用户投诉更快。总体而言,商户号未配置支付授权目录是低技术含量但高发生率的故障,只要理解匹配规则、规范配置流程、做好上线核对,就能彻底规避 JSAPI 调起失败。