短信网关 — 系统需求

MVP 不实现独立短信网关。本文保留为系统需求与后续建设参考;MVP 阶段不建设统一短信网关,不承诺通用业务短信、营销短信闭环。
三方接入域总览见 00-总览;还款提醒见 01-还款提醒,MVP 阶段由 FCS 直接对接 crs,不依赖本文短信网关。

纯 API 系统,模板管理可在运营系统。负责消息模板管理和统一发送。


业务目的

各系统需要发消息时(验证码/催收/还款通知),统一走消息网关。模板一处管理,供应商切换对上游透明。


能力模型

上游系统              消息网关                    消息供应商
┌─────────┐         ┌──────────────┐          ┌──────────────┐
│ 客户系统  │ ──发验证码─▶ │  短信发送      │ ──选择──▶ │ Termii         │
│         │         │  WhatsApp发送  │          │ Twilio         │
│ 催收系统  │ ──逾期提醒─▶ │  App Push     │          │ Infobip       │
│         │         │  模板管理      │          │ WhatsApp API   │
│ 还款中心  │ ──失败通知─▶ │  供应商路由    │          └──────────────┘
│         │         │  限流控制      │
│ 运营系统  │ ──营销推送─▶ │  发送记录      │
└─────────┘         └──────────────┘

发送规则

规则说明
场景编码调用方传入场景编码(如 verification_code / overdue_reminder),网关自动匹配模板和供应商
模板选择场景编码 → 语言(默认英语,按客户偏好)→ 匹配模板
变量替换调用方传参 {code: "123456", name: "John"},网关替换模板中的占位符
供应商选择按场景配置首选供应商,失败时自动切换备选
发送优先级验证码 > 催收 > 还款通知 > 营销(营销触发受频控约束)
频控约束同一客户 5 分钟内最多 3 条,同一场景 24 小时内最多 5 条

接口清单

上游调用

接口方向说明
发送消息← 各系统传入场景编码 + 接收方 + 模板变量
批量发送← 运营系统传入客户列表 + 场景编码 + 变量列表
查询发送状态← 各系统按消息 ID 查询投递状态

回调

接口方向说明
投递报告→ 上游系统供应商异步回执后,通知调用方终态

模板管理

接口方向说明
创建模板← 运营系统定义场景编码 + 语言 + 模板内容 + 参数列表
更新模板← 运营系统版本管理,旧版本保留
查询模板← 各系统按场景编码查询模板列表

状态机

message_log

状态说明
pending收到请求,待发送
sent已发送至供应商,等待回执
delivered供应商确认投递成功
failed投递失败(供应商返回明确失败)
undelivered投递失败(供应商无法送达但未明确原因)
expired发送超时未获回执
blocked被频控拦截,未实际发送

核心字段

message_template

字段类型说明
template_idstring模板 ID
scene_codestring场景编码(verification_code / overdue_reminder / repayment_failure / marketing)
channelenumsms / whatsapp / push
languagestringen / ha / yo / ig(英语 / 豪萨语 / 约鲁巴语 / 伊博语)
contentstring模板正文,变量用 {var_name} 占位
paramsjson参数列表定义(参数名 + 类型 + 说明)
versionint版本号
statusenumactive / archived
created_attimestamp

message_log

字段类型说明
message_idstring消息 ID(全局唯一)
scene_codestring场景编码
source_systemstring来源系统
source_referencestring来源系统的关联 ID(如申请 ID、借据号)
recipientstring接收方(手机号 / WhatsApp ID / 设备 token)
channelenumsms / whatsapp / push
providerstring实际使用的供应商
template_idstring使用的模板 ID
rendered_contenttext已替换变量的完整文本
statusenumpending / sent / delivered / failed / undelivered / expired / blocked
provider_message_idstring供应商侧消息 ID
failure_reasonstring失败原因
block_reasonstring频控拦截原因
sent_attimestamp
delivered_attimestamp
provider_callback_rawtext供应商回执原始报文
retry_countint重试次数

异常路径

场景处理
供应商返回失败自动切换备用供应商(若配置),最多重试 2 次
供应商超时无回执TTL(默认 30s)后标记 expired,不重试(验证码除外)
模板变量不匹配模版定义了 {name} 但调用方未传,保留未替换文本发送,记录告警
接收方格式无效返回校验错误,不发送
频控拦截不发送,记录 status=blocked + 拦截原因,返回成功但标记频控
同场景同接收方重复请求验证码场景 1 分钟内去重(防刷接口)

MVP 边界

MVP 阶段短信网关整体不实现。下表仅作为后续版本拆分参考。

能力MVP二期
短信发送后续版本建设
WhatsApp 发送催收核心场景
App Push
模板管理至少验证码/催收/通知三类模板
发送记录
频控基本防刷(一分钟内同号码去重)
供应商自动切换MVP 只接 1 家
批量发送运营系统营销场景
投递回调通知向上游异步通知投递状态
多语言支持模板预留 lang 字段,二期启用