微信支付V3退款接口必须使用商户证书(含私钥和CA根证书),禁用API密钥;需配置双向HTTPS、备案notify_url域名;请求体金额单位为分、out_refund_no全局唯一;签名须按规范生成并用商户私钥RSA-SHA256签名;回调需验签解密且返回SUCCESS。

退款接口必须用商户证书,不能只靠 API 密钥
微信支付 V3 退款接口强制要求双向 HTTPS 认证,access_token 或 APIv3 key 都无法替代商户证书。Fiber 默认的 HTTP 客户端(如 fasthttp)不支持客户端证书,直接调用会返回 401 Unauthorized 或 403 Forbidden,错误信息里常含 "invalid certificate" 或 "missing client certificate"。
实操建议:
- 从微信商户平台下载
apiclient_cert.pem(含私钥)、apiclient_key.pem和apiclient_ca.pem,合并为 PKCS#12 格式更稳妥:openssl pkcs12 -export -in apiclient_cert.pem -inkey apiclient_key.pem -out cert.p12 -name "wxpay" -passout pass:123456
- Fiber 中需换用原生
net/http客户端,并加载证书:cert, _ := tls.LoadX509KeyPair("apiclient_cert.pem", "apiclient_key.pem")<br>tr := &http.Transport{<br> TLSClientConfig: &tls.Config{Certificates: []tls.Certificate{cert}},<br>} - 别漏掉 CA 根证书校验——微信用的是自签名 CA,需显式加入:
caCert, _ := ioutil.ReadFile("apiclient_ca.pem")<br>caPool := x509.NewCertPool()<br>caPool.AppendCertsFromPEM(caCert)<br>tr.TLSClientConfig.RootCAs = caPool
refund 请求体必须带 notify_url 且域名已备案
微信要求退款异步通知地址(notify_url)必须是 HTTPS、已通过微信商户平台备案的域名,且不能是 localhost 或 IP 地址。填错会导致请求被拒,返回 400 Bad Request,错误响应中 code 字段为 "PARAM_ERROR",message 提示 "notify_url domain not in whitelist"。
实操建议:
- 开发阶段可用
https://your-domain.com/api/wxpay/refund-notify,但必须提前在微信商户平台「开发配置 → APIv3 回调地址」中添加该完整 URL -
notify_url域名需与公众号/小程序绑定的主体一致,不能混用不同商户号的域名 - 退款请求体中的
out_refund_no必须全局唯一,重复提交会返回"REFUND_CLOSE"或"REFUND_SUCCESS",不会二次处理 - 金额单位统一为分,
amount和refund_amount都是整数,且refund_amount <= amount
签名头 Authorization 必须按微信规则生成,不能手拼
微信 V3 接口签名不是简单 HMAC-SHA256,而是包含时间戳、随机串、HTTP 方法、路径、请求体哈希的复合字符串,再用商户私钥 RSA-SHA256 签名。Fiber 本身不提供签名工具,手写极易出错,常见问题包括:时间戳未用秒级、路径没去掉 query 参数、body 哈希用了原始 JSON 而非规范格式(无空格、字段排序)。
解析微信公众号文章,提取标题、作者、正文、图片等信息。用户发送链接(mp.weixin.qq.com)时触发,自动提取内容并可保存至飞书表格。
实操建议:
- 直接使用官方推荐的 Go SDK:
github.com/wechatpay-apiv3/wechatpay-go,它内置了core.Client和自动签名逻辑 - 若自行实现,关键点:
// body 哈希必须用规范 JSON(json.MarshalIndent 也不行)<br>hash := sha256.Sum256([]byte(strings.ReplaceAll(string(body), " ", "")))<br>// 签名原文格式:<br>// METHOD\nPATH\nTIMESTAMP\nNONCE_STR\nBODY_HASH\n<br>signStr := fmt.Sprintf("POST\n/v3/pay/transactions/id/%s/refund\n%d\n%s\n%s", transactionId, time.Now().Unix(), nonceStr, hash.Hex()) - 务必用商户私钥(
apiclient_key.pem内容)做 RSA-SHA256 签名,不是 APIv3 key
Fiber 路由中处理退款回调要验证签名和证书链
微信退款回调(notify_url)不是简单 POST,而是带 Wechatpay-Serial、Wechatpay-Timestamp、Wechatpay-Nonce 和 Wechatpay-Signature 四个头部,且响应体必须返回 {"code":"SUCCESS","message":"OK"},否则微信会持续重发。
实操建议:
- 回调路由必须用
fiber.Post("/api/wxpay/refund-notify", handler),且 handler 中先校验Content-Type: application/json - 用
wechatpay-go的verifier.Verify方法验签,不要自己解析 header + 手算——微信证书会轮换,SDK 自动管理证书缓存和更新 - 验签通过后才解析 JSON body,检查
resource.algorithm是否为"AEAD_AES_256_GCM",再用resource.nonce+resource.ciphertext+resource.associated_data解密退款结果 - 解密失败时仍要返回 200 + SUCCESS,否则微信判定失败并重推;但业务上应记录日志,避免重复处理
证书轮换和解密逻辑是高频出错点,微信每三个月可能更新平台证书,硬编码或手动更新证书文件容易导致某天突然回调全部失败。


















