Go语言实现简易支付系统是构建对接微信/支付宝等第三方网关的HTTP服务,承担流程协调与安全校验职责;需用平台证书初始化TLS、按规范生成Authorization头、解密并验签回调通知;推荐使用wechatpay-go等成熟SDK而非手写加解密;须保障证书自动更新与通知幂等性。
Go 语言本身不内置支付能力,所谓“用 Golang 实现简易支付系统”,实际是用 Go 编写一个对外提供支付相关 HTTP 接口的服务端,对接第三方支付网关(如微信支付、支付宝),并完成必要的安全校验与业务逻辑。它不是从零造支付协议,而是做「支付流程的协调者」和「安全守门人」。
如何对接微信支付 v3 API(含签名验证)
微信支付 v3 接口强制要求 HTTPS + 平台证书 + 请求签名 + 响应验签,Go 官方 crypto/tls 和 net/http 可支撑,但签名逻辑需手动实现或借助社区库(如 wechatpay-go)。
- 必须用平台证书(
apiclient_cert.pem+apiclient_key.pem)初始化 TLS 客户端,否则调用/v3/pay/transactions/native等接口会返回401 Unauthorized - 请求头
Authorization需按规则拼接:类型(WECHATPAY2-SHA256-RSA2048)+ 有效时间戳 + 随机数 + 商户号 + 签名串,其中签名原文为:HTTP_METHOD\nREQUEST_PATH\nTIMESTAMP\nNONCE_STR\nBODY\n - 收到微信回调(
POST /notify)时,必须用平台证书中的公钥解密通知体,并用wechatpay-go的DecryptNotification或自行实现 AES-GCM 解密,再对解密后 JSON 中的resource.algorithm和resource.ciphertext进行验签 - 别直接用
http.Post发起请求——要复用http.Client并设置Timeout,否则超时未处理会导致重复下单
如何用 Gin 实现带 JWT 的支付回调鉴权
外部支付平台(如支付宝)回调你的 /alipay/notify 接口时,不携带 Cookie 或 Session,也无法走常规登录态;JWT 是轻量且可控的替代方案,但仅用于「确认该回调确实来自你自己的前端下单请求」,不能替代支付平台自身的签名验证。
- 用户在前端调用你的
POST /api/v1/order创建预支付单时,后端生成一个有效期 15 分钟的 JWT,载荷含order_id、amount、user_id,用服务私钥签名(HS256或RS256),返回给前端 - 前端在唤起支付宝 SDK 前,把该 JWT 放入请求参数
passback_params(支付宝)或ext_info(微信),确保回调时能原样带回 - 回调入口(如
POST /alipay/notify)先解析passback_params,再用对应密钥解析 JWT,校验exp和order_id是否匹配本次通知的out_trade_no;不通过则直接返回success(支付宝要求)但不更新订单状态 - JWT 不解决重放——要配合 Redis 记录已处理的
notify_id或trade_no,SETNX + EXPIRE 300 秒,防止同一通知被多次消费
为什么不要自己实现 RSA/AES 加解密逻辑
微信/支付宝文档里写的加解密步骤看似清晰,但实际涉及 PKCS#1 v1.5 填充、OAEP、AES-GCM nonce 处理、base64 URL-safe 编码等细节,Golang 标准库虽支持,但一两处字节错位就会导致「解密失败」或「验签失败」,而错误信息往往只报 crypto/aes: invalid key size 或空响应。