O que é um webhook? Como as apps se notificam entre si
Um webhook é uma mensagem automática que um serviço envia à sua app no momento em que algo acontece. Quando o pagamento de um cliente é aprovado, a Stripe envia um webhook para um endereço da sua app a dizer «pagamento aprovado, aqui estão os detalhes», e a sua app reage — marca a encomenda como paga, envia o recibo, ativa a conta. Em resumo: uma API é a sua app a fazer uma pergunta a outro serviço; um webhook é o outro serviço a chamar a sua app para lhe dizer algo.
Porque é importante quando constrói com IA
Assim que a sua app recebe pagamentos, submissões de formulários de outra ferramenta ou se liga a serviços como o GitHub, a Shopify ou um calendário, vai cruzar-se com webhooks. Normalmente são a forma correta de saber que algo aconteceu — mas também é onde as apps construídas com IA costumam estar subtilmente erradas:
- O endpoint aceita qualquer pedido, por isso qualquer pessoa pode falsificar um evento de «pagamento aprovado».
- A app concede acesso na página de redirecionamento do checkout, e não no webhook, por isso quem fecha o separador cedo nunca recebe o que pagou, e quem descobrir o URL de sucesso recebe-o de graça.
- O mesmo evento chega duas vezes e o cliente recebe duas encomendas ou dois emails.
Saber como funcionam os webhooks permite-lhe pedir as proteções desde o início.
Uma analogia do dia a dia: uma mensagem de entrega
Pode saber se a sua encomenda chegou de duas formas. Pode andar até à porta de casa de dez em dez minutos para verificar (isso é polling — a sua app a chamar repetidamente uma API para perguntar «há novidades?»). Ou o estafeta pode enviar-lhe uma mensagem quando entregar (isso é um webhook).
A mensagem é claramente melhor — desde que possa confiar nela. Se qualquer pessoa pudesse enviar-lhe uma mensagem de «encomenda entregue», quereria alguma forma de saber se veio mesmo do estafeta. E se o telemóvel estivesse desligado quando a mensagem chegou, quereria que o estafeta voltasse a tentar mais tarde. Essas duas preocupações — verificação e novas tentativas — são a maior parte do que torna os webhooks complicados.
Como funciona um webhook, passo a passo
- Cria um endpoint no backend da sua app: um URL como
https://asuaapp.pt/webhooks/stripeque aceita pedidosPOST. - Regista esse URL no fornecedor e escolhe os eventos que quer (por exemplo, «checkout concluído» e «subscrição cancelada»).
- O fornecedor dá-lhe um segredo de assinatura. Guarda-o como segredo no seu servidor — veja variáveis de ambiente e segredos.
- Acontece um evento. O fornecedor envia um pedido HTTP para o seu URL com um corpo JSON que descreve o evento, mais um cabeçalho de assinatura.
- A sua app verifica a assinatura, regista o ID do evento, responde rapidamente com um código de sucesso (
200) e só depois faz o trabalho. - Se a sua app não responder com sucesso, muitos fornecedores tentam de novo mais tarde.
Assinaturas
Uma assinatura prova que o pedido veio do fornecedor e que não foi alterado. A Stripe, por exemplo, calcula um HMAC (uma espécie de impressão digital com chave) com SHA-256 sobre o corpo do pedido e um timestamp, usando o segredo de assinatura, e envia-o num cabeçalho Stripe-Signature. A sua app faz o mesmo cálculo com a sua cópia do segredo; se os resultados coincidirem, o pedido é genuíno. Como o timestamp também é assinado, pode rejeitar pedidos antigos que alguém tenha gravado e reenviado mais tarde — as bibliotecas da Stripe têm por defeito uma tolerância de cinco minutos, segundo a documentação de setembro de 2026.
Um detalhe prático: a assinatura é calculada sobre o corpo bruto do pedido. Se a sua framework fizer parse e reformatar o JSON antes de verificar, a verificação falha. Este é um erro muito comum.
Novas tentativas, duplicados e ordem
Os fornecedores diferem, por isso confirme a documentação de cada um. Em setembro de 2026:
| Comportamento | Stripe | GitHub |
|---|---|---|
| Novas tentativas automáticas | Sim, durante até três dias com intervalos crescentes no modo ativo | Não; as entregas falhadas são reenviadas manualmente ou por script |
| Tempo de resposta | Responda com um 2xx rapidamente, antes de qualquer trabalho lento | Uma entrega que demore mais de 10 segundos a obter resposta conta como falhada |
A documentação da Stripe também diz que os eventos não têm garantia de chegar na ordem em que aconteceram, e que o mesmo evento pode, ocasionalmente, chegar mais do que uma vez; por isso recomenda registar os IDs dos eventos.
A lição geral vale para qualquer fornecedor: os eventos podem chegar atrasados, mais do que uma vez e fora de ordem. O seu handler deve ser idempotente — processar o mesmo evento duas vezes tem o mesmo efeito que processá-lo uma vez.
Um exemplo prático: desbloquear um curso pago
Vende um curso online. Um aluno clica em Comprar, paga na página de checkout alojada pela Stripe e é reencaminhado para o seu site.
A forma frágil: a página de «obrigado» desbloqueia o curso. Se o aluno fechar o navegador durante o redirecionamento, pagou mas não tem acesso. Se alguém adivinhar o URL da página de obrigado, obtém acesso sem pagar.
A forma com webhook:
- Quando a Stripe confirma o pagamento, envia um evento
checkout.session.completedpara/webhooks/stripe. - O seu backend verifica a assinatura com o segredo de assinatura. Se falhar, responde
400e não faz nada. - Verifica se esse ID de evento já foi processado. Se sim, responde
200e para. - Guarda o ID do evento, responde
200e só então concede acesso ao aluno e envia um email de boas-vindas. - A página de obrigado diz apenas «Pagamento recebido — o seu curso aparecerá dentro de momentos» e verifica o estado de acesso do aluno.
Mais tarde, se uma subscrição for cancelada ou um cartão falhar, outros eventos de webhook dizem à sua app para remover ou suspender o acesso. É assim que os produtos de subscrição se mantêm sincronizados com a faturação — veja o que é SaaS e como adicionar pagamentos à sua app.
Termos-chave
- Endpoint: o URL da sua app que recebe webhooks.
- Evento / payload: o que aconteceu, e os dados que o descrevem (normalmente JSON).
- Segredo de assinatura: o segredo partilhado usado para verificar assinaturas.
- Idempotente: seguro de executar mais do que uma vez com o mesmo resultado.
- Polling: pedir repetidamente à API alterações, em vez de esperar por um webhook.
- Túnel: uma ferramenta que dá ao portátil um URL público temporário para que os webhooks o possam alcançar durante o desenvolvimento.
Erros comuns e ideias erradas
- Não verificar assinaturas. O URL do endpoint não é um segredo. A verificação é o que torna o pedido fiável.
- Fazer trabalho lento antes de responder. Enviar emails ou gerar PDFs antes de responder pode causar timeouts, que disparam novas tentativas, que causam duplicados.
- Assumir entrega exatamente uma vez, e em ordem. Registe os IDs dos eventos e não dependa da ordem de chegada.
- Usar um URL de pré-visualização. Os webhooks precisam de um endereço público e estável. Pré-visualizações privadas e
localhostnão são alcançáveis a partir da internet; use o seu URL publicado (ou um túnel durante os testes). - Misturar segredos de teste e ativos. Os fornecedores costumam emitir segredos de assinatura diferentes para os modos de teste e ativo. Guarde ambos e use o correto.
- Confiar cegamente no payload para decisões importantes. Em ações de grande impacto, é razoável obter o estado mais recente da API do fornecedor depois de receber o evento.
O que pedir ao seu construtor de IA
Acrescenta um endpoint
POST /webhooks/stripeno servidor. Verifica a assinatura da Stripe usando o corpo bruto do pedido e o segredoSTRIPE_WEBHOOK_SECRET. Rejeita assinaturas inválidas com 400. Guarda o ID de cada evento e ignora eventos já processados. Responde 200 rapidamente e, depois, tratacheckout.session.completedmarcando a encomenda como paga e enviando o recibo. Regista o tipo de evento. Não concedas acesso a partir da página de sucesso do checkout.
Depois, teste: envie um evento de teste a partir do painel do fornecedor, envie o mesmo outra vez e envie um pedido com uma assinatura errada. Só o primeiro deve alterar alguma coisa.
Webhooks no Mythex
O Mythex não tem um serviço de webhooks separado; pede ao agente que acrescente um endpoint de webhook no backend da sua própria app, e aponta o fornecedor para o seu URL publicado, já que os webhooks precisam de um endereço público. O segredo de assinatura vai para os segredos do projeto, e se o alterar numa app ativa, publique novamente. A receita da documentação sobre como tratar webhooks tem um prompt inicial, e os modelos de loja são um bom ponto de partida para apps que recebem pagamentos.
Perguntas
O que é um webhook, em termos simples?
Um webhook é uma mensagem automática que um serviço envia para um endereço web da sua app quando algo acontece, como um pagamento concluído ou um formulário submetido. Em vez de a sua app perguntar repetidamente se algo mudou, o outro serviço é que lhe diz.
Qual é a diferença entre um webhook e uma API?
Com uma chamada de API, a sua app pede a outro serviço algo e recebe uma resposta. Com um webhook, o outro serviço chama a sua app quando um evento acontece. Muitas integrações usam ambos: webhooks para saber dos eventos, chamadas de API para obter detalhes ou executar uma ação.
Os webhooks são seguros?
Podem ser, se os verificar. Os fornecedores bem concebidos assinam cada webhook com um segredo partilhado apenas com a sua app, e esta deve rejeitar qualquer pedido cuja assinatura não corresponda. Sem essa verificação, quem encontrar o URL poderia enviar eventos falsos.
O que acontece se a minha app estiver em baixo quando o webhook for enviado?
Depende do fornecedor. A Stripe, por exemplo, volta a tentar entregas falhadas durante até três dias no modo ativo, enquanto o GitHub não tenta novamente automaticamente e espera que volte a enviar. Consulte a documentação de cada fornecedor e desenhe o seu handler para lidar com eventos atrasados ou repetidos.