短信通道迁移与接入需求

本文定义消息网关一期短信网关能力。目标是接入 1 家短信通道,并将原 CRS 已接入的短信供应商能力迁移到消息网关统一封装。迁移完成后,BNS、FCS、CRS 等上游系统均通过消息网关发送短信,不再直接适配短信供应商。

1. 接入目标

  1. 消息网关统一承接短信发送入口。
  2. 原 CRS 短信通道迁移到消息网关,CRS 不再直接维护短信供应商协议细节。
  3. BNS 登录 OTP、交易通知、FCS 还款提醒等短信场景统一按 scene + templateCode + variables 调用。
  4. 一期接入 1 家短信通道,但按多短信供应商模型设计,后续可平滑增加备用短信供应商。
  5. 一期支持同类型短信路由框架:主短信通道、备用短信通道、通道启停、失败重试一次。

2. 一期范围

2.1 包含范围

能力一期要求
统一短信发送提供消息网关统一 sendMessage 入口
CRS 通道迁移复用或迁移 CRS 当前短信供应商账号、模板和发送能力
模板映射内部 templateCode 映射到供应商模板 ID 或模板内容
变量校验发送前校验必填变量
手机号规范化支持 +234 标准手机号并按供应商要求转换
发送记录记录消息单、短信发送明细、供应商请求和响应
回执记录支持供应商受理结果和投递回执入库
同类型路由预留主短信 / 备用短信配置;一期只有 1 家时备用为空
失败处理参数错误、模板错误、供应商失败、超时有标准失败码
监控指标发送量、受理成功率、投递成功率、失败码、回执延迟

2.2 不包含范围

  • 不在一期接入多家短信供应商做动态权重。
  • 不做短信营销活动、人群圈选和批量营销。
  • 不做跨类型自动降级,例如短信失败自动 WhatsApp。
  • 不在消息网关生成 OTP 或校验 OTP。
  • 不把供应商密钥写入文档、前端或普通后台。

3. CRS 迁移口径

项目迁移前迁移后
短信供应商协议CRS 直接适配消息网关短信适配器适配
发送入口BNS / FCS 可能调用 CRS 或历史短信服务BNS / FCS / CRS 统一调用消息网关
模板 IDCRS 或供应商侧维护消息网关统一维护内部模板和供应商模板映射
发送记录分散在 CRS / 业务系统消息网关统一保存消息单和发送明细
回执解析CRS 解析供应商回执消息网关接收并标准化回执
监控指标CRS 局部统计消息网关按 scene、provider、template 统计

迁移要求:

  • 迁移期间允许 CRS 作为上游系统调用消息网关,避免一次性改完所有业务系统。
  • 迁移完成后,CRS 不再保存短信供应商密钥,不再解析短信供应商私有回执。
  • 已审批模板和供应商模板 ID 需要迁移到消息网关模板配置。
  • 历史发送记录不要求迁移,只要求迁移后新发送记录统一落消息网关。

4. 短信场景

场景来源系统模板示例要求
login_otpBNS / 登录服务OTP 验证码低延迟,快速失败,可一次备用
loan_submit_successBNS借款提交成功普通优先级
loan_approvedBNS审批通过普通优先级
loan_rejectedBNS审批拒绝普通优先级
repayment_due_smsFCS到期还款提醒支持还款金额、到期日、还款链接
repayment_result_successFCS还款成功交易通知
repayment_result_failedFCS还款失败交易通知

5. 短信供应商配置

字段说明
provider_code短信供应商内部编码,例如 crs_legacy_sms 或研发确认后的编码
provider_name供应商展示名称
channel_type固定为 sms
api_endpoint供应商接口地址
auth_typetoken / sign / basic auth 等
credential_ref密钥在配置中心或密钥系统中的引用
enabled是否启用
timeout_seconds请求超时时间
callback_url供应商回执地址
environmenttest / production

安全要求:

  • 供应商密钥不写入 Markdown。
  • 后台只展示供应商编码、启停状态和非敏感配置。
  • 生产密钥只通过配置中心或密钥系统注入。

6. 模板配置

字段说明
template_code内部模板编码
scene业务场景
provider_code供应商编码
provider_template_id供应商模板 ID
required_variables必填变量
language模板语言
statusenabled / disabled

要求:

  • 上游只传 templateCode 和变量。
  • 供应商模板 ID 可变更,不要求上游改代码。
  • 模板变量缺失时,消息网关直接拒绝发送并返回 variable_missing

7. 同类型短信路由

一期只有 1 家短信通道时,也要按路由模型实现:

字段一期值
scene业务场景
primary_channelsms
primary_provider首家短信供应商
backup_channelsms 或空
backup_provider备用供应商,一期可为空
max_attemptsOTP 建议 1-2;普通通知可 1
cross_channel_enabledfalse

多家短信通道的路由采用“配置化场景路由 + 供应商优先级 / 权重 + 失败切换”的方式实现,不在一期引入复杂规则引擎或实时智能调度。

路由配置建议:

配置项说明
scene业务场景,例如 login_otprepayment_due_sms
country国家,默认 Nigeria;后续可按国家扩展
phone_prefix号段规则,可为空;用于后续按运营商或号段选择通道
provider_code短信供应商编码
priority优先级,数字越小优先级越高
weight权重,二期可用于同优先级供应商分流;一期可先固定为 100
enabled是否启用
timeout_seconds当前供应商超时时间
retryable_failure_codes允许切换备用通道的失败码
daily_quota可选,供应商日限额
cost_level可选,成本等级,用于后续优化

一期执行逻辑:

  1. scene + country + phone_prefix 查询可用短信路由。
  2. 过滤 enabled=false、供应商不可用、模板未映射的通道。
  3. priority 选择主短信供应商;一期只有 1 家时只命中主供应商。
  4. 如果主供应商请求超时、鉴权失败、明确返回可重试失败码,且存在同类型备用短信供应商,则切换备用供应商。
  5. OTP 场景最多尝试 1-2 次,且必须受验证码有效期约束;普通通知默认只尝试 1 次,是否备用发送由场景配置决定。
  6. 每次供应商调用都生成独立 attempt_id,备用发送通过 parent_attempt_id 关联主发送记录。
  7. 如果没有可用供应商或备用也失败,返回标准失败码,不静默丢弃。

三家短信通道配置示例:

scenecountryphone_prefixprovider_codepriorityweightenabled说明
login_otpNGsms_provider_a1100true主通道
login_otpNGsms_provider_b2100true第一备用
login_otpNGsms_provider_c3100true第二备用

当前一期框架支持配置三家短信通道,前提是三家供应商都已完成供应商配置、模板映射、鉴权配置和适配器接入。当前一期交付范围只要求接入 1 家短信通道,因此“三家同时可用”不是默认已具备能力;如果业务要求一期上线三家,需要把另外两家供应商接入、联调和验收纳入一期范围。

执行效果:

  • priority=1 为主通道。
  • 主通道失败且失败码允许备用时,尝试 priority=2
  • 是否继续尝试 priority=3max_attempts 和场景配置控制。
  • OTP 场景建议最多尝试 1-2 次,避免验证码过期后送达;普通通知可按业务容忍度配置最多 2-3 次。
  • 同优先级按 weight 比例分流属于二期能力,一期不支持 A / B / C 按比例动态分流。

二期增强逻辑:

  • 按供应商成功率、成本、号段、运营商、回执延迟、限额做动态权重。
  • 支持同优先级供应商按 weight 分流。
  • 支持供应商健康检查自动摘除和恢复。
  • 支持按场景配置不同路由策略,例如 OTP 优先低延迟,营销通知优先低成本。

规则:

  • 主短信通道禁用时,如果存在备用短信通道,则切换备用短信通道。
  • 如果没有备用短信通道,则返回明确失败,不静默丢弃。
  • 一期不允许短信失败后自动 WhatsApp。
  • OTP 场景不做长时间异步重试,避免验证码过期后送达。

8. 接口与回执

8.1 发送

上游仍调用消息网关统一接口:

POST /message-gateway/api/v1/messages/send

短信场景请求示例:

{
  "sourceSystem": "BNS",
  "bizId": "OTP202607150001",
  "scene": "login_otp",
  "receiverPhone": "+2348012345678",
  "preferredChannel": "sms",
  "templateCode": "LOGIN_OTP",
  "variables": {
    "otp_code": "1234",
    "expire_minutes": "5"
  },
  "priority": "high"
}

8.2 回执

供应商回执统一进入消息网关:

POST /message-gateway/api/v1/provider-callback/{providerCode}

要求:

  • 按供应商消息 ID 做幂等。
  • 投递成功映射为 delivered
  • 投递失败映射为 failed 并保存标准失败码。
  • 无法匹配的回执进入异常表。

9. 监控指标

指标说明
sms_send_total短信发送请求数
sms_accept_success_rate供应商受理成功率
sms_delivery_success_rate投递成功率
sms_failure_total失败数量,按失败码拆分
sms_callback_delay_seconds回执延迟
sms_provider_timeout_total供应商超时数量
sms_template_error_total模板错误数量

告警建议:

  • OTP 短信 5 分钟受理成功率低于阈值,P0。
  • 还款提醒短信 30 分钟投递成功率低于阈值,P1。
  • 供应商鉴权失败,P1。
  • 回执延迟持续升高,P2 / P1。

10. 联调用例

用例预期
BNS 发送登录 OTP消息网关调用短信通道并返回 messageId
FCS 发送还款提醒模板变量正确渲染,供应商受理成功
CRS 作为上游调用消息网关CRS 不直接调用供应商,消息网关记录发送明细
手机号为 +2348012345678适配为供应商要求格式
模板变量缺失返回 variable_missing
供应商鉴权失败返回 provider_auth_failed 并告警
供应商超时返回或异步标记 provider_timeout
投递成功回执重复推送幂等处理,不重复更新业务状态
主短信通道禁用且无备用返回明确失败

11. 验收标准

  • 原 CRS 短信通道能力已在消息网关侧完成配置或适配。
  • BNS、FCS、CRS 均可通过消息网关统一接口发送短信。
  • 登录 OTP、交易通知、还款提醒至少各完成一条测试发送。
  • 内部 templateCode 能映射到供应商模板 ID 或模板内容。
  • 模板变量缺失、手机号非法、供应商禁用、供应商鉴权失败均有标准错误码。
  • 短信发送记录、供应商流水、投递回执可按 messageId 查询。
  • 回执重复推送不会重复处理。
  • 短信监控指标能按 scene、provider、template 拆分。
  • 供应商密钥不暴露给上游系统、前端或普通后台用户。
  • 一期只启用短信同类型路由,不启用短信到 WhatsApp 的跨类型自动降级。