Todos os artigos

Ferramentas · 25 de julho de 2026 · 10 min de leitura

Como testar webhooks em localhost: túneis, inspeção e ferramentas

Você configurou o webhook no painel do provedor, apontou para http://localhost:3000 e… nada chegou. Não é bug: é rede. Provedores entregam webhooks pela internet, e o seu localhost simplesmente não existe para ela. Neste guia, comparamos as quatro estratégias para testar webhooks durante o desenvolvimento — endpoints de inspeção, túneis, CLIs oficiais e encaminhamento — e em que cenário cada uma é a escolha certa.

Por que o provedor não enxerga o seu localhost

Quando um provedor dispara um webhook, ele age como um cliente HTTP comum: resolve o endereço que você cadastrou e abre uma conexão até ele. Se esse endereço é localhost (ou 127.0.0.1), cada máquina o resolve para si mesma — para o servidor do provedor, "localhost" é o próprio servidor do provedor, não a sua máquina de desenvolvimento.

E cadastrar o IP da sua máquina também não resolve. Na maioria das redes, você está atrás de NAT: o roteador compartilha um único IP público entre todos os dispositivos e não sabe para qual deles encaminhar uma conexão que chega de fora. Somam-se a isso firewalls que bloqueiam conexões de entrada e IPs residenciais dinâmicos que mudam sem aviso. O resultado é que não existe rota da internet até o processo rodando na sua porta 3000.

Para receber uma entrega de verdade, você precisa de uma URL pública com HTTPS. As estratégias abaixo são, no fundo, quatro maneiras diferentes de conseguir uma — cada uma com trade-offs próprios. (Se o conceito de webhook em si ainda está nebuloso, vale começar pelo guia definitivo sobre webhooks e voltar aqui depois.)

Estratégia 1 — Capture antes de codar: endpoints de inspeção

Antes de escrever qualquer handler, vale a pena ver o que o provedor realmente envia. Um endpoint de inspeção é uma URL temporária que aceita qualquer requisição e exibe tudo o que chegou — método, headers, query string e body formatado — direto no navegador, sem que você suba servidor nenhum. Ferramentas como SafeHook, webhook.site e Beeceptor fazem isso em segundos: você copia a URL gerada, cadastra no provedor, dispara um evento de teste e examina a entrega real.

Esse passo parece dispensável, mas evita um erro clássico: codar contra a documentação e descobrir em produção que o payload real é diferente. Documentação atrasa; o payload que chega no endpoint de inspeção não mente. Ao examinar a captura, preste atenção em:

  • Headers de assinatura e identificação — o nome exato do header (cada provedor usa o seu), o formato do valor e se existe um ID de entrega para deduplicação.
  • Content-type real — a maioria envia application/json, mas alguns usam application/x-www-form-urlencoded ou até XML.
  • O envelope do evento — onde ficam o tipo do evento, o ID e os dados em si; alguns provedores mandam o objeto completo, outros só uma referência para você consultar a API.

Estratégia 2 — Túneis: exponha o seu localhost

Um túnel inverte a direção do problema. Em vez de esperar uma conexão de entrada (que o NAT bloqueia), um agente na sua máquina abre uma conexão de saída até um servidor público — e conexões de saída atravessam NAT e firewall sem drama. O servidor público recebe as requisições na URL que ele te deu e as despacha pelo túnel até o seu processo local. Para o provedor de webhooks, você é um servidor normal na internet.

ngrok

O ngrok é o túnel mais conhecido. Um comando expõe a porta do seu app:

terminal
$ ngrok http 3000

Forwarding  https://a1b2-203-0-113-7.ngrok-free.app -> http://localhost:3000

Cadastre a URL https://…ngrok-free.app/webhooks no provedor e as entregas passam a chegar no seu handler local. O ngrok ainda oferece um painel local em http://127.0.0.1:4040 que registra cada requisição e permite replay — reenvia a mesma entrega sem você precisar disparar o evento de novo no provedor. A limitação do plano gratuito: a URL é aleatória e muda a cada execução, obrigando a recadastrar o webhook no painel do provedor toda vez que você reinicia o túnel; domínio fixo é recurso pago.

Cloudflare Tunnel

O cloudflared faz o mesmo papel, com "quick tunnels" gratuitos que nem exigem conta:

terminal
$ cloudflared tunnel --url http://localhost:3000

https://random-words-here.trycloudflare.com

Com uma conta Cloudflare e um domínio próprio, dá para criar túneis nomeados com URL estável — resolvendo o problema da URL que muda, de graça, ao custo de um setup inicial um pouco maior.

Outras opções

  • localtunnelnpx localtunnel --port 3000, sem instalação; simples, porém menos estável para uso contínuo.
  • Tailscale Funnel — excelente se a sua equipe já usa Tailscale; expõe um serviço da sua tailnet para a internet com URL estável.
  • Dev tunnels do VS Code — o port forwarding embutido no editor serve para testes rápidos sem ferramenta extra.

Estratégia 3 — CLIs oficiais: eventos reais sem expor nada

Alguns provedores resolvem o problema na raiz com uma CLI que se conecta à sua conta e encaminha os eventos para o localhost por uma conexão de saída — sem URL pública, sem túnel, sem recadastrar nada. A Stripe CLI é o exemplo canônico:

terminal
$ stripe listen --forward-to localhost:3000/webhooks
> Ready! Your webhook signing secret is whsec_xxxxxxxxxxxxx

# em outro terminal, dispare um evento de teste:
$ stripe trigger payment_intent.succeeded

Repare no detalhe importante: o stripe listen imprime um signing secret local. As entregas encaminhadas vêm assinadas com ele, o que permite testar a validação de assinatura de verdade durante o desenvolvimento. O GitHub tem equivalente via extensão da CLI oficial:

terminal
$ gh webhook forward --repo=sua-org/seu-repo --events=push \
    --url=http://localhost:3000/webhooks

Quando o provedor oferece uma CLI assim, ela costuma ser a melhor opção para o dia a dia: eventos reais, assinatura verificável, zero exposição da sua máquina e nenhuma URL para recadastrar. A limitação é óbvia — nem todo provedor tem. Stripe e GitHub, sim; a maioria dos gateways brasileiros, por exemplo, não.

Estratégia 4 — Encaminhamento a partir de uma URL pública estável

As estratégias anteriores têm um atrito em comum: a URL cadastrada no provedor aponta para algo efêmero (um túnel que morre, uma captura temporária). A quarta abordagem inverte isso: você cadastra no provedor uma URL pública persistente — um endpoint de captura/relay que é seu e não muda — e é dela que os eventos são encaminhados para onde você precisa: seu localhost durante o desenvolvimento, um ambiente de staging, ou os dois.

Isso é especialmente útil em equipe: todos compartilham o mesmo endpoint cadastrado no provedor, e cada pessoa puxa os eventos para a própria máquina quando está trabalhando na integração. Algumas ferramentas de inspeção oferecem esse forwarding embutido; também dá para montar um relay próprio minimalista num VPS — um handler de vinte linhas que recebe, loga e repassa via HTTP para um destino configurável.

O cuidado aqui é lembrar que o relay vira infraestrutura: se ele cair, as entregas passam a falhar e ficam acumuladas nos retries do provedor. Para desenvolvimento isso é tolerável; se a mesma peça for parar em produção, trate-a com o rigor de produção.

Simulando entregas com curl

Nada impede você de imitar o provedor na sua própria máquina. Capture um payload real (com um endpoint de inspeção, por exemplo), salve como fixture e dispare contra o handler local:

terminal
$ curl -X POST http://localhost:3000/webhooks \
    -H "Content-Type: application/json" \
    -H "X-Event-Id: evt_teste_001" \
    -d '{"type":"payment.approved","data":{"payment_id":"pay_123","amount":14990}}'

É a forma mais rápida de testar roteamento, parsing e regras de negócio — e a única que roda offline e cabe num teste automatizado de CI. A limitação: o curl não sabe assinar a requisição como o provedor assina. Para exercitar a validação de assinatura você precisa ou computar o HMAC do corpo com um segredo de teste no próprio script, ou usar uma entrega real via túnel/CLI. O mecanismo completo de assinatura está destrinchado em Segurança de webhooks: assinatura HMAC e boas práticas.

Qual estratégia usar?

Não existe vencedor único — existe a ferramenta certa para cada momento do fluxo de trabalho:

CenárioMelhor estratégiaPor quê
Explorar o payload antes de codarEndpoint de inspeçãoZero setup; mostra headers e body reais sem escrever código
Desenvolver o handler com eventos reaisCLI oficial (se existir) ou túnelEntregas de verdade chegando no seu processo local, com replay
Testar validação de assinaturaCLI oficial ou túnelSão os únicos caminhos com entregas assinadas de verdade
URL estável para a equipe ou stagingEncaminhamento persistenteCadastra uma vez no provedor; cada destino puxa os eventos
Testes automatizados / CIcurl + fixtures de payloads reaisReprodutível, offline e rápido; assine o corpo você mesmo se necessário

Resumo

  • Localhost não é alcançável da internet por causa de NAT, firewall e IP dinâmico — testar webhook exige uma URL pública HTTPS, e cada estratégia é um jeito de obter uma.
  • Comece por um endpoint de inspeção para ver o payload real antes de escrever o handler.
  • Para desenvolver, prefira a CLI oficial do provedor quando existir; na falta dela, um túnel (ngrok, cloudflared) resolve — lembrando que a URL gratuita muda a cada sessão.
  • Encaminhamento a partir de uma URL persistente elimina o recadastro e funciona bem em equipe; curl com fixtures cobre testes automatizados.
  • Em qualquer caminho: use dados de sandbox em ferramentas de terceiros e valide assinatura até em dev.