Webhook de teste do Stripe: teste pagamentos localmente com a CLI

Como rodar um webhook de teste do Stripe localmente com a Stripe CLI: stripe listen, stripe trigger, falhas, eventos duplicados e a saída do construtor de IA.

Illustration of payment events routed through a listener into a local laptop, depicting a Stripe test webhook setup
Nesta página · 7 seções
  1. Como envio um webhook de teste no Stripe?
  2. Como uso o stripe listen para encaminhar eventos para o localhost?
  3. Como disparo eventos específicos com a Stripe CLI?
  4. Quais casos de falha devo testar antes do lançamento?
  5. Como testo eventos duplicados e fora de ordem?
  6. Como testo depois de sair do construtor?
  7. Quer um segundo par de olhos?

Principais pontos

  • Use o modo de teste do Stripe e a Stripe CLI; nunca teste com chaves de produção ou cartões reais.
  • stripe listen –forward-to envia eventos para o seu endpoint local e mostra um segredo de assinatura válido só para aquela sessão.
  • stripe trigger cria eventos de exemplo, mas o seu fluxo real de checkout é um teste melhor da sua própria lógica de negócio.
  • Teste falhas, duplicatas e entregas fora de ordem, não só o caminho feliz.
  • Algumas verificações focadas encontram a maior parte do risco; corrigir bugs de pagamento custa mais depois que usuários e pagamentos reais chegam.

O jeito mais rápido de rodar um webhook de teste do Stripe é com a Stripe CLI. Você faz login, roda stripe listen para encaminhar eventos do modo de teste do Stripe para uma URL local e depois roda stripe trigger para disparar eventos de exemplo. O seu app recebe requisições reais e assinadas sem nenhum deploy.

Isso importa principalmente para apps construídos com ferramentas de IA como Lovable, Bolt ou Base44, em que o fluxo de pagamento costuma parecer ótimo numa demo, mas nunca enfrentou um cartão recusado, uma nova tentativa ou um evento duplicado. Sou engenheiro brasileiro, e esta é a rotina que uso antes de qualquer dinheiro real passar por um app.

Como envio um webhook de teste no Stripe?

Você tem três opções, e elas testam coisas diferentes.

  • Stripe CLI: a melhor para desenvolvimento local. Ela encaminha eventos para o localhost e permite dispará-los pelo terminal.
  • Event destinations no dashboard: no modo de teste, você pode apontar o Stripe para uma URL pública e enviar um evento de teste pelo dashboard. Útil para um deploy de staging.
  • Ações reais no modo de teste: concluir um Checkout com um cartão de teste gera exatamente a sequência de eventos que o seu app vai receber em produção.

No dia a dia, combino a primeira e a terceira. A CLI dá feedback rápido, e um checkout de teste real confirma a cadeia inteira: o seu frontend, o seu servidor, o Stripe e a volta para o seu banco de dados.

Como uso o stripe listen para encaminhar eventos para o localhost?

Instale a Stripe CLI e autentique com stripe login. Ela abre o navegador para vincular a CLI à sua conta. Confirme que você está trabalhando no modo de teste.

Suba o seu app localmente e então rode:

  1. stripe listen –forward-to localhost:3000/api/stripe/webhook (use a sua própria porta e o seu caminho).
  2. Copie o segredo de assinatura que a CLI mostra. Ele começa com whsec_.
  3. Coloque esse valor na sua variável de ambiente local do segredo do webhook.
  4. Reinicie o app para que ele leia o novo valor.

O erro mais comum que vejo é usar localmente o segredo do endpoint do dashboard. A sessão da CLI tem o próprio segredo, então a verificação da assinatura falha com um erro confuso. Se o seu handler retorna 400 em todos os eventos, verifique isso primeiro.

Confirme também que o seu handler verifica a assinatura usando o corpo bruto da requisição. Frameworks que fazem o parse do JSON antes de o seu código ver o corpo quebram a verificação. Isso é um problema do código, não do Stripe.

Duas janelas de terminal lado a lado em um notebook, uma delas encaminhando eventos de webhook de teste do Stripe para um servidor local
Um terminal encaminha os eventos, o outro roda o seu app.

Como disparo eventos específicos com a Stripe CLI?

Com o listener rodando, abra um segundo terminal e rode stripe trigger seguido do nome de um evento. Os mais comuns para um app de pagamentos:

  • checkout.session.completed
  • payment_intent.succeeded
  • payment_intent.payment_failed
  • invoice.paid e invoice.payment_failed
  • customer.subscription.deleted

Acompanhe a saída do listener. Cada linha mostra o evento e o status HTTP que o seu endpoint retornou. Você quer 200 para os eventos tratados, e quer ver também os seus próprios logs e as mudanças no banco de dados.

Uma ressalva: os eventos disparados usam dados de fixture gerados. Eles não vão conter o ID do seu cliente, o ID do seu pedido nem os seus metadados. Então um trigger prova que o seu endpoint recebe e verifica eventos, mas pode não provar que a sua lógica de pedidos funciona. Para isso, faça um checkout de teste real com o cartão 4242 4242 4242 4242 e deixe a CLI encaminhar os eventos resultantes.

Quais casos de falha devo testar antes do lançamento?

Apps construídos com IA normalmente tratam o caso de sucesso. É nas falhas que dinheiro e dados se perdem. Esta é a lista que eu percorro.

CasoComo testarO que você deve ver
Cartão recusadoCartão de teste 4000 0000 0000 0002Nenhum acesso liberado, o usuário vê um erro claro
Assinatura inválidaEnvie uma requisição com o segredo erradoResposta 400, nada é gravado
Crash no handlerLance um erro no seu handlerResposta 500, o Stripe tenta de novo mais tarde
Tipo de evento desconhecidoDispare um evento que você não trataResposta 200, evento ignorado com segurança
Checkout abandonadoFeche a página antes de pagarNenhum pedido pago é criado

A regra principal: o seu app só deve liberar acesso ou marcar um pedido como pago depois que um webhook verificado confirmar o pagamento, e não porque o navegador chegou a uma página de sucesso. Qualquer pessoa pode abrir uma URL de sucesso manualmente. Um scanner de segurança genérico não vai pegar isso, porque é lógica de negócio, não um padrão de vulnerabilidade conhecido.

Verifique também se os erros retornam um status diferente de 2xx. Se o seu handler engole uma exceção e retorna 200, o Stripe entende que o evento foi tratado e não tenta de novo, e você perde o registro do pagamento sem perceber.

Como testo eventos duplicados e fora de ordem?

O Stripe pode entregar o mesmo evento mais de uma vez e não garante a ordem. O seu handler precisa sobreviver às duas coisas.

Duplicatas

Use stripe events resend com um ID de evento do seu dashboard de teste para entregar o mesmo evento de novo. O seu app não deve criar um segundo pedido, enviar um segundo email nem estender uma assinatura duas vezes. A correção de costume é guardar os IDs dos eventos processados numa tabela com uma constraint de unicidade e pular os que você já viu. Melhor ainda: torne a atualização em si idempotente, por exemplo definindo o status de um pedido como pago em vez de incrementar um contador.

Fora de ordem

Você pode receber invoice.paid antes de checkout.session.completed, ou uma atualização de assinatura antes de o registro existir. Teste reenviando eventos em outra ordem, ou apagando temporariamente a linha relacionada e reenviando. Um handler robusto ou busca o objeto atual na API do Stripe, ou falha com 500 para que o Stripe tente de novo mais tarde.

Envelopes embaralhados e duplicados chegando a uma mesa, representando eventos de webhook do Stripe fora de ordem e duplicados
Eventos podem chegar duas vezes e na ordem errada.

Concorrência

Se duas cópias chegam quase no mesmo instante, um padrão de verificar e depois inserir ainda pode criar duplicatas. Quem realmente protege você é a constraint de unicidade no banco de dados, então confie nela, e não só no código da aplicação.

Como testo depois de sair do construtor?

Código construído no Lovable pode ser levado para o GitHub e para a sua própria hospedagem. Quando você faz isso, a configuração do webhook muda, e esse é um ponto comum em que pagamentos quebram em silêncio.

  1. Registre um novo endpoint no Stripe para a nova URL pública, primeiro no modo de teste.
  2. Use o segredo do novo endpoint nas variáveis de ambiente da nova hospedagem. Não reaproveite o segredo da CLI nem um antigo.
  3. Verifique onde o código roda no servidor. Se os webhooks rodavam numa função gerenciada pelo construtor, confirme que a mesma lógica agora existe no seu próprio backend.
  4. Faça um checkout de teste completo na URL de staging publicada e confirme que a linha do banco de dados muda.
  5. Repita no modo de produção com um pagamento real pequeno que você reembolsa depois, quando tudo estiver passando.

Remova o endpoint antigo no Stripe quando terminar, para que os eventos não sejam enviados para dois lugares. Continuar no construtor às vezes é a melhor decisão, principalmente para um app simples com pouco tráfego. Mas, se você migrar, trate o webhook como a primeira coisa a testar de novo, porque o dono do app é responsável pela confirmação do pagamento mesmo quando a plataforma cuida da infraestrutura.

Corrija o código existente antes de considerar uma reescrita. Quando reviso um fluxo de pagamento, começo procurando correções pontuais no código existente antes de qualquer coisa maior.

Quer um segundo par de olhos?

Se você quer uma segunda opinião sobre o seu handler de webhook ou o seu fluxo de pagamento, mande um email para me@filipeeduardo.dev com uma descrição do seu setup, e eu digo o que verificaria primeiro.

Perguntas frequentes

Preciso de uma URL pública para testar um webhook do Stripe?

Não. A Stripe CLI encaminha eventos do Stripe para o localhost, então você pode testar sem fazer deploy e sem usar uma ferramenta de túnel.

Por que o meu webhook local retorna erro de assinatura?

Normalmente o segredo está errado ou o corpo foi parseado antes da verificação. Use o valor whsec_ mostrado pelo stripe listen e verifique usando o corpo bruto.

O stripe trigger cria os meus pedidos reais?

Não. Ele cria objetos de fixture genéricos, sem os seus metadados. Use um checkout de teste real para exercitar a sua própria lógica de pedidos.

Posso reenviar um evento que já recebi?

Sim. Use stripe events resend com o ID do evento, ou reenvie pelo dashboard no modo de teste, para verificar o tratamento de duplicatas.

O modo de teste basta antes do lançamento?

Ele cobre a maior parte da lógica, mas faça um pagamento pequeno no modo de produção depois do deploy para confirmar que as chaves de produção e o segredo do endpoint de produção estão configurados corretamente.

stripe test webhook

Filipe Eduardo

Engenheiro de Software Sênior. Sete anos construindo produtos web e mobile de ponta a ponta e liderando os times que os entregam.

Acompanhe

Quer conversar
sobre isso?

Trabalho com problemas assim todos os dias. Me conte o seu.

Fale comigo