如果你需要在应用中自动化处理SMS验证码接收,手动操作控制台明显不够高效。SMSCode提供完整的REST API,让你可以将虚拟号码能力直接集成到自己的系统中。
本文从零开始,带你完成SMSCode API的集成,包含可以直接使用的代码示例。
TL;DR: SMSCode API兼容SMS-Activate协议,接入成本极低。核心流程是:获取号码 → 等待验证码 → 标记完成。本文提供Python和Node.js的完整代码示例,30分钟内完成集成。
准备工作
在开始编写代码前,需要完成以下准备:
- 注册SMSCode账号并完成邮箱验证
- 充值账户余额(API调用需要余额支撑)
- 在控制台的”设置”→“API”页面获取你的API密钥
- 确认目标服务在SMSCode上可用(查看服务目录)
API密钥格式:32位十六进制字符串,例如 a1b2c3d4e5f6...
安全提示:API密钥等同于账号密码权限。不要将其写入代码仓库,应该通过环境变量注入。
API基础
Base URL
https://api.smscode.gg/v1
认证方式
所有请求需要在Header中携带API密钥:
Authorization: Bearer YOUR_API_KEY
或者通过查询参数传入(不推荐,容易出现在日志中):
?api_key=YOUR_API_KEY
请求/响应格式
所有API请求和响应均使用JSON格式。完整的API文档请访问开发者文档。
核心工作流
SMS验证码接收的完整流程分三步:
1. 购买号码(获取虚拟号码 + 订单ID)
↓
2. 轮询/等待验证码(最多等待规定时间)
↓
3. 标记订单状态(完成 或 取消)
Python集成示例
以下是一个可以直接使用的Python集成示例:
import requests
import time
class SMSCodeClient:
def __init__(self, api_key: str):
self.api_key = api_key
self.base_url = "https://api.smscode.gg/v1"
self.headers = {"Authorization": f"Bearer {api_key}"}
def get_number(self, service: str, country: str) -> dict:
"""购买虚拟号码"""
resp = requests.post(
f"{self.base_url}/orders",
headers=self.headers,
json={"service": service, "country": country}
)
resp.raise_for_status()
return resp.json()["data"]
def wait_for_sms(self, order_id: str, timeout: int = 120) -> str | None:
"""轮询等待验证码,返回验证码字符串或None"""
start = time.time()
while time.time() - start < timeout:
resp = requests.get(
f"{self.base_url}/orders/{order_id}",
headers=self.headers
)
data = resp.json()["data"]
if data["status"] == "completed" and data.get("sms_code"):
return data["sms_code"]
elif data["status"] in ["cancelled", "expired"]:
return None
time.sleep(5) # 每5秒轮询一次
return None
def cancel_order(self, order_id: str):
"""取消订单(收不到验证码时调用,触发退款)"""
requests.patch(
f"{self.base_url}/orders/{order_id}",
headers=self.headers,
json={"action": "cancel"}
)
# 使用示例:注册Google账号
def register_with_google_verification():
client = SMSCodeClient(api_key="YOUR_API_KEY")
# 1. 购买印度号码(Google注册推荐)
order = client.get_number(service="google", country="in")
phone_number = order["phone"]
order_id = order["id"]
print(f"已获取号码: {phone_number}")
print(f"订单ID: {order_id}")
# 2. 将phone_number输入到Google注册表单...
# (在这里添加你的Selenium/Playwright代码)
# 3. 等待验证码
code = client.wait_for_sms(order_id, timeout=120)
if code:
print(f"收到验证码: {code}")
# 将验证码填入表单...
else:
print("未收到验证码,取消订单")
client.cancel_order(order_id)
Node.js集成示例
const axios = require('axios');
class SMSCodeClient {
constructor(apiKey) {
this.apiKey = apiKey;
this.baseUrl = 'https://api.smscode.gg/v1';
this.headers = { Authorization: `Bearer ${apiKey}` };
}
async getNumber(service, country) {
const resp = await axios.post(
`${this.baseUrl}/orders`,
{ service, country },
{ headers: this.headers }
);
return resp.data.data;
}
async waitForSms(orderId, timeout = 120000) {
const start = Date.now();
while (Date.now() - start < timeout) {
const resp = await axios.get(
`${this.baseUrl}/orders/${orderId}`,
{ headers: this.headers }
);
const data = resp.data.data;
if (data.status === 'completed' && data.sms_code) {
return data.sms_code;
}
if (['cancelled', 'expired'].includes(data.status)) {
return null;
}
await new Promise(r => setTimeout(r, 5000));
}
return null;
}
async cancelOrder(orderId) {
await axios.patch(
`${this.baseUrl}/orders/${orderId}`,
{ action: 'cancel' },
{ headers: this.headers }
);
}
}
// 使用示例
async function main() {
const client = new SMSCodeClient(process.env.SMSCODE_API_KEY);
const order = await client.getNumber('whatsapp', 'id'); // 印尼WhatsApp号码
console.log(`号码: ${order.phone}`);
// 将号码输入WhatsApp注册页面...
const code = await client.waitForSms(order.id);
if (code) {
console.log(`验证码: ${code}`);
} else {
await client.cancelOrder(order.id);
console.log('未收到验证码,已退款');
}
}
Webhook实时推送(推荐)
轮询方式简单,但每次请求都有网络开销。对于高并发场景,推荐使用Webhook——验证码到达时,SMSCode主动推送到你指定的URL。
配置Webhook
在控制台的API设置页面,填入你的Webhook URL:
https://your-server.com/smscode-webhook
Webhook接收端(Node.js示例)
const express = require('express');
const crypto = require('crypto');
const app = express();
app.use(express.json());
app.post('/smscode-webhook', (req, res) => {
// 验证请求来自SMSCode(使用签名验证)
const signature = req.headers['x-smscode-signature'];
const payload = JSON.stringify(req.body);
const expected = crypto
.createHmac('sha256', process.env.SMSCODE_WEBHOOK_SECRET)
.update(payload)
.digest('hex');
if (signature !== expected) {
return res.status(401).json({ error: 'Invalid signature' });
}
const { order_id, phone, sms_code, status } = req.body;
if (status === 'sms_received' && sms_code) {
console.log(`订单 ${order_id} 收到验证码: ${sms_code}`);
// 处理验证码(填入表单、存入数据库等)
processVerificationCode(order_id, sms_code);
}
res.json({ received: true });
});
Webhook方式的优势:
- 验证码到达后毫秒级响应,无轮询延迟
- 减少API请求次数,降低成本
- 适合高并发场景(同时处理数百个号码)
错误处理最佳实践
常见错误码
| 错误码 | 含义 | 处理方式 |
|---|---|---|
| 400 | 参数错误 | 检查请求参数格式 |
| 401 | API密钥无效 | 检查API密钥是否正确 |
| 402 | 余额不足 | 充值后重试 |
| 404 | 订单不存在 | 检查订单ID |
| 429 | 请求频率超限 | 降低请求频率,实现退避重试 |
| 503 | 号码暂时缺货 | 等待或换其他国家 |
重试逻辑
import time
import random
def api_call_with_retry(func, max_retries=3):
for attempt in range(max_retries):
try:
return func()
except requests.exceptions.HTTPError as e:
if e.response.status_code == 429:
# 遇到频率限制,指数退避
wait = (2 ** attempt) + random.random()
time.sleep(wait)
continue
elif e.response.status_code in [500, 503]:
# 服务器错误,短暂等待后重试
time.sleep(2 ** attempt)
continue
else:
raise # 其他错误直接抛出
raise Exception("超过最大重试次数")
服务代码参考
购买号码时,需要指定服务代码(service参数)。常用服务代码:
| 平台 | 服务代码 |
|---|---|
google | |
whatsapp | |
| Telegram | telegram |
facebook | |
instagram | |
| TikTok | tiktok |
| Twitter/X | twitter |
完整的服务代码列表,请访问开发者文档或控制台的服务目录。
批量操作优化
对于需要同时处理大量号码的企业用户,需要考虑并发控制:
import asyncio
import aiohttp
async def process_batch(services: list, concurrency: int = 10):
semaphore = asyncio.Semaphore(concurrency)
async def process_one(service):
async with semaphore:
# 一个号码的完整处理流程
order = await get_number_async(service)
code = await wait_for_sms_async(order['id'])
return {"order": order, "code": code}
tasks = [process_one(s) for s in services]
results = await asyncio.gather(*tasks, return_exceptions=True)
return results
建议的并发限制:
- 普通账号:最多20个并发请求
- 企业账号:根据套餐上限,通常可以更高
- 轮询间隔:至少5秒,避免触发频率限制
迁移自SMS-Activate
已经在使用SMS-Activate API的开发者:SMSCode兼容SMS-Activate协议,迁移通常只需修改一行代码。
SMS-Activate API endpoint:
https://api.sms-activate.org/stubs/handler_api.php
SMSCode兼容endpoint:
https://api.smscode.gg/compat/sms-activate
保持其他代码不变,只修改base URL,即可完成迁移。当然,使用原生SMSCode REST API可以获得更好的功能和错误信息。
查看SMSCode vs SMS-Activate的完整对比了解更多迁移细节。
FAQ
SMSCode API有免费试用额度吗?
SMSCode按次计费,没有单独的免费试用额度。但注册后可以充值最低金额进行测试,验证码接收失败会自动退款,实际成本风险很低。
API的请求频率限制是多少?
标准账号的API请求限制是每秒10次。如果你需要更高的并发能力,可以联系客服申请企业级配额。对于轮询请求,建议间隔至少5秒,不要无限制地高频轮询。
API密钥泄露了怎么办?
立即在控制台的API设置页面重置API密钥,旧密钥会立即失效。同时检查账号余额和订单历史,确认是否有异常消费。
SMSCode的API支持哪些编程语言?
SMSCode API是标准的REST API,任何支持HTTP请求的语言都可以使用:Python、Node.js、PHP、Java、Go、Ruby等。本文提供了Python和Node.js示例,其他语言的集成方式类似。
如何在测试环境中安全地使用API密钥?
使用环境变量存储API密钥(SMSCODE_API_KEY),不要硬编码到代码中。对于CI/CD环境,使用对应平台的Secrets功能(GitHub Secrets、GitLab CI Variables等)。测试环境建议使用单独的、余额有限的测试账号。