← Blog

·

Código de verificação (OTP) pelo WhatsApp com template de autenticação

Atualizado em 25/10/2026

Para enviar código de verificação (OTP) pelo WhatsApp, a Meta exige um template de autenticação: texto pré-definido (“123456 é seu código de verificação.”), um botão de OTP (copiar código, preenchimento com um toque ou zero-tap) e nenhuma URL, mídia ou emoji. Você cria o template uma vez, a Meta aprova e, a cada login, sua aplicação envia o código como parâmetro. Para destinatários no Brasil, cada mensagem de autenticação entregue custa R$ 0,0350 na tabela em reais em vigor desde 1º de outubro de 2026, com desconto por volume.

Este guia mostra os três tipos de botão, os payloads de criação e envio, como configurar validade e TTL e os cuidados de segurança que a Meta recomenda.

Por que precisa ser template de autenticação

A Meta é explícita: só templates de autenticação podem enviar senha de uso único para verificar identidade. Marketing e utilidade não podem. Se a Meta detectar um template de outra categoria sendo usado para isso, ela avisa e muda o status dele para REJECTED no primeiro dia do mês seguinte, sem direito a revisão. As regras completas de categoria estão em como a Meta classifica seu template.

Para ser classificado como autenticação, o template precisa:

  • usar os modelos de autenticação da Cloud API, com texto fixo definido pela Meta;
  • ter um botão de OTP;
  • não ter URL, mídia nem emoji, no conteúdo ou nos parâmetros;
  • usar parâmetros de no máximo 15 caracteres.

Casos de uso aceitos: criação de conta, recuperação ou integridade de acesso e confirmação de pedidos ou transações.

O texto é fixo: o que você pode configurar

O corpo não é escrito por você. A Meta usa um texto pré-definido, traduzido para o idioma do template, e permite dois complementos opcionais:

OpçãoCampoEfeito
Aviso de segurançaadd_security_recommendation: true no corpoAcrescenta uma frase pedindo para não compartilhar o código
Validade do códigocode_expiration_minutes no rodapé (1 a 90)Acrescenta no rodapé o aviso de que o código expira em N minutos
Tempo de vida da mensagemmessage_send_ttl_seconds (30 a 900)Se não for entregue nesse prazo, a mensagem é descartada

O TTL padrão de templates de autenticação é de 10 minutos (templates criados antes de 23 de outubro de 2024 tinham 30 dias). A Meta recomenda um TTL igual ou menor que a validade do código: não faz sentido entregar um código que já expirou. Como a Meta só cobra mensagens entregues, mensagens descartadas pelo TTL não entram na conta.

Os três tipos de botão

TipoComo funcionaPlataformaExige integração no app?
Copiar código (COPY_CODE)O usuário toca no botão, o código vai para a área de transferência e ele cola no appTodasNão
Um toque (ONE_TAP)O botão abre o seu app já com o código preenchidoAndroidSim: handshake e activity para receber o código
Zero-tap (ZERO_TAP)Sem botão: o app recebe o código por broadcast e o usuário nem sai da telaAndroidSim: handshake, broadcast receiver e aceite de termos

No iOS 26 ou superior, o próprio teclado sugere o código recebido no WhatsApp, sem integração. Em versões anteriores do iOS, o usuário vê o botão de copiar código.

Um ponto importante: one-tap e zero-tap têm fallback. Se o handshake não aconteceu, se o app não confere ou se o destinatário não está no Android, o WhatsApp mostra o botão de copiar código (e, no zero-tap, tenta primeiro o one-tap). Por isso, um template one-tap ou zero-tap sempre funciona como copiar código no pior caso.

Criando o template com botão de copiar código

Na Cloud API direta, o template é criado no endpoint message_templates da conta do WhatsApp Business:

curl -X POST "https://graph.facebook.com/v26.0/SEU_WABA_ID/message_templates" \
  -H "Authorization: Bearer TOKEN_DA_META" \
  -H "Content-Type: application/json" \
  -d '{
    "name": "codigo_verificacao",
    "language": "pt_BR",
    "category": "AUTHENTICATION",
    "message_send_ttl_seconds": 300,
    "components": [
      { "type": "BODY", "add_security_recommendation": true },
      { "type": "FOOTER", "code_expiration_minutes": 5 },
      {
        "type": "BUTTONS",
        "buttons": [
          { "type": "OTP", "otp_type": "COPY_CODE", "text": "Copiar código" }
        ]
      }
    ]
  }'

Repare que não há campo text no corpo: a Meta preenche. O rótulo do botão (text) tem até 25 caracteres e é opcional; sem ele, a Meta usa um rótulo padrão traduzido. Depois da criação, o botão OTP aparece como tipo URL quando você consulta o template, e isso é esperado.

Variação one-tap (Android)

Para one-tap, troque o botão e informe os apps autorizados:

{
  "type": "OTP",
  "otp_type": "ONE_TAP",
  "text": "Copiar código",
  "autofill_text": "Preencher",
  "supported_apps": [
    { "package_name": "br.com.exemplo.app", "signature_hash": "K8a/AINcGX7" }
  ]
}

Regras do one-tap, segundo a documentação de autofill:

  • supported_apps aceita até 5 pares de pacote e hash;
  • package_name tem até 224 caracteres, com pelo menos dois segmentos separados por ponto;
  • signature_hash tem exatamente 11 caracteres;
  • autofill_text e text têm até 25 caracteres;
  • o app precisa iniciar um handshake com o WhatsApp antes do envio e ter uma activity com a ação com.whatsapp.otp.OTP_RETRIEVED;
  • o handshake vale por 10 minutos, ou pelo tempo de code_expiration_minutes, se definido.

A Meta recomenda o SDK oficial para o handshake. O método baseado em PendingIntent está sendo descontinuado em 15 de outubro de 2026.

Variação zero-tap (Android)

O zero-tap usa "otp_type": "ZERO_TAP", os mesmos supported_apps e o campo zero_tap_terms_accepted: true. Sem esse aceite, o template não é criado. O app precisa de um broadcast receiver para com.whatsapp.otp.OTP_RETRIEVED. Mesmo no zero-tap, o usuário vê no WhatsApp a mensagem com o texto fixo.

Para depurar one-tap e zero-tap no Android, o WhatsApp envia sinais de erro por broadcast com a ação com.whatsapp.OTP_ERROR, com chaves como otp_request_expired e missing_handshake_or_disorder.

Enviando o código

O envio é um template comum, com uma particularidade: o código aparece duas vezes, no parâmetro do corpo e no parâmetro do botão. O código tem no máximo 15 caracteres.

{
  "messaging_product": "whatsapp",
  "recipient_type": "individual",
  "to": "5584999999999",
  "type": "template",
  "template": {
    "name": "codigo_verificacao",
    "language": { "code": "pt_BR" },
    "components": [
      {
        "type": "body",
        "parameters": [{ "type": "text", "text": "482913" }]
      },
      {
        "type": "button",
        "sub_type": "url",
        "index": "0",
        "parameters": [{ "type": "text", "text": "482913" }]
      }
    ]
  }
}

Um exemplo de função em Node.js que gera o código, guarda o hash e envia:

import crypto from 'node:crypto';

export async function enviarOtp(telefone, db) {
  const codigo = String(crypto.randomInt(0, 1_000_000)).padStart(6, '0');
  const hash = crypto.createHash('sha256').update(codigo).digest('hex');
  await db.salvarOtp(telefone, hash, Date.now() + 5 * 60 * 1000); // 5 minutos

  const corpo = {
    messaging_product: 'whatsapp',
    recipient_type: 'individual',
    to: telefone,
    type: 'template',
    template: {
      name: 'codigo_verificacao',
      language: { code: 'pt_BR' },
      components: [
        { type: 'body', parameters: [{ type: 'text', text: codigo }] },
        { type: 'button', sub_type: 'url', index: '0', parameters: [{ type: 'text', text: codigo }] },
      ],
    },
  };

  const r = await fetch(process.env.WHATSAPP_URL, {
    method: 'POST',
    headers: { Authorization: `Bearer ${process.env.WHATSAPP_TOKEN}`, 'Content-Type': 'application/json' },
    body: JSON.stringify(corpo),
  });
  return r.json(); // guarde o wamid para cruzar com o webhook de status
}

Acompanhe o status pelo webhook: se o delivered não chegar dentro do TTL, considere a mensagem descartada e ofereça outro canal. Os estados possíveis estão em status de mensagem via webhook.

Segurança: o que a Meta recomenda

A página de boas práticas de autenticação traz alguns cuidados que vale levar a sério:

  • Número reciclado. O WhatsApp só verifica a posse do número no registro. Um número pode mudar de dono. Na Cloud API, guarde o hash de identidade recebido depois do primeiro OTP validado e inclua-o nos envios seguintes: se o número for de outra pessoa, a entrega falha em vez de chegar ao novo dono.
  • Desafio extra em fluxos sensíveis. Para recuperação de conta, combine o código do WhatsApp com outra verificação.
  • Encaminhamento bloqueado. O WhatsApp desativa o encaminhamento de mensagens de autenticação, o que reduz phishing.
  • Escolha do canal. Peça consentimento e ofereça opções (WhatsApp, e-mail, SMS). Confirme com o usuário qual número ele usa no WhatsApp, que pode ser diferente do número do SMS.
  • WhatsApp instalado. No Android, verifique os pacotes com.whatsapp e com.whatsapp.w4b; no iOS, se o esquema whatsapp://otp pode ser aberto.
  • Uma conta por empresa. Cada empresa precisa da própria conta, conta de mensagens e número. Compartilhar entre empresas viola a política.

Quanto custa cada código

A Meta cobra autenticação por mensagem entregue. Para destinatários no Brasil, a tabela em reais em vigor desde 1º de outubro de 2026 tem desconto progressivo por volume mensal, somado em todas as contas do portfólio:

Mensagens de autenticação por mês (Brasil)Preço por mensagem (BRL)
Até 500.000R$ 0,0350
500.001 a 3.000.000R$ 0,0333
3.000.001 a 5.250.000R$ 0,0315
5.250.001 a 10.000.000R$ 0,0298
10.000.001 a 20.000.000R$ 0,0280
Acima de 20.000.000R$ 0,0263

As faixas zeram todo mês. A tarifa de autenticação internacional, cobrada em alguns mercados, não se aplica ao Brasil. Mensagens enviadas dentro de uma janela de ponto de entrada gratuito, aberta por anúncios de clique para o WhatsApp, não são cobradas. Para simular volumes, veja quanto custa uma campanha no WhatsApp e o artigo de preços da API no Brasil.

Como fazer com a Vectalk

Na Vectalk, o template de autenticação é criado em POST /api/templates com o mesmo corpo da Meta, usando um token de instância:

curl -X POST https://apis.vectalk.com.br/api/templates \
  -H "Authorization: Bearer SEU_TOKEN_DE_INSTANCIA" \
  -H "Content-Type: application/json" \
  -d '{
    "name": "codigo_verificacao",
    "language": "pt_BR",
    "category": "AUTHENTICATION",
    "components": [
      { "type": "BODY", "add_security_recommendation": true },
      { "type": "FOOTER", "code_expiration_minutes": 5 },
      { "type": "BUTTONS", "buttons": [ { "type": "OTP", "otp_type": "COPY_CODE", "text": "Copiar código" } ] }
    ]
  }'

O envio usa POST https://apis.vectalk.com.br/api/messages com o payload da seção anterior. No código Node.js acima, basta apontar WHATSAPP_URL para esse endpoint e usar o token da Vectalk. Veja a documentação de templates, crie sua conta em apps.vectalk.com.br/register e, se estiver começando, leia o guia da API oficial do WhatsApp.

Perguntas frequentes

Posso escrever meu próprio texto no código de verificação?

Não. O texto do template de autenticação é pré-definido pela Meta. Você só escolhe o idioma, se inclui o aviso de segurança, a validade em minutos e o rótulo dos botões.

O código pode ter letras?

Sim, a Meta fala em códigos geralmente alfanuméricos. O limite é de 15 caracteres por parâmetro, e o mesmo valor vai no corpo e no botão.

O one-tap funciona no iPhone?

Não. One-tap e zero-tap são exclusivos do Android. No iPhone, o usuário vê o botão de copiar código; no iOS 26 ou superior, o teclado também sugere o código automaticamente.

Preciso de template diferente para cada idioma?

Sim. Cada idioma é um template. Na criação em massa da Meta, o endpoint upsert_message_templates aceita uma lista de idiomas de uma vez.

Um template de autenticação pode ser reprovado?

Sim, por formato ou parâmetros inválidos. Ele não sofre a regra de duplicidade, já que o texto é padrão. Veja template reprovado no WhatsApp.


Fontes oficiais consultadas em 25/10/2026: Templates de autenticação, Botão de copiar código, Botão one-tap, Zero-tap, Sinais de erro, Boas práticas de autenticação, Time-to-live, Categorização de templates, Preços e planilha “Níveis de volume em BRL” (vigência 1º/10/2026).

Integre o WhatsApp oficial ao seu sistema

A Vectalk entrega a Cloud API da Meta com os mesmos payloads e webhooks, um token para todas as contas e documentação completa.