Como Integrar Pagamentos no App Feito com IA: Stripe, Pix e Supabase [2026]
![Como Integrar Pagamentos no App Feito com IA: Stripe, Pix e Supabase [2026]](/_next/image?url=https%3A%2F%2Ffxomitcagluilpagghdp.supabase.co%2Fstorage%2Fv1%2Fobject%2Fpublic%2Farticle-images%2Fcovers%2F1789031426417-9rzbdxn48m4.png&w=1920&q=75)
TL;DR
- Stripe com Supabase é a combinação que usamos para cobrar em apps feitos com IA, porque resolve cartão, Pix e assinatura com o backend que o app já tem.
Levar para a IA
Leve este artigo para o ChatGPT, o Claude ou a sua IA preferida.
Um app feito com IA que ainda cobra por Pix manual no WhatsApp está deixando dinheiro na mesa. Integrar pagamentos no app é o passo que transforma um projeto de fim de semana em negócio, e em 2026 isso leva uma tarde, com o Stripe fazendo a cobrança e o Supabase guardando quem pagou o quê. Na Marfin já colocamos cobrança em apps que nasceram no Lovable, no Cursor e no Claude Code, e o caminho é sempre o mesmo, com as mesmas armadilhas.
O problema é que a maioria dos tutoriais para no botão de checkout. O botão é a parte fácil. O que separa um app que cobra de verdade de um app que quase cobra está no que acontece depois do clique: o webhook que confirma o pagamento, a tabela que registra a assinatura, a regra de segurança que libera o conteúdo pago e o cancelamento que funciona sem ninguém mexer no banco na mão.
Este guia cobre tudo isso na ordem em que fazemos: escolha do meio de pagamento no Brasil, preparação da conta e do banco, os cinco passos da integração Stripe com Supabase, Pix e boleto, nota fiscal, os prompts que usamos para a IA gerar o código e uma tabela com o que cada peça custa hoje.
Stripe, Mercado Pago ou plataforma brasileira: onde cobrar
Antes de escrever uma linha, a decisão que mais pesa é qual processador vai receber o dinheiro. Para apps de assinatura feitos com IA, nós usamos Stripe na maioria dos casos, e o motivo é prático: a API é a mais bem documentada do mercado, todos os modelos de IA conhecem ela de cor, e o Stripe no Brasil já aceita cartão, Pix e boleto na mesma conta. Um app que precisa explicar seu modelo de cobrança para o Claude Code em duas frases e receber uma integração funcionando ganha muito com isso.
O Stripe exige CNPJ para abrir conta no Brasil, o que elimina o cenário de pessoa física testando uma ideia. Se o app ainda está na fase de descobrir se alguém paga, o Mercado Pago aceita CPF e resolve o teste inicial com o Checkout Pro, embora a API seja mais trabalhosa e menos conhecida pelos modelos de IA. Pagar.me e Asaas são fortes quando o volume cresce e vale negociar taxa, ou quando boleto e cobrança recorrente por Pix são o coração do produto. A Abacate Pay entrou nesse mercado com Pix a taxa fixa de centavos por transação e uma API simples que os vibe coders adotaram rápido.
Plataformas como Hotmart e Kiwify resolvem cobrança, nota fiscal e afiliados de uma vez, mas cobram perto de 10% e foram desenhadas para curso e infoproduto, o que trava quando o produto é software com login e uso contínuo. Para quem está construindo um SaaS de verdade, com plano mensal e área logada, a combinação Stripe com Supabase continua sendo o padrão que recomendamos.
O que muda com Pix no Stripe
O Pix chegou ao Stripe no Brasil e mudou a conta. Cartão custa 3,99% mais R$ 0,39 por transação doméstica, enquanto Pix custa 1,19%. Numa assinatura de R$ 49 por mês, a diferença é R$ 2,35 contra R$ 0,58, o que parece pouco até multiplicar por mil assinantes durante um ano. Para pagamento único, como um plano anual ou um pacote de créditos, oferecer Pix como primeira opção aumenta a conversão porque muita gente no Brasil simplesmente evita colocar cartão em app novo.
A limitação é que o Pix do Stripe funciona só para pagamento único. Assinatura mensal no cartão renova sozinha, enquanto assinatura por Pix precisa de uma nova cobrança a cada ciclo, com o cliente pagando ativamente. Nós resolvemos isso com plano anual por Pix e plano mensal por cartão, e a maioria dos apps que atendemos converge para esse desenho depois de um ou dois meses olhando os números.
O que precisamos antes de integrar pagamentos no app
Uma conta Stripe verificada com CNPJ, um projeto no Supabase com autenticação funcionando e um modelo de cobrança definido no papel. Parece óbvio, mas já vimos gente pedir para o Claude Code "adicionar Stripe" sem saber se ia cobrar assinatura, pagamento único ou crédito por uso, e o resultado foi uma integração que fazia as três coisas pela metade.
O modelo de cobrança define a estrutura do banco. Assinatura precisa de uma tabela que guarde o status atual, o plano, a data de renovação e o identificador do cliente no Stripe. Pagamento único precisa de uma tabela de pedidos com o que foi comprado e se foi pago. Crédito por uso precisa de saldo e de um histórico de consumo. Cada um desses desenhos é simples isolado, e vira bagunça quando alguém tenta fazer os três com uma tabela só.
A autenticação do Supabase precisa estar pronta antes, porque o pagamento sempre está preso a um usuário. O fluxo completo é: o usuário cria conta no app, clica em assinar, a gente cria uma sessão de checkout no Stripe já com o ID desse usuário nos metadados, o Stripe cobra, avisa a gente por webhook, e a gente marca no banco que aquele usuário está pago. Sem login, falta a quem dar acesso. Se o app foi feito no Lovable, o tutorial de Lovable que publicamos mostra como ligar a autenticação do Supabase antes de chegar nessa etapa.
A chave secreta nunca vai pro frontend
O Stripe entrega duas chaves: a publicável, que começa com pk_, e a secreta, que começa com sk_. A publicável pode aparecer no código do navegador. A secreta cria cobranças, faz reembolsos e lê dados de todos os clientes, e por isso vive só no servidor. No nosso caso, servidor significa Edge Function do Supabase, com a chave guardada como segredo do projeto e nunca em arquivo .env commitado.
Esse é o erro que mais vemos em app feito por IA sem revisão. O modelo, tentando ser prestativo, coloca a chave secreta num arquivo do React porque foi ali que o usuário pediu o botão. Funciona no teste, e expõe a conta inteira em produção. Antes de qualquer deploy, buscamos "sk_live" e "sk_test" em todo o repositório, e a busca tem que voltar vazia.
Como integrar pagamentos no app com Stripe Checkout e Supabase, passo a passo
O desenho que usamos tem cinco peças: a tabela de assinaturas, a função que cria o checkout, a função que recebe o webhook, a política de acesso no banco e o portal do cliente. Vamos passar por cada uma na ordem em que construímos.
Passo 1: modelar a assinatura no banco
A tabela mínima liga o usuário do Supabase ao cliente do Stripe e guarda o estado da assinatura. Nós criamos ela por migration, com Row Level Security ligado desde o começo:
create table public.subscriptions (
user_id uuid primary key references auth.users(id) on delete cascade,
stripe_customer_id text unique,
stripe_subscription_id text unique,
status text not null default 'inactive',
price_id text,
current_period_end timestamptz,
updated_at timestamptz default now()
);
alter table public.subscriptions enable row level security;
create policy "usuario le a propria assinatura"
on public.subscriptions for select
using (auth.uid() = user_id);
Repare que o usuário só tem política de leitura. Quem escreve nessa tabela é o webhook, usando a service role do Supabase, que ignora RLS. O usuário lê o próprio status e nada mais. Essa decisão elimina a categoria inteira de bug em que alguém chama a API do app e se marca como pago.
Passo 2: criar a sessão de checkout numa Edge Function
O botão de assinar no frontend chama uma Edge Function, que valida o token do usuário logado, cria a sessão no Stripe e devolve a URL do checkout hospedado. Usamos o Checkout hospedado do Stripe em vez de montar formulário de cartão, porque ele já resolve 3D Secure, Pix, boleto, cupom e recibo sem código nosso:
import Stripe from "npm:stripe@17";
import { createClient } from "npm:@supabase/supabase-js@2";
const stripe = new Stripe(Deno.env.get("STRIPE_SECRET_KEY")!);
const appUrl = Deno.env.get("APP_URL")!;
Deno.serve(async (req) => {
const authHeader = req.headers.get("Authorization")!;
const supabase = createClient(
Deno.env.get("SUPABASE_URL")!,
Deno.env.get("SUPABASE_ANON_KEY")!,
{ global: { headers: { Authorization: authHeader } } },
);
const { data: { user } } = await supabase.auth.getUser();
if (!user) return new Response("Unauthorized", { status: 401 });
const { priceId } = await req.json();
const session = await stripe.checkout.sessions.create({
mode: "subscription",
customer_email: user.email,
line_items: [{ price: priceId, quantity: 1 }],
success_url: appUrl + "/sucesso",
cancel_url: appUrl + "/planos",
metadata: { user_id: user.id },
});
return Response.json({ url: session.url });
});
O detalhe que faz tudo funcionar é o metadata com o user_id. Ele volta no webhook e é o que permite ligar o pagamento à conta certa. Sem isso, o webhook recebe um e-mail e precisa adivinhar quem é, e e-mail duplicado ou trocado vira bug de acesso. Os meios de pagamento aceitos vêm da configuração do painel do Stripe, então cartão, Pix e boleto aparecem no checkout sem mudar o código quando você ativa cada um.
Passo 3: receber o webhook e atualizar o Supabase
O webhook é uma segunda Edge Function, sem verificação de JWT do Supabase, porque quem chama é o Stripe e não um usuário logado. A segurança vem da assinatura que o Stripe envia no cabeçalho, verificada com o segredo do endpoint. Depois de verificar, a função lê o evento e grava o estado na tabela usando a service role:
const admin = createClient(
Deno.env.get("SUPABASE_URL")!,
Deno.env.get("SUPABASE_SERVICE_ROLE_KEY")!,
);
const event = await stripe.webhooks.constructEventAsync(
await req.text(),
req.headers.get("stripe-signature")!,
Deno.env.get("STRIPE_WEBHOOK_SECRET")!,
);
if (event.type === "checkout.session.completed") {
const session = event.data.object;
await admin.from("subscriptions").upsert({
user_id: session.metadata!.user_id,
stripe_customer_id: session.customer as string,
stripe_subscription_id: session.subscription as string,
status: "active",
});
}
Os eventos que tratamos em todo app são quatro: checkout concluído, assinatura atualizada, assinatura cancelada e pagamento de fatura falhado. Os dois últimos são os que os tutoriais esquecem, e são os que evitam que um cliente com cartão recusado continue usando o produto três meses de graça. Cada evento vira um upsert na tabela, e a função devolve 200 rápido, porque o Stripe reenvia qualquer evento que fique sem resposta em poucos segundos, e um webhook lento acaba processando o mesmo pagamento duas vezes.
Passo 4: liberar o acesso com RLS
Com a tabela de assinaturas atualizada, a liberação do conteúdo pago acontece no banco, com uma política que consulta o status. Se o app tem uma tabela de relatórios que só assinante vê, a política de select checa se existe assinatura ativa para o usuário atual. O frontend continua mostrando um cadeado bonito, mas quem decide é o Postgres, e isso vale mesmo se alguém abrir o console do navegador e chamar a API direto.
Para apps com muita tabela paga, criamos uma função SQL que responde se o usuário atual está ativo e reutilizamos ela em todas as políticas. Fica um lugar só para mudar a regra quando entra um plano novo ou um período de teste grátis, e a IA entende essa função com facilidade quando pedimos para estender o modelo depois.
Passo 5: portal do cliente e cancelamento
Trocar cartão, mudar de plano e cancelar são funções que o Stripe entrega prontas no Customer Portal. Uma terceira Edge Function cria a sessão do portal para o cliente logado e devolve a URL. O que o cliente fizer lá volta por webhook e atualiza a tabela. Nós nunca construímos tela de cancelamento própria, porque o portal já lida com pró-rata, reembolso e a regra de cancelar no fim do período pago.
Depois que os cinco passos estão no ar, o deploy do app com IA precisa incluir o registro do endpoint de webhook na URL de produção e a troca das chaves de teste pelas de produção. Esquecer a URL de produção é o motivo número um de "pagou e liberou nada" que recebemos de quem chega até aqui sozinho.
Como testar antes de cobrar um real de verdade
A Stripe CLI resolve o teste local com um comando que escuta os eventos e repassa para a função rodando na máquina: stripe listen apontando para o endereço da Edge Function servida por supabase functions serve. Com isso, um checkout feito em modo de teste dispara o webhook local e a tabela do Supabase local muda na hora. Sem essa etapa, o teste vira publicar em produção e torcer.
Os cartões de teste do Stripe cobrem os cenários que interessam: um número que aprova, um que recusa, um que exige autenticação 3D Secure e um que é salvo no cadastro do cliente e falha na hora da cobrança, o cenário da renovação recusada. Testamos os quatro em todo app, e o de renovação falhada é o que mais pega integração mal feita, porque o app precisa reagir a um evento que só chega um mês depois. O Stripe permite avançar o relógio de teste para simular esse mês em segundos, e esse recurso vale mais que qualquer teste unitário nessa parte do sistema.
Nota fiscal e imposto ficam fora do Stripe
O Stripe cobra, repassa e emite recibo. A nota fiscal de serviço, que todo SaaS no Brasil precisa emitir a cada cobrança, fica por conta de um serviço separado. Nós ligamos NFe.io ou eNotas no mesmo webhook que marca a assinatura como paga: o evento de fatura paga dispara a emissão da NFS-e com o CPF ou CNPJ que o cliente informou no cadastro, e o PDF vai por e-mail. O Asaas tem emissão nativa, o que pesa a favor dele para quem quer menos peças no sistema.
Coletar CPF ou CNPJ no cadastro, e o endereço quando a prefeitura exige, é uma decisão de produto que vale tomar antes de integrar pagamentos no app. Pedir depois, para quem já paga, custa suporte e cancelamento. Nossa regra é pedir o documento na tela de planos, antes do checkout, e guardar na mesma tabela de perfil que o app já tem.
Fazendo tudo isso com IA: os prompts que usamos
Claude Code é a ferramenta que mais usamos na Marfin para esse tipo de integração, e o Cursor é onde fazemos o building do app no dia a dia. A diferença entre pedir "adiciona Stripe" e receber algo pronto está no contexto que damos. O prompt que usamos parte do modelo de cobrança já definido e lista as cinco peças: tabela com RLS, função de checkout, função de webhook com verificação de assinatura, política de acesso e portal. Com o Opus 4.8, o Claude Code cria as migrations, as três funções e a página de planos numa rodada, e a revisão fica concentrada em conferir os quatro eventos de webhook e a ausência de chave secreta no frontend.
No Lovable, o caminho é mais curto porque a plataforma tem integração nativa com Stripe conectada ao Supabase. O Agent Mode gera as Edge Functions e pede as chaves na configuração do projeto, sem colar segredo em código. A modelagem do banco do jeito que descrevemos fica por nossa conta, então vale conversar sobre a tabela de assinaturas antes de pedir o checkout. O Bolt.new também oferece integração com Stripe e é uma opção válida, mas a experiência com Supabase é menos integrada e acabamos ajustando mais coisa na mão.
Para quem está começando pelo vibe coding e ainda está montando o app, a ordem que funciona é: fazer o app funcionar com login, colocar a cobrança com um plano só, e depois adicionar plano de equipe, cupom e período de teste. Quem tenta fazer tudo de uma vez pede à IA um sistema de billing completo e recebe um sistema de billing pela metade. Se a dúvida é qual ferramenta escolher para esse trabalho, a comparação das melhores IDEs com IA em 2026 cobre Claude Code, Cursor e Windsurf lado a lado.
Um atalho que vale conhecer: o Supabase mantém um wrapper de dados que permite consultar clientes e assinaturas do Stripe direto por SQL, sem sincronizar tabela. Serve para relatório e conciliação sem código extra, enquanto a liberação de acesso continua no webhook, porque a consulta remota é lenta demais para rodar em cada requisição.
Stripe vs Mercado Pago vs Pagar.me vs Asaas para apps feitos com IA
O Stripe ganha em documentação, em conhecimento dos modelos de IA e em completude para assinatura. Perde na exigência de CNPJ e na ausência de Pix recorrente automático. É a escolha padrão para SaaS com área logada.
O Mercado Pago ganha na abertura de conta com CPF, na confiança que o brasileiro médio tem na marca dentro do checkout e no Pix a 0,99%. Perde numa API mais confusa, com mais versões e menos exemplos, o que se traduz em mais rodadas de correção quando a IA gera o código. É a escolha para validar ideia antes de abrir empresa.
Pagar.me e Asaas ganham em taxa negociada quando o volume passa de algumas dezenas de milhares por mês e em recursos de cobrança brasileira, como boleto com juros e multa, Pix recorrente com aviso automático e emissão de nota fiscal integrada no caso do Asaas. Perdem na curva de integração e na dependência de contrato comercial. São a escolha para app que cobra pequeno negócio brasileiro por boleto e Pix.
A Abacate Pay ganha em simplicidade e na taxa fixa por Pix, que fica imbatível em ticket alto. Perde em maturidade e em recursos de assinatura. É a escolha para pagamento único por Pix, como venda de crédito ou plano anual.
Para quem ainda decide se o produto vai ser um app pago ou uma ferramenta grátis com upsell, o guia de como criar app sem programar mostra o caminho até o ponto em que a cobrança entra.
Preços e planos
| Item | Custo em 2026 |
|---|---|
| Stripe, cartão nacional | 3,99% + R$ 0,39 por transação |
| Stripe, cartão internacional | acréscimo de 2%, mais 2% se houver conversão de moeda |
| Stripe, Pix | 1,19% por transação |
| Stripe, boleto | R$ 3,45 por boleto pago |
| Stripe Billing (assinaturas) | 0,7% sobre o volume recorrente no plano Starter |
| Supabase Free | US$ 0, 500 MB de banco, 500 mil invocações de Edge Function por mês |
| Supabase Pro | US$ 25 por mês, 8 GB de banco, 2 milhões de invocações, projeto sem pausa |
| Supabase Team | US$ 599 por mês, SSO, mais retenção de logs e suporte |
| Mercado Pago, Pix | 0,99% por transação |
| Mercado Pago, cartão | 3,98% a 4,98% conforme o prazo de repasse |
Na prática, um app com 100 assinantes a R$ 49 no cartão paga ao Stripe algo perto de R$ 270 por mês entre taxa de transação e Billing, ou cerca de 5,5% do faturamento. O mesmo app recebendo tudo por Pix anual pagaria menos de R$ 70. O Supabase Free segura o começo, mas tem uma pegadinha: projeto grátis sem atividade por uma semana entra em pausa, e um webhook batendo num projeto pausado perde o pagamento. Por isso a primeira cobrança real acontece já no plano Pro, e os US$ 25 por mês viram a assinatura mais barata da operação.
8 dicas para integrar pagamentos no app sem dor de cabeça
1. Comece com um plano só. Um preço, um checkout, um webhook. Plano de equipe, cupom e teste grátis entram depois, quando o fluxo básico já roda em produção por algumas semanas e você sabe o que os clientes pedem.
2. Guarde o ID do usuário nos metadados do checkout. É a única forma confiável de ligar um pagamento a uma conta. E-mail muda, e-mail repete, e o Stripe cria cliente novo com facilidade. O user_id do Supabase resolve tudo isso.
3. Trate os quatro eventos de webhook desde o primeiro dia. Checkout concluído, assinatura atualizada, assinatura cancelada e fatura falhada. Quem só trata o primeiro descobre meses depois que tem cliente inadimplente usando o produto.
4. Use o Customer Portal em vez de tela própria. O portal cuida de troca de cartão, mudança de plano, cancelamento e pró-rata, com as regras que você define no painel. Construir isso na mão custa semanas e ainda sai com bug.
5. Peça à IA para procurar chave secreta no repositório. Antes de cada deploy, o Claude Code roda uma busca por sk_live e sk_test e confirma que a única ocorrência está nos segredos do Supabase. Um minuto de revisão evita uma conta comprometida.
6. Ofereça Pix no plano anual e cartão no mensal. O Pix converte melhor e custa menos, mas exige pagamento ativo a cada ciclo. Casar o meio de pagamento com o ciclo de cobrança resolve os dois lados.
7. Suba para o Supabase Pro antes da primeira cobrança real. Projeto grátis pausa depois de uma semana sem uso e engole webhook. Os US$ 25 por mês são a proteção mais barata que existe contra pagamento sem acesso liberado.
8. Registre o webhook de produção como item do checklist de deploy. Chaves de produção, endpoint de webhook na URL final e segredo do endpoint atualizado na Edge Function. Os três juntos, sempre, porque qualquer um faltando quebra o fluxo de forma silenciosa.
Cobrar pelo app é onde o vibe coding encontra a realidade de operar um produto. A IA escreve a integração em uma tarde, e o que fica com a gente é decidir o modelo de cobrança, revisar a segurança e testar o caminho que o dinheiro faz até a tabela de assinaturas. Feito com esse cuidado, o mesmo desenho aguenta do primeiro cliente até os primeiros milhares sem reescrita, e cada plano novo vira uma migration e uma linha a mais no webhook.
Leia também:
- O que é vibe coding
- Lovable tutorial: como criar apps com IA sem código
- Como criar app sem programar
- Deploy de app com IA
- Como criar um site com IA: ferramentas de vibe coding na prática
- Lovable vs Bolt.new vs V0: comparativo completo
- V0 da Vercel: tutorial completo
- No-code: o que é e quando usar
- O que é SaaS
- Melhores IDEs com IA em 2026

