Como Adicionar Assinaturas com Stripe: Planos, Testes Grátis, Webhooks e Pagamentos Recusados
Para adicionar assinaturas com a Stripe, crie um produto com preço recorrente no Painel da Stripe, envie os clientes para o Stripe Checkout no modo assinatura a partir do seu servidor e deixe um webhook avisar o seu app quando cada pagamento for bem-sucedido, falhar, mudar ou terminar. Guarde o status da assinatura junto ao usuário e libere o acesso com base nele, não na página de sucesso. Adicione um botão Gerenciar cobrança que abre o portal do cliente hospedado pela Stripe, para que as pessoas possam trocar o cartão, mudar de plano e cancelar sem que você precise construir essas telas.
Este guia se apoia em como adicionar pagamentos ao seu app, que cobre o Checkout de pagamento único, o modo de teste e a entrada em produção. Aqui focamos no que é diferente na cobrança recorrente. Os detalhes da Stripe vêm da documentação oficial da empresa em setembro de 2026.
Por que assinaturas são mais difíceis do que pagamentos únicos
Um pagamento único acontece enquanto o cliente está no seu app. Uma assinatura continua acontecendo depois que ele sai: renovações todo mês, cartões que vencem, upgrades no meio do ciclo, cancelamentos que valem só no fim do período. O seu app fica sabendo disso apenas por webhooks. A maioria dos bugs de assinatura vem de tratar o primeiro pagamento como se fosse a história inteira.
Suas opções
| Abordagem | O que você constrói | Ideal para |
|---|---|---|
| Payment Link com preço recorrente | Nada além de um link | Testar demanda; liberar acesso manualmente |
| Checkout (modo assinatura) + portal do cliente | Uma rota no servidor, um webhook, um botão de cobrança | A maioria dos apps SaaS e associações |
| API de assinaturas com formulário de pagamento próprio | Bem mais: interface de pagamento, autenticação, novas tentativas | Apps com fluxos de cobrança incomuns |
| Provedor merchant of record | Semelhante ao Checkout | Vendedores que querem que o provedor cuide do imposto sobre vendas |
Para a maioria dos apps, o Checkout mais o portal é o equilíbrio certo. Compare os provedores em Stripe vs. Paddle vs. Lemon Squeezy se o tratamento de impostos for uma preocupação.
Planeje seus preços na Stripe primeiro
Na Stripe, um produto é o que você vende ("Plano Pro") e um preço é como você cobra por ele ("R$ 99 por mês", "R$ 990 por ano"). Um produto pode ter vários preços. Defina:
- Quais níveis você oferece e o que cada um libera no seu app
- Mensal, anual ou os dois
- Se oferece período de teste, e se ele exige cartão logo no início
Crie os produtos e os preços no modo de teste e guarde os IDs de preço; o seu app faz referência a eles. Se você ainda não definiu os preços, leia como precificar um produto SaaS e freemium vs. período de teste grátis.
O ciclo de vida da assinatura que você precisa tratar
A visão geral de assinaturas da Stripe lista os status que uma assinatura pode ter. Os mais importantes para o acesso:
| Status | O que significa | Liberar acesso? |
|---|---|---|
trialing | Em período de teste | Sim |
active | Em dia | Sim |
incomplete | O primeiro pagamento ainda não foi concluído; a Stripe dá ao cliente 23 horas | Não |
incomplete_expired | O primeiro pagamento nunca foi bem-sucedido | Não |
past_due | O último pagamento falhou ou não foi tentado; novas tentativas podem acontecer | Sua escolha; muitos apps dão um pequeno período de tolerância |
unpaid | As tentativas terminaram, as faturas continuam abertas, sem novas tentativas | Não; a documentação da Stripe recomenda revogar o acesso |
canceled | Encerrada; não pode ser reiniciada | Não |
paused | Um período de teste terminou sem forma de pagamento e foi configurado para pausar | Não |
Guarde o status no registro do usuário ou da conta e baseie o acesso nele. Atualize-o toda vez que um webhook relevante chegar.
Os eventos de webhook a tratar
| Evento | O que o seu app faz |
|---|---|
checkout.session.completed | Vincula os IDs de cliente e de assinatura da Stripe ao seu usuário |
invoice.paid | Marca a assinatura como ativa e registra o novo fim do período |
invoice.payment_failed | Avisa o usuário que o cartão falhou e traz um link para o portal |
invoice.payment_action_required | Pede ao usuário que conclua a autenticação do cartão |
customer.subscription.updated | Atualiza plano, status e qualquer cancelamento agendado |
customer.subscription.deleted | Remove o acesso pago |
customer.subscription.trial_will_end | Lembra o usuário antes do fim do teste; a Stripe envia três dias antes |
As regras de manipulação de webhook da documentação da Stripe continuam valendo: verifique a assinatura usando o corpo bruto, responda 2xx rapidamente, trate eventos duplicados e fora de ordem, e espere reenvios. O guia o que é um webhook explica a ideia, e o guia de pagamentos lista as regras em detalhes.
Passo a passo
- Crie produtos e preços no modo de teste da Stripe.
- Adicione os segredos: a chave secreta, os IDs de preço e, depois, o segredo de assinatura do webhook. Nunca os coloque no código do frontend.
- Página de preços: o botão de cada plano chama o seu servidor, que cria uma Checkout Session no modo assinatura para o usuário logado. Passe o ID do seu usuário para que o webhook consiga vincular o pagamento à conta.
- Endpoint de webhook: verifique as assinaturas e trate os eventos acima, atualizando um registro de assinatura por usuário.
- Controle os recursos pelo status e plano guardados, verificados no servidor em cada ação protegida, não apenas em botões escondidos.
- Portal do cliente: configure-o no Painel da Stripe (quais planos as pessoas podem escolher, se podem cancelar), depois adicione um botão Gerenciar cobrança que cria uma sessão do portal no servidor e redireciona para ele.
- Pagamentos recusados: nas configurações de cobrança da Stripe, escolha o comportamento de novas tentativas e o que acontece depois da última. Mostre um aviso no app enquanto estiver
past_due. - Teste o ciclo de vida inteiro, depois publique e registre o webhook de produção.
Prompts para dar ao seu construtor de IA
Adicione cobrança por assinatura com a Stripe. Planos: Starter (ID de preço em STRIPE_PRICE_STARTER) e Pro (STRIPE_PRICE_PRO). A página de preços cria uma Checkout Session no modo assinatura no servidor, usando STRIPE_SECRET_KEY, com o ID do usuário logado anexado. Salve no usuário o ID de cliente da Stripe, o ID da assinatura, o plano e o status. Nunca exponha a chave secreta ao navegador.
Adicione POST /api/stripe/webhook. Verifique a assinatura com STRIPE_WEBHOOK_SECRET usando o corpo bruto da requisição. Trate checkout.session.completed, invoice.paid, invoice.payment_failed, customer.subscription.updated, customer.subscription.deleted e customer.subscription.trial_will_end. Registre os IDs de eventos já processados para que duplicatas sejam ignoradas. Atualize o status do usuário a partir do objeto da assinatura, não da ordem em que os eventos chegam.
Libere os recursos Pro no servidor: permita-os somente quando o status for active ou trialing e o plano for Pro. Mostre o aviso "pagamento recusado, atualize seu cartão" quando o status for past_due. Adicione um botão Gerenciar cobrança que abre o portal do cliente da Stripe para este usuário.
Upgrades, downgrades e proporcional
Quando um cliente troca de plano, a documentação da Stripe diz que a mudança costuma gerar um ajuste proporcional (proration): o novo preço é aplicado ao restante do período de cobrança atual. Você pode visualizar esses ajustes ou desligá-los. Se os planos tiverem o mesmo intervalo, as datas de cobrança permanecem as mesmas; ao mudar de mensal para anual, a data de cobrança passa para o dia da troca. Deixar o cliente trocar de plano no portal poupa você de escrever essa lógica, mas defina nas configurações do portal quais trocas são permitidas.
Checklist de testes
Use o modo de teste da Stripe e cartões de teste, e percorra cada estado:
- Uma nova assinatura libera o plano certo para o usuário certo
- Fechar a aba logo depois de pagar ainda libera o acesso (prova que o webhook funciona)
- Um cartão recusado no cadastro não libera nada
- Uma renovação que falha coloca a conta em past_due e mostra o aviso
- Atualizar o cartão no portal restaura o status active
- Upgrades e downgrades mudam os recursos corretamente
- Cancelar ao fim do período mantém o acesso até a data final, e depois o remove
- Usuários em teste recebem acesso, recebem o lembrete e convertem ou perdem o acesso corretamente
- Enviar o mesmo evento de webhook duas vezes não altera nada
Os relógios de teste da Stripe permitem simular a passagem do tempo, para testar renovações sem esperar um mês. Consulte a documentação atual de testes da Stripe para saber como usá-los.
Erros comuns
- Liberar acesso na página de sucesso. Os clientes podem pagar e nunca chegar a ela. Use o webhook.
- Tratar só o primeiro pagamento. Renovações, falhas e cancelamentos chegam depois, como eventos.
- Verificar o status do plano só no frontend. Qualquer pessoa pode chamar a sua API diretamente.
- Um usuário, várias assinaturas por acidente. Verifique se já existe uma assinatura antes de criar uma nova Checkout Session, ou envie os clientes existentes para o portal.
- Revogar o acesso na primeira renovação falha. Cartões falham por motivos banais. Um período de tolerância curto com um aviso claro mantém os clientes.
- Esquecer o webhook de produção. Os endpoints de teste e de produção têm segredos de assinatura diferentes.
- Ignorar impostos e reembolsos. Defina sua política de reembolso e confira suas obrigações tributárias com um contador antes do lançamento.
Assinaturas no Mythex
Os apps que você cria no Mythex usam a sua própria conta e as suas chaves da Stripe; não existe uma conexão com a Stripe de um clique para o seu app. Adicione suas chaves de teste e os IDs de preço como segredos do projeto, use prompts como os acima e teste com os cartões de teste da Stripe no Preview. Os webhooks precisam da URL pública do seu app, então publique antes de registrar o endpoint na Stripe, e publique novamente depois de trocar para as chaves de produção, para que o app em produção as utilize. Veja Aceitar pagamentos com Stripe e Tratar webhooks no seu backend. Para o produto como um todo, como criar um MVP de SaaS cobre o que construir ao redor da cobrança.
Perguntas
Qual é a forma mais simples de adicionar assinaturas com a Stripe?
Crie um produto com um preço recorrente no Painel da Stripe, envie os clientes para o Stripe Checkout no modo assinatura, trate os eventos da assinatura com um webhook e vincule um botão Gerenciar cobrança ao portal do cliente hospedado pela Stripe. Assim você evita construir formulários de cartão e telas de troca de plano.
Quais eventos de webhook da Stripe preciso para assinaturas?
No mínimo, checkout.session.completed para vincular a nova assinatura ao seu usuário, invoice.paid para confirmar cada pagamento bem-sucedido, invoice.payment_failed para avisar sobre renovações recusadas, e customer.subscription.updated e customer.subscription.deleted para acompanhar mudanças de plano e cancelamentos.
O que acontece quando um pagamento de assinatura falha?
Segundo a documentação da Stripe em setembro de 2026, a assinatura normalmente fica como past_due, e a Stripe pode tentar o pagamento de novo conforme as suas configurações. Depois da última tentativa, as configurações do seu Painel decidem se ela é cancelada, marcada como não paga ou mantida como past_due.
Posso oferecer um período de teste grátis sem pedir cartão?
Sim. A Stripe oferece suporte a períodos de teste grátis, e a documentação descreve um status paused para testes que terminam sem forma de pagamento, quando configurado assim. Pedir o cartão logo no início costuma significar menos cadastros, mas mais clientes pagantes; teste o que combina com o seu produto.