Stripe (web)
Assinaturas web via Stripe Checkout + Customer Portal. Do teste à produção.
O módulo Stripe cobre assinaturas na web (quando o usuário está no navegador ou PWA). No mobile (iOS/Android), o kit usa RevenueCat.
Mobile usa RevenueCat. Você pode ligar só Stripe (app web), só RevenueCat (app mobile) ou os dois juntos. Veja RevenueCat.
Implementação
Pelo MCP do Kasy: peça ao assistente "adiciona stripe no meu projeto" pra ligar a feature no código (add_feature). O MCP da Stripe (abaixo) é outra coisa: cria produto e preços no painel deles. Veja MCP do Kasy.
1. Criar conta na Stripe
Acesse stripe.com e crie sua conta.
2. Criar Produto e Preços (pelo painel ou via MCP)
Pelo painel
- Stripe → Products → Add product
- Nome / descrição (aparecem no paywall)
- Em Pricing, adicione:
- Um Price mensal recorrente
- Um Price anual recorrente
- (Opcional) Em Features do Produto, liste os benefícios, que viram a lista do paywall
- Copie o
prod_…do produto (você vai precisar comoSTRIPE_PRODUCT_ID)

O kit usa só planos recorrentes (mensal/anual). Não use Prices one-time.
Via MCP do Stripe (mais rápido)
Prefere configurar pela IA em vez do painel? Siga MCP do Stripe, na seção Informações abaixo, e volte pro passo 3 quando terminar.
3. Registrar o webhook
O webhook é obrigatório: é ele que grava a assinatura no banco.
- Stripe → Webhooks → Add endpoint
- Cole a URL do webhook do seu backend:
| Backend | URL |
|---|---|
| Firebase | https://<region>-<projectId>.cloudfunctions.net/stripeFunctions-stripeWebhook |
| Supabase | https://<project-ref>.supabase.co/functions/v1/stripe-webhook |
kasy doctor mostra a URL do webhook do seu projeto.
- Em Select events, marque os 3 eventos:
customer.subscription.createdcustomer.subscription.updatedcustomer.subscription.deleted
- Salve → copie o Signing secret (
whsec_...)

4. Configurar as chaves no backend
Você vai precisar de 3 valores:
| Chave | Formato | Onde pega |
|---|---|---|
STRIPE_SECRET_KEY | sk_test_... / sk_live_... | Stripe → API keys |
STRIPE_WEBHOOK_SECRET | whsec_... | Stripe → Developers → Webhooks → seu endpoint → Signing secret |
STRIPE_PRODUCT_ID | prod_... | do seu Produto (opcional; em branco lista todos) |

# Firebase: configura os secrets e faz o deploy
kasy configure stripe # pede as 3 chaves
kasy deploy # publica as funções com os secrets
# Supabase: configura os secrets
supabase secrets set STRIPE_SECRET_KEY=sk_test_xxx
supabase secrets set STRIPE_WEBHOOK_SECRET=whsec_xxx
supabase secrets set STRIPE_PRODUCT_ID=prod_xxx # opcionalPelo MCP: no Firebase, cole as 3 chaves no chat e peça "configura o Stripe". O assistente grava com configure_project_keys (o kasy deploy pra publicar as funções ainda é um passo separado). Veja MCP do Kasy.
API REST: você implementa 4 endpoints no seu servidor:
| Endpoint | O que faz |
|---|---|
GET /stripe/list-prices | Devolve os Prices recorrentes ativos da sua conta |
POST /stripe/checkout-session | Cria sessão de Checkout e devolve { url } |
POST /stripe/portal-session | Cria sessão do Customer Portal e devolve { url } |
POST /webhooks/stripe | Recebe os 3 eventos customer.subscription.* e grava em subscriptions (store=STRIPE) |
A STRIPE_SECRET_KEY e a STRIPE_WEBHOOK_SECRET ficam no seu servidor, nunca no app. O contrato completo (payload de cada endpoint) está no README.md gerado dentro do seu projeto Kasy.
5. Testar
kasy run --web # abre em localhost:5555Abra o paywall → escolha um plano → você cai no Checkout da Stripe.
Use os cartões de teste da Stripe:
- Número:
4242 4242 4242 4242 - Validade: qualquer data futura
- CVC: qualquer 3 dígitos

Confirme que a tabela subscriptions recebeu store='STRIPE' e o app virou premium. Se sim, terminou o modo teste.
6. Ir pra produção
- No painel Stripe, desligue o Test mode (Live)
- Recrie (ou ative) Produto + Prices em live
- Pegue
sk_live_...e atualize no backend - Registre um novo endpoint de webhook em live e pegue o novo
whsec_... - Refaça o deploy
- Faça uma compra real de validação
Se a compra real cair como premium na conta, a implementação está completa.
Por que cobrar na web também. Compra feita dentro do app passa pela Apple ou pela Google e elas retêm uma comissão de cada pagamento. A mesma assinatura vendida pelo navegador via Stripe tem uma taxa bem menor. Por isso muitos apps mantêm os dois caminhos: RevenueCat no celular e Stripe no site.
Informações
Como funciona
- O app chama o backend que cria uma sessão de Stripe Checkout e devolve a URL.
- O app abre essa URL no navegador. Toda a parte de cartão / PCI fica na Stripe.
- Quando o usuário paga, o webhook da Stripe chama o backend e grava a assinatura.
- O app detecta a mudança e vira premium. O cliente nunca escreve "sou premium": não dá pra forjar.
Os planos do paywall são buscados automaticamente dos Prices recorrentes ativos da sua conta Stripe. Você não digita preço no código.
O que a CLI configura automaticamente
Ao escolher Stripe no kasy new ou kasy add stripe:
- Liga a flag
withStripeno app - Embarca a camada de pagamento (checkout, portal, busca de preços)
- Instala as funções de backend (Firebase Cloud Functions ou Supabase Edge Functions)
- Configura a injeção por plataforma: web usa Stripe, mobile usa RevenueCat (se ligado)
MCP do Stripe
A Stripe tem um servidor MCP que deixa a IA criar produtos, preços e webhooks na sua conta, sem abrir o painel. Use como alternativa ao passo 2.
Configurar o MCP
Cole na sua IA (troque pela sua chave de teste):
Configure o MCP da Stripe (modo teste) nesta máquina, no Claude Code.
Use o pacote oficial @stripe/mcp via npx, com a chave no env STRIPE_SECRET_KEY.
Minha chave de teste é: sk_test_XXXXXXXX
Adicione um servidor MCP chamado "stripe-test" que roda:
npx -y @stripe/mcp (com env STRIPE_SECRET_KEY = a minha chave acima)
NÃO use @stripe/agent-toolkit (é biblioteca, dá "Connection closed").
No fim, me avise pra eu reiniciar o Claude Code.Reinicie o Claude Code. O MCP só carrega em sessão nova.
Ou use o MCP remoto oficial (mais simples, sem chave em arquivo):
{
"mcpServers": {
"stripe": { "url": "https://mcp.stripe.com" }
}
}Criar o catálogo pela IA
Com o MCP conectado, cole na IA (ajuste preços e nomes):
Com o MCP da Stripe conectado (modo teste), crie meu catálogo de assinatura:
- 1 Produto "Pro" com descrição curta e 3 benefícios (viram a lista do paywall)
- 2 preços recorrentes: mensal R$ 19,90 e anual R$ 199 (moeda BRL)
- 7 dias de trial grátis (metadata trial_days=7 no produto)
Liste os preços ativos e me dê o STRIPE_PRODUCT_ID (prod_...) para configurar no backend.Volte pro passo 3 quando o catálogo estiver criado.
Período de teste gratuito (trial)
O trial é lido do Price da Stripe e aparece no paywall automaticamente.
Duas formas de configurar:
- metadata
trial_days: no Price (ou no Produto), adicione metadatatrial_days = 7 - Trial nativo do Price: configure o free trial direto no painel do Price
O backend devolve trialDays em listPrices e a UI mostra "7 dias grátis" automaticamente.
Feature flags
Em lib/core/config/features.dart:
| Flag | Padrão | O que faz |
|---|---|---|
withStripe | nenhum | Liga o módulo Stripe |
withStripePromoCodes | true | Exibe campo de cupom no Checkout |
withStripePlanSwitching | true | Habilita upgrade/downgrade no Customer Portal |
Como funciona o pagamento (detalhes)
- App cria sessão de Checkout → abre o Stripe numa nova aba
- O e-mail vem preenchido com o e-mail da conta do usuário
- A tela do app fica em espera e faz polling a cada 5s no backend
- Quando a pessoa paga, o webhook grava
subscriptions→ o polling detecta → app vira premium - Timeout: após ~10 min sem confirmação, app volta ao paywall com toast "se já pagou, toque em Restaurar"
No mobile (nativo), se o usuário assinou via Stripe na web, o app mostra um diálogo: "Esta assinatura foi feita em outra plataforma. Gerencie onde você comprou." Isso é exigido pelas políticas da Apple e do Google.
Troubleshooting
Paywall vazio (sem planos) na web
- Não há Price recorrente ativo na conta
STRIPE_PRODUCT_IDaponta pra um produto sem Prices recorrentesSTRIPE_SECRET_KEYé de test mode mas os produtos estão em live (ou vice-versa)
Webhook não grava a assinatura
STRIPE_WEBHOOK_SECRETerrado ou de outro modo (teste vs live)- Os 3 eventos
customer.subscription.*não foram selecionados no endpoint - No Firebase: falta o deploy após configurar os secrets
Premium não ativa mesmo após pagar
- Verifique se o webhook chegou: Stripe → Developers → Webhooks → logs do endpoint
- Verifique se o
uidno metadata bate com o usuário logado
"No Stripe customer for user" ao abrir o Portal
- O usuário ainda não passou pelo Checkout. O Portal só funciona após a primeira assinatura.
Atualizado em 03/11/2026

