应定义paymentstrategy接口并拆分为pay、notify、queryorder三个方法,各渠道用专属配置结构体初始化,notify需预读body并分渠道验签,策略通过工厂函数按名创建并预加载证书密钥。

支付接口统一抽象用什么结构体
Go 里没法靠继承做策略,得靠接口 + 具体实现。核心是定义一个 PaymentStrategy 接口,所有渠道都实现它,而不是各自写一堆不相干的函数。
常见错误是把签名、验签、回调处理全塞进一个方法里,结果微信要传 notify_url,支付宝却要 return_url,硬塞导致参数混乱、调用方总要 if-else 判断类型。
推荐拆成三个方法:Pay()(发起支付)、Notify()(接收异步通知)、QueryOrder()(查单)。每个渠道按需实现,没用到的返回 errors.New("not implemented")。
示例:
立即学习“go语言免费学习笔记(深入)”;
type PaymentStrategy interface {
Pay(req *PayRequest) (*PayResponse, error)
Notify(r *http.Request) (map[string]string, error)
QueryOrder(orderID string) (*OrderResult, error)
}
支付宝和微信初始化参数怎么隔离
两个渠道配置项长得像但不能混用:支付宝要 app_id、private_key、public_key;微信要 appid、mch_id、api_v3_key、cert_path。直接塞进同一个 struct 容易传错字段或漏填。
做法是为每种渠道单独建初始化函数,返回实现了 PaymentStrategy 的实例,并在内部封装好自己的配置:
-
NewAlipayStrategy(<code>config*AlipayConfig) —— 只认AlipayConfig -
NewWechatStrategy(<code>config*WechatConfig) —— 只认WechatConfig
这样调用方不会误把微信的 mch_id 当成支付宝的 app_id 传进去,编译期就能拦住。
damishop介绍 大米外贸商城系统 简称damishop 完全开源版,只需做一种语言一键开启全球133中语言自动翻译功能,价格实现自动汇率转换,集成微信支付宝 paypal以及国外主流支付方式,自带文章博客系统,首创支持可视化编辑。 软件架构 基于MVC+语言包模式,增加控制台,API导入产品方便对接其他系统(带json示例数据)。 使用要求
Notify 回调怎么避免重复处理和验签失败
微信回调是 JSON body + 微信证书验签,支付宝是 form 表单 + RSA 签名,两者解析方式、验签逻辑完全不同。统一用 http.Request 当入参是对的,但具体实现里必须分开关处理。
容易踩的坑:
- 没提前读取
r.Body就多次调用r.FormValue()—— 支付宝下会拿不到值(body 已被读空) - 微信验签前没校验
TLS客户端证书,或漏了wechatpay-timestamp头 - 支付宝验签时用了错误的公钥(比如用了应用公钥而不是支付宝公钥)
建议在 Notify() 实现开头就做三件事:读 body → 解析原始数据 → 验签。微信走 json.Unmarshal + wechatpay-go 验签,支付宝走 r.PostForm + alipay-go 的 VerifySign()。
策略切换时要不要用 map[string]PaymentStrategy 缓存
要,但别在全局变量里硬写死 map[string]PaymentStrategy{"alipay": ..., "wechat": ...}。问题在于:微信可能有多个商户号(不同业务线),支付宝也可能配多套 app_id,硬编码 map 会导致扩展性差、测试难 mock。
更稳妥的做法是用工厂函数 + 依赖注入:
- 定义
func NewStrategy(name string, config interface{}) (PaymentStrategy, error) - 内部用 switch 匹配
name,再根据config类型做断言(config.(AlipayConfig)或config.(WechatConfig)) - 业务层按需传入配置,不关心 map 存在哪
这样加新渠道只要扩 switch,老代码不用改,单元测试也容易构造不同 config 实例。
最常被忽略的是:微信证书加载、支付宝密钥解析这些 IO 操作,千万别放在 Notify() 这种高频路径里 —— 必须在初始化策略时就完成并缓存到 struct 字段中。










