Erro 1: Ler o Corpo como JSON Antes de Verificar a Assinatura

Em vez de chamar req.json() primeiro, você deve ler o corpo bruto do pedido. Isso garante que a assinatura do Stripe seja verificada corretamente.

6 Erros Comuns ao Usar Webhooks do Stripe no Next.js (App Router) com Supabase

``ts
const body = await req.text();
let event: Stripe.Event
try {
event = stripe.webhooks.constructEvent(body, sig, process.env.STRIPE_WEBHOOK_SECRET!);
} catch {
return new Response('assinatura inválida', { status: 400 });
}
return new Response('ok');
``

Erro 2: Usar o Segredo do Webhook Errado

O STRIPE_WEBHOOK_SECRET do seu projeto pode ser diferente do que está configurado no painel do Stripe. Certifique-se de configurar corretamente para cada ambiente (Preview e Production) e faça um novo deploy após alterar as variáveis.

Erro 3: Gravar no Supabase com a Chave Anon

O webhook não tem um usuário logado, então as políticas de RLS bloqueiam a escrita feita com a chave anon. Use um cliente com a service role key, criado só no servidor e nunca exposto ao navegador.

Erro 4: Não Saber a Qual Usuário Pertence o Pagamento

Sem um vínculo, o webhook recebe um customer que o seu banco não conhece. Ao criar a sessão de checkout, passe o ID do usuário do Supabase em client_reference_id ou metadata, e guarde o customer do Stripe na tabela de perfis. No webhook, procure pelo ID que você mesmo enviou.

Erro 5: Processar o Mesmo Evento Duas Vezes

O Stripe pode reenviar um evento. Se cada entrega cria um crédito novo, o cliente ganha em dobro. Guarde o event.id numa tabela com chave única e ignore o que já foi processado.

Erro 6: Demorar para Responder

Se o handler faz muita coisa antes de responder (e-mails, chamadas externas), ele pode estourar o tempo da função e o Stripe registra falha. Responda rápido, grave o essencial e deixe o trabalho pesado para depois. E escute só os eventos que você usa, como checkout.session.completed, customer.subscription.updated e customer.subscription.deleted.

Checklist

  • req.text() e stripe.webhooks.constructEvent antes de qualquer coisa
  • Segredo de webhook certo para cada ambiente
  • Service role key só no servidor
  • ID do usuário em client_reference_id ou metadata
  • Tabela de event.id para idempotência
  • Resposta rápida e só os eventos necessários
  • Transparência: você faz parte do time do Massvai (massvai.com)

--

Erros Next Stripe Supabase Webhooks