3. 支付渠道接入与网关设计
医疗支付平台面对的是高度碎片化的渠道生态:微信支付、支付宝、银联云闪付、医保移动支付,以及部分医院自有的 POS、聚合码、银行直连通道。每个渠道在接口协议、签名方式、报文格式、异步通知机制、退款规则、对账文件结构上都不一致。如果让业务系统直接对接每一个渠道,任何一次渠道升级、证书轮换或限额调整都会引发大范围改造。统一支付网关的核心价值,就是把“渠道差异”收敛到网关内部,向上暴露一套稳定的支付能力接口。
一、网关的分层结构与职责边界
统一支付网关通常分为四层:接入层、能力层、渠道路由层、渠道适配层。接入层负责鉴权、限流、幂等校验与参数规范化;能力层把业务语义(下单、支付、退款、查询、关单、对账)翻译成内部统一指令;渠道路由层根据支付方式、金额、医院、医保类型、渠道健康度选择具体通道;渠道适配层则封装各渠道 SDK 与协议细节,完成签名、加密、报文组装与响应解析。
关键设计原则是:业务系统只感知“支付方式 + 金额 + 订单号”,不感知“走哪个渠道的哪个接口”。渠道选择、重试、降级全部在网关内部完成。这样新增一个医保移动支付渠道时,只需在适配层增加一个实现类并注册路由规则,上层业务零改动。
二、渠道抽象:统一接口与差异封装
渠道适配层的关键是定义一套稳定的内部契约。以支付下单为例,内部统一请求对象包含:商户订单号、支付金额(分)、支付方式、用户标识(openid/医保电子凭证)、回调地址、超时时间、扩展参数。适配器负责把这些字段映射到各渠道的真实字段,并处理差异。
典型差异包括:微信支付 v3 使用 SHA256-RSA 签名与 AES-GCM 解密回调;支付宝使用 RSA2 签名,回调为 form 表单;银联全渠道使用证书签名与 XML/JSON 混合报文;医保移动支付则涉及医保局下发的动态令牌与医院端密钥协商。适配器需要把这些差异全部吸收,向上只返回统一结果:SUCCESS / FAIL / UNKNOWN / PROCESSING,并附带渠道流水号与原始响应。
下面是一个适配器接口的示例定义:
public interface IChannelAdapter {
// 渠道编码:WECHAT / ALIPAY / UNIONPAY / MI
String channelCode();
// 统一下单
ChannelPayResult pay(ChannelPayRequest request);
// 统一退款
ChannelRefundResult refund(ChannelRefundRequest request);
// 统一查询
ChannelQueryResult query(String outTradeNo, String channelTradeNo);
// 异步通知验签与解析
ChannelNotifyResult parseNotify(Map<String, String> headers, String body);
// 渠道健康检查
ChannelHealth health();
}
注意 UNKNOWN 状态的处理:当网关调用渠道超时或网络中断时,不能简单判定为失败,而应标记为未知,进入主动查询补偿流程。这是医疗支付场景中避免“用户已扣款但订单显示未支付”的关键。
三、渠道路由策略
路由不是简单的 if-else,而应设计为可配置的规则链。路由输入包括:支付方式、金额、医院、医保类型、渠道健康度、限额余量、降级开关。输出是目标渠道编码与适配器实例。
常见的路由规则优先级如下:
- 强制指定:医保移动支付必须走医保通道,不可降级到普通支付。
- 限额过滤:单笔金额超过微信单笔限额(示例:5万元)时,自动切换到银联或银行直连。
- 健康度过滤:渠道连续失败率超过阈值(示例:5分钟内失败率 > 30%)时,临时摘除该渠道。
- 成本与优先级:在多个可用渠道中,按费率、到账时间、医院协议优先级排序。
- 降级备选:主通道不可用时,按预设顺序切换到备选通道,并记录降级事件。
路由规则建议存储在配置中心,支持热更新。每次路由决策输出一条结构化日志,包含:订单号、命中规则、候选渠道列表、最终选择、决策耗时。这样在排障时可以快速回答“这笔订单为什么走了银联而不是微信”。
四、限额控制与降级策略
限额控制分为三个层次:渠道级限额、医院级限额、单用户级限额。渠道级限额来自各支付机构,例如微信单笔、单日限额;医院级限额是平台为控制风险设置的业务上限;单用户级限额用于防止异常高频支付。网关在路由前先做限额预检,超限则直接拒绝或切换通道。
降级策略需要区分“渠道降级”和“功能降级”。渠道降级是指主通道不可用时切换到备选通道;功能降级是指某些非核心能力(如营销立减、分期)在异常时暂时关闭,保证主支付链路可用。降级开关应支持手动与自动两种触发方式,并设置恢复条件,避免渠道恢复后仍长期处于降级状态。
五、幂等、重试与对账闭环
支付网关必须保证幂等:同一商户订单号重复请求下单,应返回首次结果而非重复创建。实现方式通常是以商户订单号 + 渠道编码作为唯一键,在数据库中做唯一约束,并在接入层做分布式锁或状态机校验。
重试策略要区分“可重试”与“不可重试”。网络超时、渠道系统繁忙可重试;参数错误、签名失败、余额不足不可重试。重试必须使用相同的商户订单号,避免重复扣款。对于 UNKNOWN 状态,应进入主动查询队列,按指数退避策略查询渠道最终状态。
对账是最后一道防线。网关每日拉取各渠道对账文件,与平台交易流水逐笔比对,输出差异明细:长款、短款、状态不一致、金额不一致。差异记录进入人工处理工单,并触发告警。只有对账闭环完成,才能确认当日资金与订单真正一致。
| 控制点 | 关键动作 | 判断依据 |
|---|---|---|
| 幂等校验 | 商户订单号唯一约束 + 状态机 | 重复请求返回首次结果 |
| 限额预检 | 渠道/医院/用户三级限额比对 | 超限则拒绝或切换通道 |
| 路由决策 | 规则链匹配 + 健康度过滤 | 输出渠道编码与备选通道 |
| 降级熔断 | 失败率阈值触发,半开试探恢复 | 试探成功率达标则恢复 |
| 对账闭环 | 渠道对账文件与平台流水逐笔比对 | 差异为零或差异已处理 |
综上,统一支付网关的设计本质是“收敛差异、稳定契约、可控降级”。把渠道差异封装在适配层,把路由与限额做成可配置规则,把异常与降级做成可观测、可恢复的状态机,再以对账闭环兜底,才能在医疗支付这种高可用、强合规的场景中稳定运行。