Para adicionar pagamentos Stripe a uma app criada com IA, escolha o produto Stripe que corresponde ao que vende (um Payment Link, o Checkout, ou o Checkout com subscrição), mantenha a chave secreta do Stripe no servidor, numa edge function, e deixe que seja um webhook, e não a página de sucesso, a escrever o estado de pagamento na base de dados. Depois teste tudo no modo de teste do Stripe antes de passar a produção. Um criador de apps com IA pode escrever todo o código, mas precisa que estas decisões lhe sejam explicadas, um passo de cada vez.
Este guia cobre as três opções do Stripe, a configuração no servidor, o webhook, o portal do cliente, os testes e os prompts exatos a enviar. Para o contexto mais amplo de construir a própria app, veja o nosso guia para criar uma app com IA.
Payment Links, Checkout ou subscrições: qual escolher
Use um Payment Link quando vende algo simples e a sua app não precisa de reagir em tempo real, use o Checkout quando é a sua app que decide o que cobrar e quem paga, e use uma sessão Checkout em modo de subscrição quando o acesso depende de um plano recorrente. Segundo a documentação dos Payment Links do Stripe, um Payment Link é uma página alojada pelo Stripe que cria sem código e partilha por ligação, código QR ou um botão de compra incorporável. Pode vender um produto, uma subscrição ou aceitar donativos, com personalização visual limitada.
O Checkout é o mesmo tipo de página de pagamento, mas é o seu código que a cria através da API Checkout Sessions, como descreve a documentação do Checkout do Stripe. É isso que permite à sua app associar o pagamento a um utilizador com sessão iniciada, escolher o preço a partir da sua base de dados e devolver o cliente ao ecrã certo. O Checkout pode ser uma página alojada pelo Stripe ou um formulário incorporado no seu site.
| Opção | Código necessário | Sabe que utilizador pagou | Ideal para | Principal limite |
|---|---|---|---|---|
| Payment Link | Nenhum para o criar | Só ao cruzar o email ou um parâmetro do URL depois | Uma primeira venda, um produto único, um donativo, uma pré-venda | Personalização limitada; a sua app fica de fora, a menos que acrescente um webhook |
| Checkout (pagamento único) | Uma função no servidor | Sim, passa o id do utilizador ao criar a sessão | Compra de créditos, um relatório pago, um sinal de reserva | Tem de manter a função e o webhook |
| Checkout (modo subscrição) | Uma função no servidor e tratamento de webhooks | Sim | Planos SaaS, associações, tudo o que é cobrado todos os meses ou anos | Renovações, pagamentos falhados e cancelamentos chegam mais tarde e têm de ser tratados |
A chave secreta nunca vai para o navegador
A chave secreta do Stripe só pode viver num servidor, porque quem a tiver pode criar cobranças, emitir reembolsos e ler dados de clientes. Tudo o que o navegador precisa é de um URL de Checkout de curta duração que o seu servidor devolve depois de chamar o Stripe. Um criador de apps com IA que coloque a chave secreta num ficheiro React tornou a app insegura, e é a primeira coisa a verificar em qualquer código de pagamento gerado.
O padrão habitual é uma edge function, um pequeno pedaço de código de servidor que corre junto da sua base de dados. O navegador chama-a com o login do utilizador, a função verifica quem é o utilizador, cria a sessão de Checkout com a chave secreta e devolve o URL. A própria chave fica guardada numa variável de ambiente, nunca no código. O nosso guia sobre segurança do vibe coding lista as outras verificações que vale a pena fazer ao código gerado.
Porque a base de dados é atualizada pelo webhook e não pela página de sucesso
Marque uma encomenda como paga apenas quando o Stripe o comunica ao seu servidor através de um webhook, nunca quando o cliente chega à página de sucesso. A página de sucesso é apenas um separador do navegador: pode ser fechada antes de carregar, aberta por alguém que escreveu o endereço, ou nunca ser alcançada porque a ligação do cliente caiu depois de pagar. Um webhook é o Stripe a chamar diretamente o seu servidor, e a documentação de webhooks do Stripe descreve-o como a forma de reagir a eventos assíncronos, como um banco a confirmar um pagamento, uma contestação ou um pagamento recorrente bem-sucedido.
Um tratador de webhooks precisa de quatro propriedades:
- Verifica a assinatura. Cada pedido traz um cabeçalho
Stripe-Signature. O tratador verifica-o com o segredo do seu endpoint, de modo que um desconhecido a enviar eventos "pago" falsos é rejeitado. O carimbo de data e hora dentro do cabeçalho também limita as repetições. - Responde depressa com um código de sucesso. O Stripe espera uma resposta 2xx. Em modo de produção, volta a tentar uma entrega falhada durante até três dias, com intervalos crescentes; em modo de teste, faz três tentativas ao longo de algumas horas.
- É seguro executá-lo duas vezes. Com as novas tentativas, o mesmo evento pode chegar mais do que uma vez. Guarde o id do evento, ou escreva o estado de modo que uma segunda execução dê o mesmo resultado.
- É acessível sem login de utilizador. O Stripe não é um utilizador com sessão iniciada na sua app, por isso esta função tem de aceitar pedidos sem a verificação de login habitual, e basear-se na assinatura.
O que guardar na base de dados
Guarde o id de cliente do Stripe, o id da subscrição, o plano e o estado da subscrição junto de cada utilizador, e atualize-os apenas a partir de eventos de webhook. A sua app lê então uma única linha local para decidir o que um utilizador pode fazer, sem chamar o Stripe em cada página. Para as subscrições, o guia de webhooks de subscrições do Stripe lista os eventos e estados a tratar:
| Sinal do Stripe | O que significa | O que a sua app faz |
|---|---|---|
invoice.paid | Uma fatura, incluindo uma renovação, foi paga | Conceder ou prolongar o acesso (o Stripe aconselha a confirmar primeiro que o estado da subscrição é ativo) |
invoice.payment_failed | Uma tentativa de pagamento falhou | Avisar o cliente e pedir-lhe que atualize o cartão |
customer.subscription.updated | O plano, a renovação ou o estado mudaram | Copiar o novo plano e estado para a sua tabela |
customer.subscription.deleted | A subscrição terminou | Retirar o acesso pago |
Estado past_due | O último pagamento falhou, o Stripe pode tentar de novo | Notificar o cliente; decidir durante quanto tempo manter o acesso |
Estado canceled ou unpaid | Já não paga | Revogar o acesso, segundo a orientação do Stripe |
Como os utilizadores leem o seu plano a partir desta tabela, ela precisa de row level security: um utilizador pode ler a sua própria linha e ninguém pode escrever nela a partir do navegador. Só a função do webhook, a correr com uma chave do lado do servidor, escreve. O nosso guia de Supabase row level security explica a política.
Deixe os clientes cancelar pelo portal do cliente
Use o portal do cliente do Stripe para cancelamentos, atualizações de cartão e faturas, em vez de construir esses ecrãs. Segundo a documentação do portal do cliente do Stripe, os clientes podem atualizar os dados de faturação e os meios de pagamento, alterar ou suspender uma subscrição, cancelar de imediato ou no fim do período de faturação, e ver ou pagar faturas. Configura-o no painel do Stripe.
A sua app precisa de um botão, "Gerir faturação", que chama uma segunda edge function. A função cria uma sessão do portal para o id de cliente Stripe do utilizador com sessão iniciada e devolve um URL. Dois limites da mesma página contam: o portal não pode ser mostrado dentro de um iframe, e a ligação de uma nova sessão expira ao fim de 5 minutos, por isso crie-a quando o utilizador clica, não com antecedência. Os cancelamentos feitos aí chegam à sua base de dados pelos mesmos eventos de webhook, pelo que não é preciso código extra.
Modo de teste e cartões de teste
Teste tudo com as chaves de teste do Stripe antes de tocar no modo de produção, porque os ambientes de teste são isolados e não movimentam dinheiro real. Segundo o guia de testes do Stripe, nunca deve usar dados de cartões reais nos testes. Estes são os cartões que vale a pena experimentar:
| Cenário | Número do cartão |
|---|---|
| Pagamento bem-sucedido | 4242 4242 4242 4242 |
| Recusa genérica | 4000 0000 0000 0002 |
| Saldo insuficiente | 4000 0000 0000 9995 |
| 3D Secure, autenticar a menos que já esteja configurado | 4000 0025 0000 3155 |
Para a data de validade use qualquer data futura, para o CVC quaisquer três dígitos, e qualquer valor nos outros campos. Execute pelo menos quatro cenários: um pagamento bem-sucedido, um cartão recusado, um cancelamento a partir do portal e um webhook entregue duas vezes. Verifique a linha da base de dados depois de cada um.
Taxas, impostos e faturas
A taxa padrão do Stripe para cartões é uma percentagem de cada pagamento mais um montante fixo, e ambos variam consoante o país, por isso consulte o valor do seu país em stripe.com/pricing antes de definir os preços. Não encontrámos uma taxa para os Estados Unidos nas páginas que conseguimos ler em novembro de 2026, por isso não indicamos aqui nenhuma taxa de cartão. A mesma página mostra o Billing, o produto de subscrições, como um custo separado sobre o volume recorrente (0,7 % em pay-as-you-go, verificado em novembro de 2026 na página de preços francesa), e o Stripe Tax como outra linha opcional.
Em linhas gerais: o Checkout e os Payment Links suportam ambos o Stripe Tax, que calcula por si o imposto sobre vendas ou o IVA, e o Stripe pode enviar recibos e faturas automaticamente. Saber se tem de se registar e cobrar imposto depende de onde estão você e os seus clientes, por isso pergunte a um contabilista antes do lançamento, em vez de perguntar a um criador de apps com IA.
Os prompts a enviar, um passo de cada vez
Envie estes prompts por ordem e verifique cada resultado antes do seguinte, porque um único prompt que peça pagamentos, webhooks e um portal de uma vez produz código difícil de depurar. Crie primeiro a sua conta Stripe, um produto e um preço em modo de teste, e tenha o id do preço à mão. Substitua o que está entre [parênteses retos].
- Checkout. "Adiciona uma página de Preços com um plano [Pro] a [$19 por mês]. O botão Subscrever chama uma função no servidor que verifica se o utilizador tem sessão iniciada, cria uma sessão Stripe Checkout em modo subscrição para o id de preço [price_xxx] com o id do utilizador associado, e devolve o URL. Redireciona o navegador para ele. A chave secreta do Stripe só pode ser usada dentro dessa função."
- Base de dados. "Cria uma tabela subscriptions com id do utilizador, id de cliente Stripe, id da subscrição, plano, estado e fim do período atual. Adiciona row level security para que um utilizador só possa ler a sua própria linha e nada possa ser escrito a partir do navegador."
- Webhook. "Cria uma função de webhook do Stripe que verifica o cabeçalho Stripe-Signature com o segredo do webhook e depois trata checkout.session.completed, invoice.paid, invoice.payment_failed, customer.subscription.updated e customer.subscription.deleted atualizando a tabela subscriptions. Tem de ser seguro receber o mesmo evento duas vezes, e não pode exigir login de utilizador."
- Acesso. "Lê a tabela subscriptions para decidir o que um utilizador pode usar. Mostra um estado bloqueado com um botão de upgrade em [funcionalidade] para os utilizadores cujo estado não seja active nem trialing. Nunca confies na página de sucesso para desbloquear seja o que for."
- Portal. "Adiciona um botão Gerir faturação nas definições que chama uma função no servidor que cria uma sessão do portal do cliente Stripe para o utilizador atual e devolve o seu URL."
- Falhas. "Quando um pagamento falhar, mostra um aviso a pedir ao utilizador que atualize o cartão, com uma ligação para o portal."
A primeira mensagem é a que mais conta; o nosso guia sobre como escrever prompts para criar uma app explica porquê.
Como o Cadrant faz
O Cadrant, o nosso criador de apps, gera apps web em React com um backend Supabase, e trata o Stripe através de edge functions do Supabase no seu próprio projeto Supabase. Pede a integração no chat, por exemplo "Adiciona pagamento Stripe para subscrições". O Cadrant escreve o código da edge function e implementa-o no seu projeto Supabase. Segundo a nossa documentação das edge functions, o navegador chama a função através da API do Supabase e as chaves nunca lhe chegam.
É você que acrescenta a chave, no painel Environment do projeto, sob o painel Database, como uma variável como STRIPE_SECRET_KEY, e o segredo do webhook como segunda variável. Segundo a página das variáveis de ambiente, as variáveis só estão disponíveis para o código do servidor e podem ser alteradas sem voltar a implementar a app. Nunca cole uma chave secreta no chat. A IA escreve também as migrações da base de dados com row level security, pelo que a tabela subscriptions do passo 2 acima segue as mesmas regras que o resto dos seus dados.
O Cadrant não é a única forma de o fazer. Qualquer criador que gere funções de servidor pode seguir os mesmos passos, e se quiser controlo total da lógica de faturação, continua a ser boa ideia que um programador reveja o código gerado antes do lançamento. O Stripe trata do dinheiro e dos dados dos cartões em todos os casos; o seu código apenas decide quem tem acesso.
Quando os pagamentos funcionarem, publique no seu próprio domínio; o nosso guia para publicar uma aplicação web cobre esse passo.