SMS para enviar código de verificação é caro, tem entrega instável e cai cada vez mais em filtros de operadora. O WhatsApp resolve os três: o usuário já tem o app, a entrega é quase instantânea e o custo por mensagem é uma fração do SMS. Este artigo mostra como implementar autenticação em dois fatores (2FA) e códigos OTP por WhatsApp usando uma API REST, com o fluxo completo e cuidados de segurança.
O fluxo OTP em 4 passos
- Usuário pede o código (login, cadastro ou confirmação de transação).
- Seu backend gera um código numérico, guarda um hash dele com expiração curta e envia pelo WhatsApp via API.
- Usuário digita o código.
- Seu backend compara o hash e libera (ou bloqueia após N tentativas).
Gerando e enviando o código
// 1. gere o código no backend (NUNCA no frontend)
const code = String(Math.floor(100000 + Math.random() * 900000)); // 6 dígitos
// guarde apenas o hash + expiração (ex.: Redis, TTL 300s)
await redis.set(`otp:${phone}`, sha256(code), "EX", 300);
// 2. envie pelo WhatsApp
await fetch(`https://api.zap-api.tech/v1/instances/${id}/send`, {
method: "POST",
headers: { Authorization: `Bearer ${token}`, "Content-Type": "application/json" },
body: JSON.stringify({
phone,
type: "text",
body: `Seu código de verificação é ${code}. Ele expira em 5 minutos. Não compartilhe com ninguém.`
})
});
Validando
const stored = await redis.get(`otp:${phone}`);
if (!stored) return res.status(410).json({ error: "Código expirou" });
if (stored !== sha256(req.body.code)) {
await redis.incr(`otp:fail:${phone}`); // trave após 5 falhas
return res.status(401).json({ error: "Código inválido" });
}
await redis.del(`otp:${phone}`); // uso único
// libera o acesso
POST /v1/instances/{id}/contacts/check — assim você não dispara OTP para número que nem existe no WhatsApp.
Por que verificar o número antes
POST /v1/instances/{id}/contacts/check
{ "phone": "5511999998888" }
// retorna se o número existe no WhatsApp
Disparar OTP para números inexistentes desperdiça envio e suja sua reputação. O contacts/check filtra isso de graça.
Confiabilidade: confirme a entrega
Não confie só no HTTP 200 (que significa "aceito na fila"). Escute o webhook message.status para saber se o código foi entregue. Se não entregar em alguns segundos, ofereça um canal alternativo (SMS de fallback ou ligar).
Comece em minutos, sem aprovação da Meta
Crie uma instância, conecte o WhatsApp lendo um QR Code e faça o primeiro envio via API REST. Trial de 7 dias, sem cartão.
Criar conta grátisPerguntas frequentes
Preciso de template aprovado pela Meta para OTP? Não nesta abordagem. A conta conecta por QR Code, sem aprovação de template — você envia o texto que quiser.
É seguro mandar OTP por WhatsApp? É tão seguro quanto SMS (ambos dependem do controle do aparelho), com a vantagem da criptografia ponta a ponta do WhatsApp. Mantenha expiração curta e uso único.
Qual o custo comparado ao SMS? Não há custo por mensagem aqui — você paga a assinatura da instância e envia o volume que precisar (respeitando o limite por minuto).
E se o usuário não tiver WhatsApp? Use o contacts/check para detectar e caia para um fallback (SMS/e-mail).