Skip to main content
O titular não está na sua tela: está num call center, num cadastro por telefone, ou abandonou o formulário ontem. O WhatsApp entrega a jornada no aparelho que tem a câmera boa.

Confira o exemplo

Os arquivos desta POC, com o destino de cada um.

A credencial não vai na mensagem

A entry.url carrega o acesso à jornada. Ela sai do seu backend para o titular daquela verificação e para mais ninguém — e uma mensagem fica no histórico do aparelho, do WhatsApp Web aberto no computador da loja, e do backup em nuvem. Então o que viaja é um link curto do seu domínio, que só o seu servidor sabe trocar pela entry.url:
1

Crie a verificação e guarde a entry

A entry.url fica no seu banco, junto com um token opaco e um prazo.
2

Mande o token, não a URL

A mensagem leva https://seu-dominio/v/<token>.
3

Troque no clique

A sua rota valida o token, marca como usado e redireciona para a entry.url.
Isso também é o que o template de botão do WhatsApp permite: a URL base é fixa e aprovada pela Meta, e só o sufixo é variável. Você não conseguiria mandar a entry.url inteira nem se quisesse.

Criar e despachar

app/api/verifications/whatsapp/route.ts

A mensagem

O WhatsApp exige um template aprovado para mensagem iniciada pela empresa. Registre um com botão de URL dinâmica, cuja base é o seu domínio:
Template aprovado na Meta
lib/whatsapp.ts

A rota que troca o token

app/v/[token]/route.ts
Não faça a rota devolver a entry.url em JSON para o front redirecionar. Isso coloca a credencial no histórico de rede do navegador e em qualquer extensão instalada. O redirecionamento é do servidor.

Antes de enviar para gente de verdade

Fora da janela de 24 horas de atendimento, a Meta só entrega template aprovado. Dentro dela, a mensagem livre funciona — mas o link curto continua sendo o que você manda.

Antes de rodar

.env
Use uma integração sandbox. Nenhum dos três valores vai para o browser ou para o app. Esta POC precisa também das credenciais da Meta:
.env

O que esta POC não faz

POC é código para entender o fluxo, não para copiar em produção. Em todas elas, authenticate() é um stub, db é um objeto de mentira e não há migration, observabilidade nem retentativa própria.
  • Sem webhook de status do WhatsApp: você não sabe se a mensagem foi lida.
  • Sem fallback para SMS quando o número não tem WhatsApp.
  • Sem rate limit por cadastro no reenvio.
  • Sem migration para a tabela links; ela precisa de índice único em token.

Próximo passo

QR code

A mesma entrega, quando o titular está na sua tela.

Retomada e expiração

O que fazer quando o link expira antes do clique.