DEV Community

Raphael Serafim
Raphael Serafim

Posted on

Como implementar OTP (código de confirmação) por WhatsApp no Brasil

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 E-mail
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:

  1. Enviar o código (send) → você gera um código e manda pelo canal.
  2. 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" }
Enter fullscreen mode Exit fullscreen mode

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 }
Enter fullscreen mode Exit fullscreen mode

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 }
}
Enter fullscreen mode Exit fullscreen mode

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);
}
Enter fullscreen mode Exit fullscreen mode

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()
Enter fullscreen mode Exit fullscreen mode

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 otpId para 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)