MarioSMS
一次性验证码如何抵达你的手机

一次性验证码如何抵达你的手机

作者: MarioSMS team · · 阅读约 19 分钟

目录
  1. 每条验证码都要经手的四方
  2. 为什么 A2P 短信和个人之间的短信走的路不一样
  3. 站在接收端,你能看到什么、看不到什么
  4. 什么是发送方 ID、路由和聚合商?
  5. 一步步追踪一条验证码在网络中的路径
  6. 为什么不同服务、不同国家的送达情况差别这么大?
  7. 验证码一直收不到,该怎么排查?
  8. 关于短信一次性验证码接收的常见问题

你点下”发送验证码”,手机却安静了几秒。就在这段空隙里,这条短信穿过了四套从不直接与你打交道的系统。应用生成一次性验证码,把短信内容交给消息服务商。这家服务商,也就是聚合商,选定一条下发路由。路由的终点是移动运营商,由它通过信令网络把短信推送到手机上。每一跳都可能让短信排队、改写发送方,或者干脆丢掉。

一次性验证码经过的路径

环节由谁执行可能出现的问题
你的应用或后端你自己速率限制、校验、重复发送
短信服务商或聚合商供应商路由选择、排队
批发路由两个网络之间的运营商灰色路由、静默丢弃
目标运营商该运营商发件人过滤、垃圾信息规则
手机用户关机、收件箱已满、漫游

每条验证码都要经手的四方

参与方负责什么可能坏在哪
应用生成 OTP,设置有效期(通常 60 到 300 秒)对你限流,重复下发过期的旧码
聚合商选择路由,处理发送方 ID 格式走了便宜但送达率差的路由
运营商投递到 SIM 卡,执行垃圾短信过滤拦截陌生发送方,延迟流量
手机显示短信,运行自动填充会话被静音,短信被归入垃圾箱

为什么 A2P 短信和个人之间的短信走的路不一样

朋友发来的短信从运营商网络内的一张 SIM 卡出发,全程都在运营商轨道上跑。而 A2P 短信从服务器出发,经由短信网关接入,在抵达目标网络之前就被归类为商业流量。商业流量需要报备,会被限速和过滤,而且按条计费,这就带来了压低路由成本的压力。路由走得便宜,正是验证码 40 秒才到、而不是 4 秒就到的最常见原因。

站在接收端,你能看到什么、看不到什么

在手机上你只能看到三件事:短信有没有到、发送方字符串是什么、时间戳是多少。你看不到是哪家聚合商发的,走了哪条路由,也不知道运营商是不是把它压了 20 秒。送达回执只存在于发送方那一侧。

用租用号码,这个计时就是明明白白的。MarioSMS 号码 $0.04 起,一次只接一个验证,验证码会显示在应用或后台里,通常一分钟内就到。如果在激活窗口关闭前什么都没收到,激活会自动取消,费用退回你的余额。

什么是发送方 ID、路由和聚合商?

有三个名词最容易让人犯迷糊。发送方 ID 是显示在发件人栏里的内容。路由是消息从发送方到你的运营商之间所走的商业通道。聚合商则是中间商,批量采购这些通道,再按条转售。

在运营商之间传输消息的网络设备

聚合商位于应用平台和数百家运营商之间,通过上图这类设备互相连接。一条消息在抵达为你的 SIM 卡提供服务的网络之前,可能要经过两三家聚合商。送达报告会沿着同一条链路回传,每一跳都可能改写它。

发送方 ID 的类型:字母数字、短码、长号码

字母数字型发送方 ID 显示的是品牌名称,无法接收回复。短码是 4 到 6 位数字,需按国家注册,通常吞吐量很高。长号码看起来和普通手机号一样,租用号码用的就是这一类。

聚合商如何选择路由,以及最低成本路由改变了什么

  1. 平台把消息连同目标号码前缀交给它的网关
  2. 网关先按价格给可用路由排序,再按近期送达率排序。
  3. 除非发送方付费购买了直连路由,否则最便宜且可接受的路由胜出。
  4. 如果该路由拒绝或超时,消息会在下一条路由上重试。

最低成本路由会把流量推向当前这个小时最便宜的那家供应商。直连路由是运营商到运营商的。灰色路由从侧门接入运营商,成本更低,一旦被运营商发现就会毫无预警地被封掉。

过滤和垃圾信息评分发生在哪里

过滤至少发生在三个地方。发送平台会拦截自己标记的问题账户。聚合商会丢弃匹配已知垃圾信息特征的内容。接收方运营商则根据发送方信誉、内容和发送量给消息打分,然后决定送达、延迟还是悄悄丢弃。

为什么”已送达”状态可能是错的

状态它的含义它不代表
Submitted网关已接收该消息运营商已经看到它
Sent它已离开聚合商、发往某条路由它已进入运营商网络
Delivered下游某一方返回了成功状态码手机已经显示出来
Failed某一跳返回了错误该号码无效

在某些路由上,这个成功状态值在消息抵达手机之前就已经生成,被过滤掉的消息照样可以被报成已送达。把回执当作路由参考信息,而不是验证码已经到手的证据。

一步步追踪一条验证码在网络中的路径

三秒钟就到达的验证码,和永远收不到的验证码,走的是同一条路。区别在于哪一跳卡住了或者丢了包。下面这张表列出了每一跳、由谁运营,以及该环节最常见的故障形式。

送达报告能证明什么,不能证明什么

状态代表的含义不代表的含义
Accepted(已接受)聚合商已接收该消息运营商将会送达
Sent(已发送)消息已发往运营商手机已收到
Delivered(已送达)运营商已确认送达用户已看到,或验证码仍然有效
Failed(失败)有环节拒绝了该消息你知道是哪个环节

[TABLE: The path a one-time code takes]

第 1 步到第 8 步:从 API 调用到手机

  1. 你点击发送,应用向自己的后端发起请求。
  2. 后端调用它的 短信网关 或服务商 API。
  3. 服务商为该国家和 发送方 ID 选择一条路由。
  4. 消息到达拥有本地互联的聚合商。
  5. 聚合商把消息交给运营商的 SMSC。
  6. SMSC 按用户记录把消息排入队列。
  7. 手机通过信令通道接收消息。
  8. 送达回执沿同一条链路逐级返回。

时间到底花在哪里

第 1 步到第 4 步是数据中心之间的 API 调用,通常在 500 毫秒内完成。第 5 步才是变数所在。繁忙的 SMSC 可能把一条消息压上 10 秒,如果手机脱网,甚至会压上好几分钟。

[IMAGE: Typical timing of a one-time code]

大多数验证码走完整条链路需要 2 到 20 秒。长尾情况集中在国际路由、最近携号转网的号码,以及刚从飞行模式恢复、还在重新注册网络的手机上。

从运营商的角度看,重试是什么样子

当你按下重新发送时,发送方应用会生成一个新验证码,并提交第二条消息。运营商看到的是几秒钟内发往同一个号码、内容几乎一样的两次提交。过滤系统会把这种模式视为疑似垃圾短信。连续三次快速重试,可能导致你的号码在该路由上被限流 10 到 30 分钟。

两次重试之间请等待 60 秒。如果第一条消息只是排队而不是被丢弃,它往往会在这段等待中送达。

租用号码接收同一条消息的过程

租用号码运行在运营商网络中的真实 SIM 卡上,所以第 5 步到第 7 步和你自己的手机完全一样。区别在第 8 步以及之后:消息不会出现在锁屏上,而是落到一个后台面板里。

使用 MarioSMS,你每次租一个号码完成一次验证,起价 $0.04。验证码会显示在应用中或 app.mariosms.com 上,通常一分钟内到达。如果在激活窗口关闭前没有收到短信,激活会自动取消,费用自动退回你的余额。

为什么不同服务、不同国家的送达情况差别这么大?

同一个应用,在某个国家 6 秒就能收到验证码,换个国家却直接超时。短信内容完全一样,变的是这条消息在送达途中必须通过的那套规则。

一次性验证码的典型时间线

发送方报备与各国规则

有些国家要求发送方先完成报备,才会放行任何 A2P 流量。报备内容包括公司主体、示例短信模板以及 发送方 ID 字符串。未报备的流量会被拦截、被改写成通用号码,或者直接丢弃且不返回送达报告。所以一个在欧洲各地都正常的服务,可能在某个市场一直失败,直到手续办妥为止。

规则还会层层叠加。有的监管机构禁用字母型发送方 ID,强制使用数字号码;有的要求使用本地格式号码;还有的禁止短信正文里出现网址,这对于发送魔法链接而非 6 位验证码的应用来说影响很大。

用短码发送的服务 vs 用长号码发送的服务

发送方类型典型用途你能感受到的表现
短码(5 到 6 位)单一国家的大批量 OTP快速、稳定,但仅限一个国家
长虚拟号码跨境 OTP 和回复覆盖面广,路由绕远时速度较慢
字母型 ID品牌类通知在部分国家被拦截或被改写

短码是按国家、按运营商分别租用的,所以一个在本国使用短码的服务,到了国外就会退回到长号码。这条退路要经过更多跳转节点,每一跳都会增加排队时间。

国家组合、库存与价格差异

号码就是库存。号段会被消耗、被标记、被停用,而运营商释放新号段的节奏各不相同。号段新鲜、发送方规则宽松的国家,服务成本自然低于干净号码稀缺的国家。正因如此,MarioSMS 的价格从每个号码 $0.04 起,并按服务和国家浮动,覆盖 35+ 个国家、数百种有货服务。

在 35+ 个国家测试同一套流程

  1. 选定一个服务,在国家 A 租一个号码。
  2. 记录从发送到验证码出现在后台的耗时。
  3. 在国家 B 和国家 C 重复测试,同一个服务,同一个时段。
  4. 对比各国的到达时间和取消率。
  5. Python、Node.js、Go 或 PHP 调用 REST API,把整个流程自动化循环起来。

每个号码对应一次激活。如果计时结束前没有收到短信,激活会自动取消,费用原路退回余额。所以一次失败的国家测试,花掉的是时间,不是钱。

验证码一直收不到,该怎么排查?

验证码没到,问题只可能出在三个地方:发送方、传输链路、接收方。按这个顺序逐一排查,因为发送方的问题最常见,也最容易检查。

先检查发送方

  1. 确认服务已经接受了你填写的号码格式,包括国家代码,且中间没有空格。
  2. 看看服务有没有显示「验证码已发送」的状态,或者弹出错误提示。
  3. 等满 60 秒再点重发,很多平台会把第二次请求排在第一次后面等待。
  4. 数一下你已经重发了几次。有些服务每小时超过 3 次就会限流,多出来的请求会被直接丢弃,不作任何提示。
  5. 确认该服务是否支持你所选国家的短信。

如果服务压根没把消息交给它的 短信网关,后面的环节再正常也没用。

排除链路和过滤拦截

运营商的过滤机制会拦下看起来像垃圾短信的消息,而且通常不会通知发送方。一条消息可能被聚合商接收、标记为已发送,却始终到不了手机上。被拦截的迹象:同一个服务在某个国家能正常收到,换一个国家就收不到;或者某些号段能收到验证码,另一些收不到。

现象可能原因下一步
任何国家都收不到验证码发送方拒绝了该号码重新核对格式和服务支持情况
A 国能收到,B 国没动静B 国的链路或过滤问题换一个国家
验证码延迟 5 到 15 分钟才到队列积压或重试耐心等倒计时走完
第一条验证码正常,第二条收不到发送方限流等一小时

排除手机和号码本身

用的是租用号码,手机不在你手上,所以接收端只剩一个问题:平台有没有记录到这条来信。刷新一下控制台,App 和网页版 app.mariosms.com 都看一下,并确认你查看的是当前这次号码激活,而不是之前的某一次。

什么时候该取消并重新激活

倒计时剩不到 30 秒还没收到消息,就取消。费用会自动退回你的余额。然后重新租一个号码,最好换个国家,并且只发一次请求,别连发三次。

关于短信一次性验证码接收的常见问题

一次性验证码通常多久能收到?

大多数验证码在一分钟内就会送达。如果超过 90 秒还没到,一般说明消息卡在了队列里、被过滤了或者正在重试,而不是彻底丢失了。

两个服务可以共用同一个发送方 ID 吗?

可以。字母数字发送方 ID 并非在每个国家都全球唯一,所以两个应用都可能显示为 “VERIFY”。请看短信正文,别只看开头的署名。

收到送达报告是不是意味着用户看到了验证码?

不是。送达报告只能确认手机已经接收了这条消息,至于有没有人真的看屏幕,它说明不了任何问题。

为什么有些验证码到达的顺序是乱的?

不同的消息会走不同的路由和重试路径。如果你在 20 秒内连着请求三个验证码,第三个有可能最先到。使用最新那个之前,先把每个验证码和对应的请求对上号。

如果租用的号码一直收不到短信会怎样?

激活计时器到期后,租用会自动取消,费用原路退回你的余额。号码没收到消息,你就不用付钱。可以再租一个新号码,最好换个国家,然后只发一次请求。

我可以通过 API 而不是控制台来接收验证码吗?

可以。REST API 会以 JSON 格式返回验证码,并提供 Python、Node.js、Go 和 PHP 的示例代码。可以参考用 Python 接收短信,里面有一个可直接运行的轮询循环。

租用号码的哪些用途是被允许的?

隐私保护、出于正当理由注册的第二账号,以及 QA 或 OTP 测试。绝不允许用于规避封禁或冒充他人。完整清单见可接受使用政策页面。