code:0 只代表"已提交给通道",不代表"用户已收到"。短信是异步的,想知道最终结果,要么看发送状态查询,要么接回执推送。先看你自己的日志:code 是不是 0?如果是 402(额度不足)、429(限流)、403(IP 不在白名单),那根本就没发出去,先解决这些。
成功了就把 call_id 记下来——后面每一步都靠它定位。
用「发送状态查询」或回执推送看这条的最终状态。平台会把上游的返回带回来,常见是:
DELIVRD:已送达 —— 那问题在用户侧(下一步);UNDELIV / 空号 / 停机:号码本身的问题;空号、停机、欠费、刚携号转网还没生效。换一个正常号码测一下就能排除。
平台对同一号码默认 3 条/分钟、10 条/小时、20 条/天(防短信轰炸)。如果你在几秒内连点了几次"获取验证码",后面的会被拒(返回 429),但用户以为全发出去了。前端加个 60 秒倒计时能避免这个问题。
发送前平台会做一次违规词预检,命中直接拦下、不计费。这种情况通常日志里能看到拦截原因。注意:验证码内容请只放数字/字母,别夹带营销话术。
短信内容必须是已报备通过的模板。如果模板刚提交还在审核,发送会失败或走到兜底通道。到控制台「短信模板」看审核状态。
这是最容易被忽略的一条,而且平台侧看起来是"已送达":
让用户去短信的"拦截/垃圾箱"里翻一下,或者换台手机试。
通道偶尔会抽风。可以重试一次(记得带同一个 X-Request-Id,避免重复扣费);连续多次都这样,把 call_id 发给客服查上游。
如果短信确实收不到(比如用户号码被运营商风控),可以改用语音验证码:用电话把验证码念给用户,作为短信的兜底通道。语音验证码 API →
code 是 0 吗?不是 → 按错误码处理;call_id 找客服 / 提工单。