用阿里云短信服务发验证码或通知,动手前要先备齐三样东西:一个完成实名认证的阿里云账号、一条审核通过的短信签名、一个审核通过的短信模板。调用接口还需要 AccessKey。签名就是短信开头方括号里显示的名字,一般是公司或产品名。模板是固定文字,需要变化的部分用变量占位,比如验证码。

先申请签名和模板
在短信服务控制台依次添加签名和模板。签名要上传营业执照,或其他能证明主体身份的材料。模板要选定使用场景,验证码、通知或营销三选一,并写清每条短信的完整内容。验证码类模板必须包含 ${code} 这样的变量,文字里也不能出现营销词句。审核时长以控制台显示为准,最好提前留出时间。
模板内容必须和实际用途对得上。比如模板写的是“您的验证码是 ${code},5 分钟内有效”,就不能拿来发促销。用途和内容不一致,是模板被驳回最常见的原因之一。被驳回后,先回头看一眼用途说明,问题往往出在这里,而不是文字本身。
用 RAM 子账号拿凭证
不要直接用主账号的 AccessKey。主账号权限很大,一旦泄露,损失很难控制。更稳妥的做法是在资源访问管理(RAM)里建一个子账号,只授予短信相关权限,例如系统策略 AliyunDysmsFullAccess,或者自己配一套最小权限策略。拿到 AccessKey ID 和 AccessKey Secret 后,放进环境变量,不要写进代码,也不要提交到代码仓库。
用代码调用发送接口
阿里云提供多种语言的 SDK。下面的 Python 示例调用的是 SendSms 操作,接口地址为 dysmsapi.aliyuncs.com。签名名称、模板编号和变量名都要和控制台里的内容逐字一致,任何一处对不上,接口都会直接报错。
import os
from alibabacloud_dysmsapi20170525.client import Client
from alibabacloud_dysmsapi20170525 import models
from alibabacloud_tea_openapi import models as open_api_models
config = open_api_models.Config(
access_key_id=os.environ['ALIBABA_CLOUD_ACCESS_KEY_ID'],
access_key_secret=os.environ['ALIBABA_CLOUD_ACCESS_KEY_SECRET'],
endpoint='dysmsapi.aliyuncs.com'
)
client = Client(config)
req = models.SendSmsRequest(
phone_numbers='13800000000',
sign_name='某某科技',
template_code='SMS_XXXXXXX',
template_param='{"code":"123456"}'
)
resp = client.send_sms(req)
print(resp.body.code, resp.body.message)
返回的 code 为 OK,说明请求已经提交成功。但这只代表短信进入了运营商通道,不代表用户手机已经收到。送达情况要通过回执查询接口或短信报表确认,上线后别只看接口返回值就认为一切正常。
实际案例:小店怎么用短信发验证码和发货通知
设想一家做手工饰品的小网店,以下数字仅作示意。店里每天大约有 300 个新用户注册,之前用邮件发验证码,打开率很低,常有用户反馈收不到。店主改用阿里云短信后,给注册验证码申请了一个“验证码”类模板,给发货通知申请了一个“通知”类模板,两类用途分开申请,审核也顺利通过。
上线时,开发者把验证码发送放进注册接口,并限制同一手机号每分钟只能发一次。这样一方面能挡住恶意刷短信,另一方面避免用户连点导致多次计费。发货通知则在订单状态变为“已发货”时触发,由后台定时任务批量调用。
运行一周后,店主发现一批短信发送失败,错误码是 isv.BUSINESS_LIMIT_CONTROL。查下来,原因是一次营销活动期间注册量突然上涨,撞上了账号的频率限制。开发者随后在代码里加入失败重试和指数退避,并在活动前提前申请提高限额。这件事说明,配额最好在活动前评估,事后补救要麻烦得多。
常见报错怎么排查
- isv.BUSINESS_LIMIT_CONTROL:触发了频率或流控限制。先检查代码里是否有循环调用或重试过于激进,再决定是降低频率,还是申请提高配额。
- isv.MOBILE_NUMBER_ILLEGAL:手机号格式不对。国内号码应为 11 位数字,国际号码需要带国家码。表单提交前最好先做一次格式校验。
- isv.TEMPLATE_MISSING_PARAMETERS:模板变量没有全部传入。对照模板里的变量名,检查 template_param 中的键名是否一字不差,大小写也要留意。
- isv.SMS_SIGNATURE_ILLEGAL:签名未通过审核,或者拼写不一致。把代码里的 sign_name 和控制台显示的名称逐字比对。
上线前的注意事项
短信按条计费,程序一旦出现循环调用,费用会迅速增加。上线前先在控制台设置余额提醒,并给发送量设定上限,这几分钟的设置能省去很多麻烦。
测试阶段用自己的手机号把流程跑通就够了,不要把测试脚本指向真实用户的号码。验证码和通知两类模板各自测一遍,出问题时也更容易定位。