Guia prático para adicionar verificação por código OTP via WhatsApp oficial no seu sistema, com exemplos em Node.js, PHP e Python — e comparação honesta de custos entre WhatsApp, SMS e e-mail
Como implementar OTP (código de confirmação) por WhatsApp no Brasil
Se você tem um cadastro, login ou checkout, em algum momento vai precisar confirmar que o usuário realmente controla o número de telefone que informou. Esse é o trabalho do OTP (One-Time Password, ou senha de uso único): você envia um código, o usuário digita, você confere.
No Brasil, mandar esse código por WhatsApp costuma ser melhor que por SMS — mais gente lê, entrega mais e custa menos. Neste post eu mostro como implementar isso na prática, com código que roda, e comparo os canais de forma honesta (inclusive citando alternativas pagas).
Por que WhatsApp e não SMS?
| Critério | WhatsApp oficial | SMS | |
|---|---|---|---|
| Entregabilidade | Alta | Média | Baixa (cai em spam) |
| Taxa de leitura | ~98% | ~90% | ~20% |
| Custo por envio | ~R$ 0,03 | R$ 0,08–0,15 | Baixo, mas pouco lido |
| Copiar código | Botão nativo | Manual | Manual |
O SMS ainda é um bom fallback para quem não usa WhatsApp, mas como canal principal de OTP no Brasil, o WhatsApp ganha na maioria dos casos.
⚠️ Use sempre a API oficial do WhatsApp (WhatsApp Business Platform), não automação de WhatsApp Web. Automação não oficial derruba a entrega e corre risco de bloqueio pela Meta.
O fluxo em 2 passos
Toda implementação de OTP tem a mesma forma:
-
Enviar o código (
send) → você gera um código e manda pelo canal. -
Verificar o código (
verify) → o usuário digita e você confere.
O detalhe importante: a resposta do send confirma que a mensagem foi aceita, mas a entrega no aparelho é assíncrona. Para OTP isso não é problema — a própria verificação já é a prova de entrega. Se o usuário digitou o código certo, chegou. Você não precisa de webhook nem de polling de status.
Implementando com uma API pronta
Você pode falar direto com a WhatsApp Business Platform, mas isso exige aprovação de template, gestão de número e conta na Meta. Para ir mais rápido, dá pra usar um provedor que já cuida disso. As opções mais conhecidas:
- Twilio Verify — global, robusto, ~US$ 0,05 por verificação.
- Zenvia / Infobip — grandes players com presença no Brasil.
- entrar.api.br — opção brasileira de baixo custo (R$ 0,03 por OTP enviado, verificação grátis), com dois endpoints simples e sem SDK.
Abaixo uso a entrar.api.br porque a API é minimalista (bom pra exemplo), mas o padrão vale pra qualquer provedor.
1. Enviar o código
curl -X POST https://cpf.entrar.api.br/api/otp/send \
-H "Authorization: Bearer SEU_API_SECRET" \
-H "Content-Type: application/json" \
-d '{"telefone":"+5511999999999"}'
# → { "ok": true, "otpId": "...", "status": "pending" }
Guarde o otpId — é ele que amarra o código ao usuário.
2. Verificar o código
curl -X POST https://cpf.entrar.api.br/api/otp/verify \
-H "Authorization: Bearer SEU_API_SECRET" \
-H "Content-Type: application/json" \
-d '{"otpId":"...","codigo":"123456"}'
# → { "ok": true, "verified": true }
Exemplos por linguagem
Node.js
async function enviarOtp(telefone) {
const res = await fetch("https://cpf.entrar.api.br/api/otp/send", {
method: "POST",
headers: {
Authorization: "Bearer SEU_API_SECRET",
"Content-Type": "application/json",
},
body: JSON.stringify({ telefone }),
});
return res.json(); // { ok, otpId, status }
}
async function verificarOtp(otpId, codigo) {
const res = await fetch("https://cpf.entrar.api.br/api/otp/verify", {
method: "POST",
headers: {
Authorization: "Bearer SEU_API_SECRET",
"Content-Type": "application/json",
},
body: JSON.stringify({ otpId, codigo }),
});
return res.json(); // { ok, verified }
}
PHP
function enviarOtp(string $telefone): array {
$ch = curl_init("https://cpf.entrar.api.br/api/otp/send");
curl_setopt_array($ch, [
CURLOPT_RETURNTRANSFER => true,
CURLOPT_POST => true,
CURLOPT_HTTPHEADER => [
"Authorization: Bearer SEU_API_SECRET",
"Content-Type: application/json",
],
CURLOPT_POSTFIELDS => json_encode(["telefone" => $telefone]),
]);
return json_decode(curl_exec($ch), true);
}
Python
import requests
def enviar_otp(telefone: str) -> dict:
res = requests.post(
"https://cpf.entrar.api.br/api/otp/send",
headers={"Authorization": "Bearer SEU_API_SECRET"},
json={"telefone": telefone},
)
return res.json()
Boas práticas de segurança
- Códigos de uso único e com expiração curta (ex.: 10 minutos).
-
Limite tentativas de verificação por
otpIdpara evitar força bruta. - Rate-limit no reenvio — não deixe reenviar OTP em loop para o mesmo número.
- Nunca exponha o API Secret no front-end — mantenha só no back-end.
Conclusão
OTP por WhatsApp resolve verificação de telefone no Brasil com boa entrega e custo baixo. O fluxo é simples — send e verify — e você não precisa de webhook: a verificação já é a confirmação de entrega. Se quiser o caminho mais barato e direto, a entrar.api.br cobra R$ 0,03 por envio; se precisar de escala global com fallback automático de canal, Twilio Verify e Infobip são alternativas maduras.
Escrevi este guia com base na implementação real da entrar.api.br, uma camada de identidade brasileira (CPF + OTP + verificação de idade) usada em produção por instituições como a faculdade Unifama e plataformas de alto volume como o 123 Bolão.
Top comments (0)