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.

``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()estripe.webhooks.constructEventantes de qualquer coisa- Segredo de webhook certo para cada ambiente
- Service role key só no servidor
- ID do usuário em
client_reference_idoumetadata - Tabela de
event.idpara idempotência - Resposta rápida e só os eventos necessários
- Transparência: você faz parte do time do Massvai (massvai.com)
--