Como enviar código de verificação (OTP) pela API de WhatsApp
Para enviar código de verificação pelo WhatsApp, o seu sistema gera o código, guarda só o hash com prazo de validade e usa a API apenas para entregar a mensagem. Quem valida é o seu backend, com limite de tentativas e de reenvios por número.
Quem faz o quê num fluxo de OTP
Um código de verificação serve para provar que a pessoa tem acesso àquele número naquele momento. Isso vale para cadastro, login sem senha, segundo fator e confirmação de operação sensível, como troca de e-mail ou saque. A tentação é procurar um endpoint pronto que gere e valide o código. Não faça isso depender do canal de entrega.
A divisão correta de responsabilidades é esta:
| Etapa | Responsável |
|---|---|
| Gerar o código com fonte aleatória segura | Seu backend |
| Guardar o hash, a validade e o contador de tentativas | Seu backend |
| Entregar a mensagem no WhatsApp do usuário | API de WhatsApp |
| Comparar o código digitado e invalidar após o uso | Seu backend |
| Bloquear abuso por número, IP e conta | Seu backend |
Assim, trocar de canal, somar SMS como alternativa ou mudar de fornecedor não mexe na lógica de segurança. A API de WhatsApp vira um transporte, que é o papel dela aqui.
Exemplo completo em Node
O trecho abaixo mostra as duas pontas: emitir e verificar. O armazenamento está abstraído em db, que pode ser Redis com expiração ou uma tabela com coluna de validade.
import { randomInt, createHash, timingSafeEqual } from 'node:crypto'
import { DApi } from 'd-api-sdk'
const dapi = new DApi({ apiKey: process.env.DAPI_API_KEY! })
const hash = (codigo: string) => createHash('sha256').update(codigo).digest()
export async function emitirCodigo(telefone: string) {
const codigo = randomInt(0, 1_000_000).toString().padStart(6, '0')
await db.otp.upsert(telefone, {
hash: hash(codigo),
expiraEm: Date.now() + 5 * 60_000,
tentativas: 0,
})
await dapi.messages.sendText({
sessionId: 'app-verificacao',
to: telefone, // ex.: 5511999999999
text: `${codigo} é o seu código de verificação do App. Ele expira em 5 minutos. Não compartilhe com ninguém.`,
})
}
export async function verificarCodigo(telefone: string, digitado: string) {
const registro = await db.otp.get(telefone)
if (!registro || registro.expiraEm < Date.now()) return false
if (registro.tentativas >= 5) return false
await db.otp.incrementarTentativas(telefone)
const ok = timingSafeEqual(hash(digitado), registro.hash)
if (ok) await db.otp.remover(telefone) // uso único
return ok
}Repare que o código em texto puro só existe na memória durante o envio. Ele não vai para o banco nem para o log. Para os detalhes do SDK, veja o SDK Node.js e o guia de API de WhatsApp em Node.js.
Checklist de segurança
- Aleatoriedade de verdade. Use
crypto.randomIntou equivalente. Nada deMath.randomou código derivado de horário. - Hash, nunca texto puro. Se o banco vazar, códigos em aberto viram acesso imediato.
- Validade curta e uso único. Cinco a dez minutos, e o código morre na primeira verificação bem-sucedida.
- Limite de tentativas por código. Cinco erros invalidam o código e exigem um novo envio.
- Limite de envios por número. Por exemplo, um reenvio a cada 60 segundos e no máximo cinco por hora. Isso protege o usuário de spam e protege o seu número de parecer robô descontrolado.
- Limite por IP e por conta, para barrar quem tenta disparar códigos para milhares de números diferentes.
- Sem código em log. Registre que o envio aconteceu, com o telefone mascarado, nunca o código.
- Mensagem curta e clara: código no início, validade e o aviso de não compartilhar.
Velocidade e disponibilidade do envio
Código que demora chega depois que o usuário desistiu. Algumas decisões ajudam:
- Use uma sessão dedicada para verificação, separada de atendimento e de campanhas. Assim um problema num número de marketing não trava o login dos usuários.
- Envie de forma síncrona, sem fila no meio. Aqui o usuário está olhando a tela, e a resposta da API diz na hora se houve erro.
- Monitore o evento
connection.statusda sessão de verificação e alerte o time se ela sair deconnected. - Ofereça SMS como alternativa depois de alguns segundos ou quando o envio falhar. A D-API tem API de SMS na mesma conta.
Um número usado só para códigos, com volume que acompanha o uso real do app, tem perfil de envio saudável. Mesmo assim, vale conhecer os cuidados de como evitar banimento.
Quando usar o template de autenticação da API oficial
Na API oficial da Meta, código de verificação tem uma categoria própria de template, a de autenticação. O template precisa ser aprovado antes do uso, e a cobrança da Meta é por mensagem, com valor que varia por categoria e país. Em troca, o envio sai por um número verificado da empresa.
Faz sentido considerar a oficial quando:
- O volume de códigos é muito alto e vem de usuários que nunca conversaram com a empresa.
- O setor é regulado e a empresa exige o canal oficial por política interna.
- A marca verificada no remetente é importante para o usuário confiar no código.
Na D-API, uma conexão oficial envia o template pela rota messages/send/template, com o código em bodyVariables. O resto da aplicação continua o mesmo. Veja a API oficial de WhatsApp e a comparação em API oficial vs não oficial. Código de verificação é um tipo de notificação transacional, com exigência maior de velocidade. O trial de 3 dias permite testar o fluxo inteiro com um número real.
Perguntas frequentes
A API de WhatsApp gera o código de verificação para mim?
Não, e isso é bom. O código deve nascer e ser validado no seu sistema, que é quem conhece o usuário e a regra de expiração. A API só entrega a mensagem com o código no WhatsApp da pessoa.
WhatsApp é mais seguro que SMS para enviar OTP?
O WhatsApp tem criptografia de ponta a ponta e não depende da operadora, o que elimina alguns riscos do SMS, como interceptação na rede. Mas a segurança do fluxo continua dependendo de como o seu sistema gera, guarda e expira o código.
Quantos dígitos e quanto tempo de validade o código deve ter?
Seis dígitos numéricos é o padrão mais usado, fácil de digitar e difícil de adivinhar com limite de tentativas. Para login e cadastro, cinco a dez minutos de validade costuma ser suficiente.
E se o número do usuário não tiver WhatsApp?
Tenha um canal alternativo. A D-API também envia SMS pela mesma conta, então o seu sistema pode oferecer receber por SMS quando o envio pelo WhatsApp falhar ou quando o usuário pedir.
Preciso de template para enviar código pela API oficial?
Sim. Na API oficial, mensagens de código entram na categoria autenticação e precisam de template aprovado pela Meta. Na API não oficial o código vai como texto comum, sem aprovação prévia.
Continue lendo
Teste a API de WhatsApp da D-API
Trial de 3 dias com acesso completo. Sem cartão, sem fidelidade.