支付网关核心原则是隔离变化点,定义统一支付能力契约,通过策略模式+工厂+配置驱动实现渠道热插拔,统一路由通知、幂等校验与异步处理,结合轻量状态机管理订单生命周期,并配套事务补偿、熔断开关与监控降级。

支付网关的核心设计原则
可扩展的支付网关不是堆砌功能,而是把“变化点”隔离出来。比如微信支付、支付宝、银联、PayPal 的接入方式千差万别,但它们都满足同一组抽象行为:下单、查询、退款、异步通知验签、同步跳转。所以第一件事是定义清晰的 支付能力契约 —— 用接口(如 PaymentService)声明统一方法,每个渠道实现自己的子类(WechatPaymentService、AlipayPaymentService),不互相侵入。
支持动态路由与渠道热插拔
避免在代码里写死 if (channel == "wechat") {...}。推荐用策略模式 + 工厂 + 配置驱动:
- 渠道信息(ID、名称、密钥、网关地址)存在数据库或配置中心(如 Nacos、Apollo)
- 启动时扫描所有
PaymentService实现类,按@Channel("alipay")注解注册到内存路由表 - 支付请求进来后,根据参数中的
channelCode查路由表,拿到对应 Bean 执行,无需重启即可新增渠道
统一异步通知与幂等性保障
各渠道回调格式、签名方式、重试机制不同,但业务只关心“这笔订单是否真的成功”。网关应做三件事:
- 统一路由入口(如
/api/pay/notify/{channel}),解析原始请求并转换为内部标准对象 - 对每个通知做唯一键校验(如
outTradeNo + notifyId或tradeNo + timestamp),插入数据库前先查是否存在,防止重复处理 - 通知处理逻辑放入异步队列(如 RocketMQ),失败自动重试,并配监控告警
灵活的状态机与事务补偿
支付不是原子操作,涉及商户系统、渠道系统、银行系统多端协同。建议用轻量状态机(如 Spring State Machine 或自研)管理订单生命周期:
立即学习“Java免费学习笔记(深入)”;
- 初始状态:
WAIT_PAY→ 调用渠道下单成功 →PAYING→ 收到成功通知 →PAY_SUCCESS - 异常分支(如超时未支付、渠道返回失败、通知丢失)需主动查单(
queryOrder)补全状态 - 关键动作(如扣库存、发券)放在状态变更后的事件监听器中执行,并配套本地事务表 + 定时补偿任务
基本上就这些。架构不复杂,但容易忽略配置治理、日志追踪和降级开关——上线前记得给每个渠道加 熔断开关 和 模拟回调入口。










