微信支付 / 公众号回调本地调试:用内网穿透在 IDE 里断点回调
微信的服务器回调(公众号消息、微信支付的 notify_url)只会往公网可访问的地址推送。
本地起的服务监听在 127.0.0.1,微信够不着,于是常见做法是改一行代码部署到测试服务器再看日志——一轮十几分钟。
把本地端口经内网穿透映射到公网后,微信的回调直接打到你 IDE 里的断点上,改完代码刷新就生效,联调效率完全不同。
原理:回调为什么到不了 localhost
你的开发机在家用路由器后面,没有公网 IP,微信服务器主动发起的 HTTP 请求无法路由进来。 内网穿透让开发机主动向外建立一条隧道,公网侧的入口端口与本地端口一一对应: 微信访问公网地址,流量经隧道回到你本机的服务。全程无需公网 IP,也无需改路由器端口映射。
第一步:创建映射拿到公网地址
- 下载安装 NA-Vlet 客户端(免费下载), 邮箱验证码注册登录,系统自动分配 License。
-
本地先跑起来一个 HTTP 服务,确认本机可访问,例如 Spring Boot 的
http://127.0.0.1:8080或 Node 的http://127.0.0.1:3000。 -
在「隧道映射」页新建映射:选「网站」模板,协议 HTTP,内网目标填
127.0.0.1:8080(按你的实际端口),保存。 - 映射生效后,列表显示公网访问地址。先用浏览器或 curl 自测一条路径,确认从公网进来的请求能命中本地服务, 再去动微信后台的配置。
第二步:配置公众号服务器(启用开发者模式)
登录微信公众平台 → 设置与开发 → 基本配置 → 服务器配置,填写 URL、Token、EncodingAESKey:
-
URL 的端口要求:公众号后台只接受 80(HTTP)或 443(HTTPS) 端口的 URL。
穿透工具分配的随机高位端口(如
http://xxx.example.com:39187)直接填会被拒绝。 解法是在穿透侧绑定自有域名(NA-Vlet 支持域名绑定与证书,让公网入口落在标准端口上), 或在联调期临时借用一台有备案域名的服务器做转发。没有域名时,可先用下面第三节的支付沙箱/接口调试方式过渡。 -
Token 校验:保存配置时微信向你填的 URL 发 GET 请求,携带
signature / timestamp / nonce / echostr; 服务端用 Token 按同样算法排序拼接 SHA1 后与 signature 比对,一致则原样返回echostr。这个接口必须先写好,否则「保存并提交」永远失败。 - 验证通过后,用户发给公众号的消息就会以 XML/JSON POST 到这个 URL——此刻它们正落进你本地的断点里。
# Token 校验的最小示意(以你所用框架为准)
GET /wechat/callback?signature=...×tamp=...&nonce=...&echostr=...
# 校验算法: sha1( sort([token, timestamp, nonce]).join('') ) === signature
# 通过: HTTP 200, body = echostr 原样返回
第三步:调试微信支付 notify_url
微信支付(v3)下单时传的 notify_url 是微信服务器主动 POST 回调的地址,要求:
- 必须是公网可达的 HTTPS 地址(v3 强制 TLS),不能带本地 IP 与自签证书;
- 必须在下单请求里显式传入,所以联调时把它指向穿透映射的公网 HTTPS 地址;
- 微信会重试:返回非 2xx 或超时(约 5 秒)会按衰减策略重推,本地断点停太久会看到重复通知——这是正常现象;
- 回调体先验签(平台证书/公钥验
Wechatpay-Signature头),再解密 AES-256-GCM 拿到明文报文。
// 下单时把回调指向穿透地址(以 v3 JSAPI 为例)
{
"appid": "wx...",
"mchid": "19...",
"description": "测试商品",
"notify_url": "https://你的穿透域名/api/pay/notify",
"amount": { "total": 1, "currency": "CNY" }
}
在 /api/pay/notify 的入口打上断点,真实支付一分钱(或用微信支付的「接口在线调试」模拟回调),
请求参数、重试行为、验签失败原因全部一目了然。
联调期安全清单
- 只开需要的端口:调试结束就停用映射,别让本机服务长期暴露在公网;
- 加 IP 白名单:NA-Vlet 安全组规则可以把回调入口限制到微信服务器网段,减少被扫描打点;
- 验签别偷懒:本地调试也走完整验签逻辑,避免带着「裸奔版」回调代码上了生产;
- 别在回调里做重活:微信 5 秒超时,收到后先落库返回成功,业务异步处理。
公众号/支付后台的配置项(URL、Token、密钥)改动会直接影响线上服务,联调尽量用测试号(公众平台测试账号) 或单独的商户号参数,避免与生产环境互相踩踏。