#06 Como Integrar o Stripe ao Supabase com Edge Functions 🚀 | [Série] Criando um SaaS do ZERO

Samuel Rizon shows how to connect Stripe to Supabase using Edge Functions for a multi-tenant SaaS. He sets up two subscription plans (Essential R$19,90/month and Pro R$39,90/month), designs the database schema with Row Level Security, creates a webhook function to sync Stripe events, and deploys it live.
Chapters
E aÃ, meus amigos, tudo bem com vocês? Hoje a gente vai falar sobre o Stripe e o Supabase. Então a gente vai criar nossa conta no Stripe, cadastrar os produtos, criar as tabelas no Supabase e criar nossa primeira ad function que vai servir como o nosso webhook das ações do Stripe. E a ideia é deixar tudo pronto para a gente começar já a ter as assinaturas dentro do nosso projeto, implementar isso no nosso próximo vÃdeo. E se você é novo por aqui, meu nome é Samuel Rizon e por aqui eu falo sobre programação, carreira e esse mundo de SaaS. E se você gosta desse tipo de conteúdo, não esquece de deixar o seu like, se inscrever se inscrever no canal, ativar o sininho para não perder nenhum vÃdeo. E não se esquece que a gente tem uma comunidade do canal no WhatsApp, e lá eu tô compartilhando os bastidores dessa série, eu faço enquete com o pessoal, eu ajudo a galera. Então eu fico mais próximo de vocês, junto nesse projeto e tudo que a gente está desenvolvendo aqui. Primeiro link da bio, dá um clique lá e entra para comunidade. Vamos para o vÃdeo? Show! Então vamos falar aqui sobre as nossas próximas etapas, que que a gente vai fazer tanto nesse vÃdeo agora quanto no próximo, o que que eu tô planejando. A ideia é a gente criar nossa conta no Stripe, cadastrar os produtos, e eu vou falar sobre os planos e os preços que a gente vai utilizar, e a gente vai criar as tabelas no Supabase. Então a gente vai criar a tabela da empresa, a tabela que vincula o usuário à empresa, a tabela de clientes, né, do Stripe, os produtos, os preços e as inscrições. Essas 4 tabelas aqui são do próprio Stripe. E aà por último a gente vai criar uma edge function do webhook do Stripe. E aà depois disso, a ideia no próximo vÃdeo, a gente criar uma add function para lidar com a assinatura. Então quando o usuário preencher tanto formulário de administrador quanto formulário da empresa, a gente vai criar um próximo passo para ele selecionar o produto, né, o plano que ele quer utilizar. E aà a gente vai chamar essa add function aqui para criar assinatura dele. E aà a gente cadastra usuário, a empresa, e inicia um trial de 14 dias. E aà falando sobre os planos e os preços, A ideia que a gente teve, né, e com a comunidade do WhatsApp, a galera votou pra gente fazer o plano dessa forma assim: um plano Essencial de R$19,90 por mês, que vai ter a atualização do tempo de espera, a página da barbearia com status de aberto e fechado, o link para compartilhar com os clientes e a personalização da página com a logo, as cores e a mensagem personalizada. E um plano Pro de R$39,90 por mês, que vai ter tudo do plano Essencial, só que a gente vai ter uma notificação via WhatsApp pros clientes interessados e um relatório semanal com a estatÃstica de tempo médio de espera. Então a gente vai criar esses dois produtos, né, esses dois planos aqui dentro do Stripe e adicionar o webhook pra ele atualizar esses planos dentro da nossa tabela do banco de dados. Vamos pro Stripe. Então a gente vai aqui em Stripe, vou fazer aqui do zero com vocês. A gente entra aqui no Stripe. Sing in. E a gente vem aqui, ó, criar conta. Vou colocar o meu e-mail, samuelrizondev@gmail.com, Samuel Rizon. Deixar ele escolher a minha própria senha e vou criar minha conta. E aà o Stripe vai me redirecionar para tela inicial e a gente vai chamar aqui de My Timinha Barbearia. Continua, que a gente criou nome da nossa conta. A gente vai selecionar aqui, ó, pagamentos recorrentes, que é o que a gente vai utilizar, e ir pro dashboard. E essa é a tela inicial do Stripe, tá? A gente já tem a nossa API key, a secret key, a gente já tem algumas coisas aqui do lado de inscrições, produtos. Então o nosso catálogo de produtos é aqui que a gente vai criar o nosso produto. E a gente aqui tá em sandbox, mas se eu for criar a minha live account aqui, né, minha conta principal, eu tenho que checar o meu e-mail. Então provavelmente o Stripe me mandou um e-mail e eu vou abrir esse carinha aqui agora. Eu vou abrir o Samuel Rizondev e eu tenho aqui para mim verificar o e-mail do Stripe. Sem isso eu não consigo ir para produção. Então beleza, quando eu vim para o Live Account aqui, provavelmente ele vai me pedir algumas informações adicionais para mim ativar o método de pagamento. Então aqui a gente não vai fazer isso aqui agora, mas aqui é onde eu vou colocar todas as informações de que eu preciso, conta bancária, tudo que eu preciso para o Stripe criar a conta em produção para mim. A gente não vai fazer isso aqui agora, talvez a gente faça mais para frente, mas por enquanto a gente vai deixar só no sandbox mesmo, pra gente não precisar colocar todos esses dados aqui. Então, por enquanto, a gente fica no, no modo de teste aqui mesmo, e a gente vai vir aqui no catálogo de produtos e a gente vai criar um novo produto. E aÃ, vamos dar uma olhadinha aqui qual que vai ser o nome. Vai ser Essencial, o meu produto aqui, Essencial. O valor dele vai ser R$19,90 por mês. $39,90 por mês. Aqui a gente fala que é recorrente, o perÃodo vai ser mensal, e basicamente é isso aqui que eu preciso para mim criar o meu produto. Eu posso criar outras keys aqui ou outras coisas do tipo, mas eu vou dar um Add Product aqui e eu já tenho meu produto Essencial, que é uma recorrência mensal, e eu vou criar o Pro, que é uma recorrência também no valor de $39,90 por mês. Então 39,90 e Add Product. Então isso aqui são produtos simples, então a gente só vai ter esses dois produtos aqui. Mas caso vocês queiram criar produtos mais complexos, existe essa possibilidade aqui, ó. A gente vem aqui, More Pricing Options, e por exemplo, no Ministral eu tive que fazer essa forma aqui. Então eu criei um Tiered Pricing. Então, por exemplo, No meu SaaS eu tenho um plano de escalas que de 0 a 100 voluntários, 0 a 20 voluntários é um preço. Então eu vim aqui, colocava de até 20 voluntários era, sei lá, R$99,99, 0 e 99,90. Então esse aqui é o preço por unidade, coloca o 0. Se eu precisar adicionar outro, então eu colocava aqui de 21 Ah, 100, eu vou colocar que o preço é R$159,90. Então dessa forma que a gente consegue criar uns preços diferenciados para cada produto que eu tenho dentro do meu sistema, tá? Então essa aqui é uma forma que eu fiz, eu gostei, aprendi e desenvolvi e criar esse produto dessa forma aqui. Mas se vocês precisarem criar algum produto desse jeito, é só fazer com esse Target Pricing aqui que funciona e dá certo, tá bom? A gente não vai utilizar isso aqui, os nossos produtos vão ser somente esses dois aqui. E basicamente essa parte do Stripe de criar, vamos aqui, ó, então de criar conta no Stripe, cadastrar os produtos, é só isso aqui. A gente não precisa fazer mais nada, tá bom? Os produtos já estão criados e agora a gente vai para o Supabase. Então entrando aqui no Supabase, eu tô aqui no meu projeto normal. A gente vai criar agora então as tabelas de company e user_company. Então, abrindo nosso projeto, a gente tem aqui o nosso company_details e o nosso service, subscription_service. Então, a minha empresa, por enquanto, ela tem um nome, o CNPJ e o endereço, certo? E basicamente é isso aqui que a gente vai criar agora. Se precisar adicionar mais campos, a gente vai adicionar. Mas o que que eu gosto de fazer? Eu gosto de pegar ou esse objeto ou alguma coisa aqui, e a gente pode jogar isso aqui lá para o Supabase. Então eu posso vir aqui em SQL Editor na IA, que o Supabase tem uma assistente. Eu coloco esses campos todos aqui e eu vou falar com ela: cria a tabela company com os dados acima, mas para, mas crie apenas um campo endereço do tipo JSON. E eu vou mandar para ele, ele vai criar o SQL para mim. Perfeito, ele criou a minha tabela aqui, eu vou jogar ela para cá. Ele criou a tabela com big int, então eu vou pedir altere o id para o id e remova, remova o campo zip_code. Porque, pessoal, eu tô criando aqui a tabela de address. Em vez de eu criar uma nova tabela só para esse endereço, eu tô informando que— então eu vou inserir esse código aqui, deixa eu apagar, copiar. Inserir novamente. Então eu tenho ID, nome, CNPJ, endereço, é um campo de JSON, um JSON normal, e tem o createdAt e updatedAt. Só que eu preciso do meu BaseAPI, e eu acho que a gente ainda não tem esse carinha aqui. Interfaces, a gente não tem esse carinha, mas uma coisa que a gente vai fazer, e eu vou criar uma nova tabela aqui, interfaces, e eu vou chamar de BaseInterface.ts. Export interface e Base. id é uma string, createdAt é um date, createdBy é um id de quem criou, updated_at e updated_by. E a gente vai criar um active aqui também, boolean. Então todas as nossas tabelas do banco de dados a gente vai ter esses campos base aqui. Então eu vou lá no Supabase e crio a tabela. Vamos ver se adiciona E vai escrever o SQL, perfeito. Copia. Então agora sim, eu tenho um campo, o ID, eu tenho nome, eu tenho CNPJ, eu tenho endereço, created_at aqui certinho. E show! Então eu já tenho minha tabela aqui. Aqui ele já vai habilitar o role level security. E ele vai criar um index para o nome. Então a gente já tem nossa tabela de company aqui, eu vou dar um run. E beleza, sucesso! Quando eu venho aqui então no meu Table Editor, eu já tenho minha tabela de company e eu já consigo fazer um CRUD completo aqui nessa tabela direto lá do nosso front-end. Então criamos company, agora a gente precisa criar a tabela user_company. Então vamos lá de novo agora, SQL Editor, e agora eu vou dar um reset. Crie a tabela user_company que tem o ID do usuário da tabela users e o ID da empresa da tabela company e tem uma coluna chamada rows. Então, tô literalmente falando para a IA criar a tabela para mim. Vou pegar aqui, vou colar. Então eu tenho um ID novamente. Às vezes ela cria esses IDs assim e eu vou— depois ela vai entender. Quando a gente vai criando o banco de dados, aà ela vai entendendo a nossa estrutura do banco de dados. Use essa mesma estrutura base. O ID deve ser o ID. Ele tá viajando aqui, então eu vou pegar esse código aqui de novo e eu vou pegar o meu código aqui E vou mandar ele de novo para criar a tabela e usar a estrutura base. Tá escrevendo o SQL e agora sim tá criado aqui. Então o ID é um UUID, esse carinha aqui eu vou colocar para cima. Então o company não é um bigint, company é um UID da tabela company e user_id é da tabela users. No inÃcio aà ela pode viajar um pouco à s vezes, mas depois vocês vão ver que ela vai começando a entender a sua base de dados e o que que você tá criando. Agora sim, ó, eu tenho um user_id que faz a referência ao public users eu tenho um company_id que faz a referência ao company, show, e eu tenho created_at, active e as roles do meu usuário. A coluna roles é um enum com as roles de admin e user. Então a gente vai ter uma role de admin e de usuário. Ele vai criar esse carinha aqui para gente. Então basicamente, vou colar aqui, mudar aqui para public. Show! Então agora eu tenho um type UserRole que pode ser admin ou user, e ele tá usando esse type aqui. Então vamos criar também, ele tá falando para lembrar de criar a role level security para da tabela, mas a gente vai rodar e a gente já tem a nossa user_company criada. Então se eu venho aqui, user_company tá criada. Vocês podem ver que tá esse cadeadinho aqui, ó, porque o role level security não tá habilitado, e a gente vai trabalhar nisso aqui depois. Então a gente criou company, user_company, e agora a gente vai criar as tabelas do Stripe. E como que a gente faz isso, gente? O Supabase, ele já dá para gente alguns templates e uns quick starts aqui, ó. Então quando eu venho aqui, ó, em SQL Editor, quick starts, eu tenho Stripe subscriptions. Quando eu clico aqui, eu já vejo esse código do próprio Supabase. Deixa eu dar um zoom aqui para ficar mais fácil de entender. Aqui ele tá criando a tabela de usuários. A gente não precisa dessa parte porque a gente já criou no último vÃdeo. Tá bom, mas aqui agora a gente vai criar então a tabela de customers. Então vou dar um create table aqui, vou dar um Ctrl+F, products, prices e subscriptions. Então ele já me dá as tabelas que eu preciso para eu conseguir entregar com Stripe de uma forma muito mais simples, muito mais fácil. Só que se vocês perceberem, a tabela customers ele coloca o ID do usuário e a gente não quer isso, a gente quer que a nossa tabela customers seja o ID da empresa. Então aqui a gente vai colocar um company_id, tá, public company, não é nulo e é uma chave primária. E aqui o ID do cliente no Stripe. Ao invés da gente conectar, né, e vincular o Stripe a um usuário, a gente vai vincular o Stripe a uma empresa, porque essa empresa vai poder ter mais de um usuário para gerenciar e administrar as coisas da empresa. Tá, então a gente vai criar esse company ID aqui. Produtos, o ID do produto, se ele tá ativo ou não, nome, descrição, imagem e metadata. Isso aqui o Swabbase já me dá porque é o que o Stripe já cria quando ele cria um produto. Preços, a mesma coisa, o Swabbase já me dá aqui, ó, os tipos dos preços, tudo que a gente precisa para integrar com o Stripe. E as subscriptions, então eu tenho a subscription aqui, ID, inscrição. E aqui a gente vai mudar também, então vai ser, em vez de ser user_id, vai ser o company_id, public company, tá bom? Então sempre lembrar disso aqui, porque a gente tá vinculando uma inscrição, né, uma assinatura à empresa e não a um usuário. E todos os outros campos aqui a gente já tá habilitando o role level security. E uma coisa que ele já faz aqui que é legal é que, por exemplo, na customers, ele ativa o Row Level Security, só que ele não cria nenhuma polÃtica. Por quê? Porque essa é uma tabela privada e a gente não quer que um usuário qualquer, ou um usuário pelo front-end, consiga alterar essa tabela. Então o pessoal fala da segurança do Supabase, né? Aà o Supabase não é seguro e não sei o quê, a gente tem falha de segurança. Não, a gente não tem. Se eu ativo esse Row Level Security, não coloco nenhuma polÃtica, somente pelo backend, por uma add function ou pela secret key, que é a chave secreta do Supabase, que ela vai passar pelo role level security. Ela não usa o role level security, então somente por ela ou pelo dashboard aqui que eu consigo alterar essa tabela. Fora isso, um usuário com a public key nunca vai conseguir fazer nada nessa tabela aqui. Então a gente tem essa parte aqui pro produtos também, ele tá habilitando role level security, só que só para select. Então qualquer usuário vai poder acessar esses produtos, mas não vai conseguir inserir, remover ou alterar um produto. E a mesma coisa para os preços aqui, tá bom? Subscriptions também. Só que nesse caso a gente não pode vincular a esse user ID porque a gente mudou esse carinha aqui agora, que é o company ID. Então a gente precisa habilitar essa opção de visualizar aqui as subscriptions somente para o usuário que estiver logado. Só que esse usuário precisa estar vinculado a esta empresa aqui através da tabela user_company. Então a gente vai precisar alterar esse carinha aqui, e eu vou usar o Supabase aqui. E vou falar: altere essa policy para deixar somente os usuários que são vinculados à tabela company, que estão vinculados à tabela company, ao invés de utilizar o user_id. E agora essa tabela possui apenas o company_id. Vamos ver o que que sua base Vai me sugerir aqui. Então aqui, ó, ele criou uma policy para mim. Eu vou copiar essa policy e colar aqui só para a gente ver o que que ele fez. Ele tá dando um SELECT na companies onde o ID é igual ao ID. Só que na verdade a gente precisa desse user_company aqui, ó. Então eu preciso dar um SELECT na user_company onde eu pego o company_id e o user_id é igual a esse carinha aqui, que é o alf_uid. Então esse SELECT aqui vai ser esse carinha aqui. Pega esse cara, colo aqui e pronto. Por último, ele só cria um real-time aqui. A gente não precisa disso, acho que a gente não vai utilizar um real-time nessas tabelas, mas eu vou dar um run. Vamos ver se vai funcionar. Beleza, funcionou. Eu venho aqui e eu já tenho todas as minhas tabelas, todas elas com role level security habilitado. Se eu vier aqui em Database, em Policies, a gente vai ver que tá tudo habilitado aqui, os role level security das tabelas. Quando a gente vem aqui, a gente consegue ver, né, que o nosso role level security dessa tabela que a gente criou tá aqui também. Então ele tá dando um select na UserCompany onde usuário é igual usuário logado. E tá tudo feito essa parte. Agora a nossa próxima etapa vai ser então criar a add function de webhook do Stripe. E para isso o que que a gente vai fazer? A gente vai dar um aqui, ó, Stripe Supabase add function. E a gente tem um tutorial do próprio Supabase ensinando a criar essa add function aqui. Então a gente tem até um vÃdeo do cara explicando. Como fazer essa Edge Function, mas basicamente a gente vai precisar de algumas coisas. Então aqui no Stripe a gente vai pesquisar por developers, a gente vai vir aqui em webhooks e a gente vai vir aqui em teste local list, né? Então a gente tem que dar esse Stripe login aqui primeiro. Vamos lá no nosso projeto, deixa eu abrir uma nova guia mesmo e eu vou dar um Stripe login. Eu vou copiar esse carinha e vou acessar ele por aqui nesse navegador. Então aqui ele deu um erro, ó, meu Stripe CLI não suporta logar com sandbox. Ele tá falando pra mim atualizar a minha Stripe CLI e eu vou fazer isso aqui agora. Upgrade Stripe CLI Stripe. Parece que atualizou algumas coisas e agora ele tem sandbox, antes ele tinha um test mode. Beleza, já tô com a nova versão do Stripe. Rodando. E agora então eu vou dar de novo um Stripe login, vou copiar esse carinha aqui, vou abrir em uma nova guia. E pronto, verificação recebida. Ele mandou um código para o meu e-mail, então provavelmente eu acabei de receber um código do Stripe aqui. Vou atualizar esse cara, eu posso fechar. E aà que ele tá falando para mim verificar o código que tá aparecendo, que o software, esse carinha aqui mesmo, hello access. Beleza, agora eu estou com acesso aqui do Stripe, já tá funcionando essa parte. Então o próximo passo é eu escutar aos eventos de webhook do Stripe, só que primeiro agora eu tenho que criar minha Edge Function. Então a gente vai vir aqui Eu vou abrir esse vÃdeo pra gente pegar o que a gente precisa aqui para criar nossa Edge Function. Então o setup que ele está mostrando basicamente é essa mesma coisa aqui e eu vou dar supabase functions new Stripe webhook. Ele criou, enquanto ele cria uma Edge Function do Supabase, ele cria aqui em supabase/functions stripe-webhook/index. Então nossa add function foi criada. E aà eu vou criar aqui um.env no.gitignore. Eu não sei se eu já tenho um.env aqui, mas se não tiver eu vou criar esse.env aqui para eu ignorar. Então stripe-api-key. E aà aqui agora eu vou vir no meu Stripe e vou pegar a minha API key que está em algum lugar por aqui. Publishable key. Então a gente cria o Stripe API key, a gente vai pegar o código que ele tem aqui. Eu vou pegar esse código e vou colar aqui no meu index, salvar. E basicamente o que ele tá fazendo? Ele tá pegando esse env aqui, tá criando uma nova versão do Stripe, ele tá pegando aqui a assinatura do Stripe quando a gente fizer E ele cria o evento recebido aqui e dá um console.log nesse evento quando a gente receber. Deixa eu remover esses comentários daqui que a gente não precisa. Esses comentários aqui a gente também não precisa. Então beleza, agora a gente vai voltar aqui no Stripe e a gente vai rodar esse comandinho aqui, ó, stripe listing for to, e eu vou rodar stripe listing esse carinha aqui, ó. E aà provavelmente ele vai me dar webhook secret key. Esse cara, colei aqui. Então rodamos esse carinha aqui e agora a gente precisa dar um serve na nossa Edge Function. Então a gente vai vir em supabase/functions/server/node/verify/stripe-webhooks --env file./supabase/functions/stripe-webhooks.env. Perfeito. Esse carinha aqui que a gente vai fazer para a gente iniciar o servidor desse carinha. Ele tá falando que eu não iniciei o Supabase, então eu vou dar um supabase init sim. Tá falando que esse cara já existe, supabase init, vou dar um não, não. E ele já iniciou o setup aqui e agora de novo eu vou rodar. Tá falando de Supabase Start, não tá rodando, então a gente vai dar o Supabase Start. Aqui ele tá literalmente rodando e iniciando o Supabase na minha máquina. Isso aqui, gente, é uma loucura, porque olha, ele tá baixando o Supabase e ele vai rodar o Supabase aqui na minha máquina para ele conseguir rodar essa Edge Function por aqui. Então isso aqui são praticamente os containers Docker que ele tá rodando. Então, super base push, por isso está baixando tudo. E aqui ele falou que deu um erro porque já tá um outro projeto rodando. Então eu preciso parar o projeto do Ministral. Então tô parando o projeto, meu projeto do Ministral tá parando os containers dele. Beleza, agora eu dou um super base start novamente. Show, meus amigos! Depois de um tempo a gente já tem aqui o Supabase rodando local. Na minha máquina. Então a gente tem toda essa parte aqui, eu tô rodando o Supabase na minha máquina localmente, tem tudo aqui que a gente consegue acessar. Mas agora a gente vai rodar novamente o nosso function serve e já tá funcionando. Então serve functions on esse endpoint aqui, beleza. Então agora, meus amigos, o próximo passo é a gente vir aqui no Stripe E a gente dá um trigger aqui nesse evento e a gente vê o que que acontece. Stripe trigger payment intent, tá rodando o trigger. E ó, deu um erro aqui. Quando a gente iniciar o Stripe, ele vai dar o forward to para a nossa add function. Então esse carinha aqui, function v1 Stripe webhook, beleza. Vou rodar novamente a minha function e vou dar um trigger aqui novamente pra gente ver. E ó, ele baixou alguma coisa aqui e o evento foi recebido, meus amigos. Então a gente está literalmente recebendo um evento do Stripe, que é o event received. Então a gente recebeu todos esses eventos quando a gente criou um payment intent aqui, o Stripe chamou a nossa API e a gente recebeu os eventos normalmente. Então a primeira parte já tá funcionando. Agora a gente precisa configurar esse webhook aqui não só para receber os eventos, mas para salvar no nosso banco de dados, tanto atualização de preço, atualização de produto e atualização de assinaturas. Então vamos trabalhar nesse script aqui da nossa add function. E vou mexer nessa parte aqui também. Vou dar um const WEB_SERVICE, esse carinha aqui. E agora a gente vai criar uma variável chamada relevant_events, esse carinha aqui. E a gente vai, if, a gente vai fazer um outro try-catch aqui. Switch Received Event Type. E aà a gente vai colocar e criar todos esses carinhas aqui. Perfeito. E agora a gente vai criar essas funções aqui no nosso projeto. Que eu posso tirar esse carinha daqui. Beleza. E agora a gente precisa trabalhar dentro desses carinhas aqui para a gente salvar no nosso banco de dados quando um desses eventos acontecer, tá? Então basicamente toda vez que um produto for criado, alterado, eu vou chamar esse carinha para inserir ou alterar. Quando for um preço, esse mesmo carinha para inserir ou alterar. Quando algum cliente novo for criado, excluÃdo ou atualizado, eu vou chamar esse carinha aqui. E se o checkout.session_completed for chamado, eu vou chamar essa função aqui. E vamos trabalhar nessas funções agora. Então, para essa aqui, eu vou pegar esse código, vou colar aqui, e eu tenho esse this.supabase aqui que a gente vai utilizar, só que aà a gente precisa criar a instância do Supabase, né? Então para isso eu vou criar esses carinhas aqui, a Supabase URL e a role key, e eu vou criar esse Supabase aqui. E agora já tenho esse Supabase aqui que eu consigo chamar ele dessa forma. Então basicamente toda vez que vier um produto eu coloco o ID do produto se ele tá ativo ou não, coloca os dados dele, products data, e eu dou um super base from products, passando o produto. Se tiver um erro, dou um true nele, senão eu falo que o produto foi inserido, atualizado, passando o ID do produto. Show! Mesma coisa para esse carinha aqui, só que a gente não vai usar esses tiers aqui, e eu vou criar essa interface do price data aqui, só que eu não quero os tiers. Beleza, então mesma coisa, quando vier um evento eu vou preencher todos os campos procurando por um preço. Se ele já tiver, eu coloco o ID desse preço aqui, eu posso dar um maybe single e eu passo, se o preço tiver um produto, eu passo o ID do produto e dou um upsert na nossa tabela de prices. Agora o próximo, a gente vai fazer isso aqui e eu vou, eu vou criar esse carinha aqui. ManageSubscriptionStatusChange. Vou removendo algumas coisas aqui e vai ser companyId, lembra que eu mostrei para vocês? Eu vou criar o outro carinha aqui, subscriptionData, e eu preciso agora criar essa nova const aqui, convertDate, para a gente converter a data, que é um date ou Beleza, então aqui que esse carinha vai fazer quando vier uma nova inscrição aqui, ó, eu vou vir aqui no Stripe Subscription e pegar a inscrição. Então eu vou lá na nossa tabela de customers e vou pegar o company ID baseado no nosso customer ID. Então eu tenho customer data aqui e eu tenho o company ID que eu vou passar para cá quando a gente for criar esse carinha. E eu tô passando todos os status da inscrição e eu crio o objeto dela e dou um upsert aqui. E aà esse carinha aqui eu não preciso. Então eu já tenho esse meu cara, agora falta esse aqui. A gente vai colar esse código aqui também e eu vou salvar. E esse aqui, quando o checkout for salvo, se for diferente de subscription, eu retorno. Se tiver subscription, pego o customer ID, subscription ID E eu passo para esse cara aqui de novo e ele vai lidar com toda essa parte da minha subscription. Beleza, tanta coisa aqui, né, galera? Vamos lá, então vamos parar tudo aqui, deixa eu rodar esse cara aqui de novo. E agora eu preciso do Supabase URL e o Supabase Key. Então o meu Supabase URL é esse carinha aqui e eu vou dar um Stripe trigger Product created. Tá rodando, baixou. Ele deu um erro aqui que eu não sei o que que tá acontecendo. Ele tá falando que a variável de ambiente não pode começar com supabase_. Então basicamente a gente tem que mudar a nossa aqui, app URL, app service role key, app service role key. E vamos ver se vai funcionar. E eu vou rodar aqui novamente. Beleza, tá falando que não achou o slug column aqui em products. Não tem problema, esse aqui eu posso remover porque a gente realmente não criou. E vamos rodar aqui de novo e ver. Violator role level security is not enabled for products. Então nosso role level security está funcionando. Eu copiei a minha service key errada, na verdade eu preciso da service role aqui. Esse carinha que eu preciso. Como eu disse para vocês, com a outra variável de ambiente realmente não vai funcionar. Então agora provavelmente, meus amigos, a gente vai ter um produto criado no nosso banco de dados. Eu vou dar aqui product, produto inserido ou atualizado. Então se eu vier aqui no nosso Supabase, na nossa aba de produtos, perfeito, temos um produto criado aqui. Pelo Stripe. Não sei se a gente tem preços, a gente não tem porque aqui foi só um produto criado, mas vamos criar um outro aqui. Vamos criar um Customer Subscription Create. Então vamos criar uma inscrição de teste aqui. Olha lá, não achou o lookup key, não tem problema. Vamos rodar de novo. Invalid Stripe API version. Esse carinha aqui. Vamos remover. Provavelmente aqui ele deve pegar a última. Subir de novo, ver o que que deu aqui agora. Aqui, ó, ele tá falando que eu tenho que usar a secret key do meu Stripe. Mais uma coisa para a gente alterar aqui. API keys, manage API keys. E eu tenho que usar a minha secret key, secret key de teste. Vou rodar de novo. Vou rodar, tá pegando. Ele já tá criando uma porrada de coisa. Customer not found, que o cliente não tinha sido cadastrado ainda. Mas eu creio que aqui no nosso banco de dados agora a gente já tem algumas subscriptions aqui criada, ou não. Product, price, já foi criado. Customer realmente não, ele não criou, que a gente ainda não criou nenhum customer aqui ainda pelo sistema. A gente vai criar no nosso próximo vÃdeo quando a gente tiver já com a parte do cliente cadastrado. Mas a gente sabe que já tá funcionando a parte do webhook do Stripe. Então a gente vai parar tudo isso aqui e a gente vai subir essa add function agora para o Supabase. Agora eu tô aqui com o supabase-functions deploy e vou rodar esse carinha. E ele tá me perguntando qual o projeto que eu quero mandar e eu vou selecionar esse projeto. Eu tive que rodar um supabase-login primeiro, ele mandou para o browser, fez o login, coloquei o código, deu tudo certo e foi. Então se eu der um F5 na nossa add function, agora a gente já tem uma add function aqui Eu vou copiar o URL dela, eu vou vir aqui em Developers, então Developers no Stripe, Webhooks, Add Destination. Aqui eu vou selecionar os eventos: Product Create, Update, and Delete. São esses mesmos eventos que a gente vai fazer aqui, tá? Product Create, Update, não vou usar o Deleted. Próximo é Price, então eu venho em Price aqui, Update, Checkout Session, Completed. E customer subscription created, deleted, and updated. Perfeito. Continue webhook endpoint. E aà agora eu vou pegar aqui no meu Supabase o meu endpoint do webhook, create destination, e já tá funcionando. Então se eu vier aqui agora e atualizar o meu produto Essencial, vou atualizar ele aqui, ó, Essencial. Plano essencial. E vou dar um update product. A gente precisa agora verificar na nossa edge function as invocações dela. E a gente tem aqui, ó, uma invocação. E a gente tem os logs da edge function aqui, ó. Ele tá falando que deu erro porque o Supabase URL é required e eu não passei os meus secrets. Que estão aqui, ó. O que aconteceu foi que aqui a gente já tem a Supabase URL e a service role key. Então eu não preciso criar esse carinha com meu env aqui, ó. Não preciso desses caras, Supabase service role key e Supabase URL. Ela já vem do Supabase. Que eu vou precisar criar aqui vai ser uma nova secret, Stripe API key. E eu vou colar esse carinha aqui e esse cara aqui. Save. E eu vou dar um deploy da minha função. Então agora eu já tenho meu Superbase URL, safety role key, a função já tá aqui. E agora se a gente vem no Stripe novamente, a gente atualiza o produto. Eu vou remover a descrição dele e a gente tem aqui, ó. Alguns logs e algumas invocações. Ele deu, ele retornou um 400. Se a gente ver aqui no Stripe, Developers, Webhooks, Events, ele retornou um 400. Missing Stripe webhook secret. Eu escrevi esse cara errado. Perfeito, volta aqui no Stripe. E aà eu tenho que pegar essa secret aqui, ó. Eu tava pegando errado também. Agora é a secret do próprio Stripe. Apago essa aqui. Eu vou subir a minha add function de novo. Eu acho que a gente não precisa disso, mas subindo a add function de novo. E agora mais uma vez a gente vai vir no Stripe, produtos, teste, update product. A gente vai vir em Developers, Eventos. Vou vir aqui em Eventos. Tá falando que nenhuma, não foi encontrado assinatura do Stripe. Esse carinha aqui, ó, que eu tenho que pegar. Pegado de algum outro lugar. Então, quando eu vier aqui nas minhas secrets, então, ó, tô pegando, eu vim aqui, vindo aqui no meu Webhooks, tem vários Webhooks aqui, então eu venho nesse carinha e pego esse Sign-in Secret aqui, ó. Copiei, vim aqui no Supabase, colei esse cara aqui, dei o save. Vamos subir esse cara aqui de novo. Tem quase certeza que não precisa, mas é só toque meu mesmo. E eu vou vir aqui testando, fritando mesmo. Beleza. Developers, eventos, todos os eventos. Refresh, 3:38. Deu sucesso, meus amigos! Até que enfim deu sucesso! Vou dar um refresh aqui. 200 e 200, nós temos os nossos produtos atualizados aqui. O Essential tá aqui, olha que maravilha! Meu Deus, isso aqui é muito emocionante, cara! Provavelmente vocês não vão ver todo o B.O. que foi para configurar tudo. Mas basicamente agora no Pro aqui vou fazer a mesma coisa, teste, vou dar um save e a gente vai ter o nosso Pro aqui salvo na base de dados. Se eu der um F5 na página, ele vai atualizar com Pro aqui. Perfeito. Deixa eu apagar esses outros aqui que a gente não precisa, a gente precisa só de 2 produtos. Ele tá falando que o prices aqui tá atrelado a esse carinha. Eu vou apagar os nossos preços, eu vou apagar esses produtos aqui. Show, tá atualizado. Os nossos preços, a gente não tem nada também, mas se eu vier aqui em algum preço e editar, então por exemplo, Description Pro, dá um update. A ideia é que ele apareça aqui no Supabase. E tá aqui, olha que coisa linda, gente! Então a nossa Edge Function já tá funcionando, já tá recebendo os webhooks do Stripe. Se a gente fizer qualquer um desses eventos que a gente configurou aqui, produto atualizado, preço criado, sessão completa, algum usuário que criou, atualizou ou removeu uma assinatura, a gente vai receber esses carinhas e vai atualizar no sistema. E é isso, meus amigos. Então hoje a gente viu como que a gente cria conta no Stripe, como que a gente cria um webhook usando o Edge Functions. A gente não tá criando uma API aqui, subindo, tendo que fazer o deploy e tudo mais, não. É um Edge Function que a gente costuma chamar, né, de serverless functions, que tá cuidando de toda essa parte do Stripe. Então toda vez que um produto for atualizado, um preço for atualizado, uma assinatura for atualizada, ele vai atualizar automaticamente no nosso sistema. No próximo vÃdeo a gente vai ver como que a gente vai criar o nosso usuário, criar o nosso customer lá no Stripe e criar a nossa assinatura no sistema pra gente já começar a receber o din din dos usuários. Então, gente, muito obrigado, deixa o seu like, se inscreve no canal, ativa o sininho pra não perder o próximo vÃdeo e é isso, valeu, até a próxima. Giggling-visionary.










