最稳路径是用 wechatpay-go 官方 SDK + Gin;需严格传入 mchID、certSerialNo、privateKey、apiV3Key 四参数;回调须调 ParseNotifyRequest 验签解密;JSAPI 下单必须用真实授权获取的 openid;所有地址须 HTTPS 且域名白名单备案。

直接用 wechatpay-go 官方 SDK + Gin 是目前最稳的路径,别自己手写签名、验签、加解密逻辑——容易漏掉平台证书轮换、时间戳校验、敏感字段 AES-GCM 解密等关键点。
初始化 wechatpay-go client 必须传对四个参数
官方 SDK 的 core.NewClient 不接受字符串拼接式配置,必须严格按顺序提供:mchID、certSerialNo(平台证书序列号,不是商户证书)、privateKey(商户 API 私钥,即 apiclient_key.pem 内容)、apiV3Key(APIv3 密钥,32位字符串)。漏一个或类型错(比如把 certSerialNo 当成证书内容传),client.Do 会直接 panic 或返回 401。
- 证书序列号要从下载的
wechatpay_cert.pem文件头里提取,格式类似1F8B0000000000000000,不是文件名也不是 base64 编码 -
privateKey必须是 PEM 格式原始字节,不能带-----BEGIN PRIVATE KEY-----头尾——SDK 内部不解析 PEM,只认纯 ASN.1 DER 数据;建议用utils.LoadPrivateKey加载 -
apiV3Key是你在商户平台「API 安全」里手动设置的,不是证书密码,也不是 v2 的 key
回调接口必须做三件事:验签、解密、幂等处理
微信支付 v3 回调是 POST JSON,但 body 是 AES-GCM 加密的密文,直接 c.ShouldBindJSON 会得到乱码或解析失败。必须先用 client.ParseNotifyRequest(不是 ParseNotifyEvent)解包,它内部完成:验签(检查 Wechatpay-Signature header)、解密(用 apiV3Key)、反序列化。
公众号运营:文章发布至草稿、样式封面、评论与用户管理、数据统计等。用户要求将 Markdown 发送到公众号草稿、查看阅读量统计或类似后台操作时,使用本技能。
- 如果没调这个方法就直接读 body,你会收到类似
{"code":"PARAM_ERROR","message":"json parse error"}的错误,实际是密文没解 - 解密后得到的
*core.NotifyEvent结构体里,Event.EventType是"TRANSACTION.SUCCESS"这类字符串,不是数字码 - 回调可能重发,
Event.Id是唯一事件 ID,务必存库去重;只靠OutTradeNo不够,同一笔订单可能触发多个事件(如退款成功、分账完成)
JSAPI 下单时 openid 不能硬编码或前端传
前端 JSAPI 支付必须传用户在当前公众号/小程序下的 openid,但它不能由前端构造或 localStorage 读取——微信禁止前端自行获取 openid(除非已授权登录),也不能后端缓存长期复用(openid 会过期或用户取消关注)。
- 正确链路是:用户在公众号打开页面 → 后端用
code换取openid(调https://api.weixin.qq.com/sns/jscode2session)→ 存 session 或短期 Redis 缓存(TTL ≤ 2h)→ 下单时从服务端上下文取 - 如果走 H5 支付(非 JSAPI),要用
redirect_url带用户跳转微信 auth 授权页,再回调拿 code,不能省 - 测试时用固定
openid可以跑通流程,但上线必须走真实授权流,否则支付会失败并返回{"code":"INVALID_REQUEST","message":"invalid openid"}
Gin 路由和中间件容易忽略的 HTTPS 和域名限制
微信支付所有回调地址(notify_url)、JSAPI 的 return_url、Native 支付二维码跳转页,都强制要求 HTTPS 且域名必须在商户平台「产品中心 → 开发配置」里白名单注册过。Gin 本地开发时若用 HTTP 或 localhost,回调根本不会触发。
- 调试阶段可用 ngrok 或 localtunnel 映射本地 8080 端口到公网 HTTPS 地址,然后填到商户平台
- 不要在 Gin 中间件里用
c.Request.URL.Scheme == "https"判断——反向代理(如 Nginx)后,实际是 HTTP,Scheme 被代理覆盖;应检查X-Forwarded-Protoheader - 回调接口路由(如
/pay/notify)不能加任何 Gin 中间件(如 JWT 验证、CORS),微信服务器不带 token 也不发 preflight,加了就 401 或 405
最常卡住的地方不是签名算法本身,而是证书序列号抄错、APIv3 密钥复制时多了空格、回调地址没备案、openid 拿错上下文——这些细节不报具体错误码,只返回模糊的 400/401,得逐项比对商户平台后台配置和代码传参是否完全一致。


















