Consultar o status é a forma mais simples de obter um código: você envia uma requisição, olha a resposta e, se vier vazia, repete alguns segundos depois. Essa simplicidade engana: cada requisição extra pesa no limite da API, e o atraso continua imprevisível, porque o código pode aparecer logo depois da consulta e ficar parado até o próximo ciclo. O webhook funciona de outro jeito: o servidor avisa sobre o evento no instante em que ele acontece. Vamos ver o que a migração para webhook traz na prática, o que preparar do seu lado, como distinguir uma chamada verdadeira de uma falsa e quando ainda não dá para abrir mão do polling.

Push versus consulta: o que o webhook oferece

No polling, o cliente chama o endpoint de status a cada poucos segundos, e até o código chegar quase todas as respostas significam «nada de novo». Com uma dezena de ativações em paralelo, já são centenas de chamadas desnecessárias por minuto, que batem no limite da API mas não eliminam o atraso entre o momento em que o código aparece no servidor e o momento em que o aplicativo fica sabendo. O que é o código em si está explicado no artigo o que é um código OTP.

O webhook inverte o esquema: o servidor do remetente inicia a requisição para o endereço do webhook assim que o evento está pronto. O atraso cai para o tempo de entrega de uma única requisição HTTP, e o número de chamadas à API diminui para uma por ativação, em vez de dezenas de consultas à espera do resultado.

O que preparar do seu lado

O primeiro requisito é um endereço de webhook acessível publicamente. O receptor precisa responder de fora por HTTPS: com domínio ou IP público, sem endereço de rede local e sem proxy entre o remetente e o seu servidor. Se o endereço não é resolvido a partir da internet, o evento não tem para onde ir: o remetente vai registrar um erro de conexão, e não um silêncio do lado dele. Os motivos pelos quais o receptor fica inacessível estão no artigo sobre a quebra das chamadas de retorno.

O segundo requisito é a velocidade da resposta. O manipulador do webhook deve receber o corpo da requisição e devolver imediatamente um código 2xx, sem esperar pela lógica de negócio: análise do texto, busca do código com regex, gravação no banco de dados. Esse trabalho vai para uma fila e é executado por um processo separado. Se você processa tudo de forma síncrona antes de responder, uma lentidão no banco ou em um serviço de terceiros vira timeout, e o remetente considera a entrega malsucedida, embora o evento tenha de fato chegado.

Assinatura da requisição: como verificar que o webhook é verdadeiro

O endereço público do webhook é visível para qualquer pessoa que o encontre ou o descubra em tráfego interceptado. Sem verificação de autenticidade, o endpoint aceita qualquer corpo com conteúdo arbitrário: basta enviar uma requisição POST com um «código» inventado, e o manipulador engole isso como se fosse um evento real.

A assinatura fecha essa brecha: o remetente gera o hash do corpo da requisição com uma chave secreta e coloca o resultado em um cabeçalho; o receptor recalcula o hash com a mesma chave e compara os valores. A coincidência confirma tanto a autenticidade da origem do webhook quanto o fato de que o corpo não foi alterado no caminho. A chave fica guardada apenas no servidor e não vai para o código do lado do cliente; em caso de suspeita de vazamento, ela é rotacionada no painel, atualizando ao mesmo tempo a verificação do seu lado.

A reentrega do webhook é normal, não é falha

O remetente não tem como ter certeza de que um código 2xx significa «evento salvo», e não «o servidor respondeu, mas o processamento falhou um segundo depois». Por isso, a maioria dos sistemas repete a entrega do webhook de acordo com um cronograma: depois de alguns segundos, depois de um minuto, e assim várias vezes, até receber a confirmação ou esgotar o limite de tentativas. O resultado é que o mesmo código, com o mesmo identificador de evento, pode chegar duas e até três vezes.

O manipulador precisa ser idempotente: antes de gravar, verificar se o código com esse identificador de ativação ou de evento já foi salvo e, na repetição, simplesmente responder 200, sem criar nada de novo. As novas tentativas do remetente se parecem com a forma correta de refazer as suas próprias requisições a uma API de terceiros; os princípios gerais estão no artigo erros de API: como tratar e repetir requisições. Se o receptor ficou indisponível durante toda a janela de repetições, o evento só não se perde sob uma condição: o remetente ter uma fila de eventos não entregues, para que o que foi perdido possa ser recuperado manualmente por uma consulta de status separada.

Quando o polling ainda faz sentido

Se a tarefa não tem um endereço público permanente (um ambiente de testes sem domínio, um script avulso em uma máquina atrás de NAT, um piloto curto que será desligado em um dia), não faz sentido criar um webhook para ela. O polling com intervalo de alguns segundos resolve uma tarefa pontual ou rara sem a infraestrutura de receptor e assinatura.

O segundo caso é uma requisição realmente única: um código para uma ativação, sem fluxo de eventos, em que o ganho do webhook não compensa o trabalho de configurar um endereço público e uma fila de processamento. No recebimento regular ou paralelo de códigos, a relação se inverte: o polling passa a consumir o limite da API mais rápido do que economiza tempo de integração.

Perguntas frequentes

Posso usar o mesmo endereço de webhook para vários serviços?

Tecnicamente sim, se o manipulador distinguir os eventos pelo campo com o identificador do serviço ou da ativação no corpo da requisição. Na prática, é melhor separar as origens em caminhos diferentes no mesmo domínio: assim fica mais fácil ler os logs e atualizar a assinatura de uma origem sem mexer nas outras.

O que fazer se o provedor não suporta reentrega?

Configure um polling de status em paralelo como seguro, para o caso de o receptor ter ficado indisponível no momento da única tentativa de push. Consulte com pouca frequência, uma vez a cada alguns minutos: isso basta para recuperar o evento perdido, sem transformar a consulta no canal principal.

Como verificar se a assinatura funciona corretamente antes de ir para produção?

Envie um evento de teste com o corpo propositalmente corrompido ou com um cabeçalho de assinatura incorreto e confirme que o manipulador o rejeita antes de gravar no banco de dados. Depois repita com a assinatura correta e o mesmo identificador de evento duas vezes seguidas: a segunda chamada deve devolver 200, sem criar nada novamente.

O formato do evento, o cabeçalho de assinatura, a estrutura do corpo da requisição e os parâmetros de novas tentativas para o recebimento de códigos por webhook estão descritos na documentação da API.