App SaaS com Next.js 15 e Stripe para receber Pagamentos

10.39k views15007 WordsCopy TextShare
Codante - Evolua no front-end
🔗 Link do projeto (e código final): https://codante.io/mini-projetos/saas-com-nextjs-e-stripe 🔗 Có...
Video Transcript:
nesse projeto a gente vai aprender como que a gente pode fazer uma aplicação como essa que é um SAS hipotético de assinatura de ebooks em que você se loga você tem um dashboard de login e você pode assinar o plano Vip usando o stripe aqui um provedor real né é claro que a gente tá no modo de teste sen não deria debitar do meu cartão de crédito mas a gente conecta o stripe na nossa aplicação a assinatura é feita a gente volta paraa dashboard e veja que agora liberou pra gente eh o painel do usuário
inclusive com detalhes da assinatura se o plano tá ativo a próxima cobrança e valor e tudo mais além de você poder atualizar M método de pagamento ou cancelar a sua assinatura e se você cancelar sua assinatura você não consegue mais acessar o livro do mês Então a gente vai fazer nesse projeto a conexão do stripe com a nossa aplicação a parte de autenticação a gente já fez num projeto anterior então ela tá pronta pra gente a gente vai pegar o repositório já com a autenticação tudo certinho A gente vai plugar agora essas páginas proteger essas
rotas e a gente vai plugar o stripe para gerenciar o nosso pagamento da nossa aplicação vamos dar uma olhada então nos requisitos desse mini projeto que estão aqui na tela Então esse é o projeto sasco nextjs esse stripe a gente vai utilizar como Framework o nextjs aqui nesse projeto e a gente vai adicionar o stripe como meio de pagamento tá o stripe é um dos maiores meios de pagamento existentes ó se a gente procurar aqui ó stripe.com é uma das se não a principal plataforma de pagamentos pela internet e O interessante é que o stripe
é muito simples de a gente implementar e a gente consegue receber e rapidamente sem muitas dores de cabeça porque implementar sistema de pagamento é um dos pontos de dor de nós deves que vamos fazer uma aplicação que tenha pagamentos online né é o o meio de pagamento a escolha do meio de pagamento é um processo às vezes um pouco difícil é um processo que leva tempo e é muitas vezes difícil de implementar mas o stripe Ele é bem facinho pra gente implementar do ponto de vista eh de desenvolvimento né então a gente vai implementar ele
aqui e essa aplicação ela tem que permitir os usuários assinar cancelar assinaturas e também alterar o meio de pagamento o produto né que é o ebook do mês é um produto hipotético Ele só pode ser exibido para aqueles que são assinantes ativos Então a gente vai fazer também o controle de rotas na nossa aplicação baseado na assinatura ativa ou não se a assinatura não tiver ativa ele não entra se tiver ativa ele consegue acessar a área protegida Então vamos dar uma olhada aqui nos requisitos né primeira coisa que é muito importante dizer a a gente
tá nesse projeto que é o Projeto 3 numa série de projetos que é esse criando um SAS com next.js Então essa aplicação que a gente está montando né Ela já foi desenvolvida em outros dois Mini projetos então o primeiro mini projeto foi a parte mais do layout né desenvolvendo a ling page o segundo mini projeto foi a parte de autenticação com next au Então veja esse mini projeto que a gente tá fazendo agora que é o mini projeto 3 que é o stripe implementação do stripe a gente já tem a autentificação pronta tá então quando
você baixar o repositório ele já tá com a autenticação pronta basta a gente plugar o stripe e programar a parte do meio de pagamento Tá então a ideia aqui não é Fazer autenticação também não é criar o layout porque isso já tá feito e a gente já fez em outros mini projetos se você tem interesse em vê-los dá uma olhada nesses outros mini projetos O link tá aqui no codante tá então antes de começar isso que eu falei a gente já tem um template Inicial pronto tá E aí a gente fazer o fork e clonar
o nosso fork pra gente rodar a gente vai utilizar aqui o Next 15 que no momento dessa gravação é super recente então Existem algumas incompatibilidades com o pacotes do Next 15 e também com o react 19 que o Next 15 já instala por padrão react 19 então agora no momento dessa instalação ainda é tudo muito novo tá depois se você não sabe o que é Tours Tours é uma base de dados online de SQL ela baseada em skite desculpa e você precisa fazer uma conta no tour se você não tiver para você usar eh a
autenticação que já está pronta tá então basta você fazer uma conta e completar o dot env né que é o arquivo de de variáveis de ambiente com essas eh credenciais que o tso lhe dá se você tiver dúvidas nisso dá uma olhada no projeto anterior que a gente explicou tudo isso tá como fazer o setup do tso e onde colocar onde pegar essas essas tokens essas chaves api e onde colocar no nosso projeto mas basicamente você vai botar no ponto Envy aqui tudo bem Depois Obviamente você pode olhar o projeto pronto também rodando tá o
setup do next out também já está pronto mas existem algumas variáveis de ambiente que você vai ter que colocar porque lembrando a gente não costuma subir variáveis de ambiente no nosso repositório do github então por isso que eu tô falando de variáveis de ambiente aqui porque o resto já tá tudo correto apenas variáveis de ambiente que precisam ser colocadas aí por você então vamos ver os requisitos aqui desse projeto primeiro faça o cadastro e setup de uma conta no stripe a primeira coisa a gente vai precisar de uma conta na stripe não precisa ser uma
conta ativa você não precisa dar muitos detalhes já para receber dinheiro porque a gente vai utilizar a conta de teste uma conta S Box tá e depois a gente vai pegar as credenciais depois implemente o pagamento recorrente da assinatura então a gente vai fazer aqui a gente vai trabalhar com assinaturas recorrentes nesse caso assinatura mensal Mas você poderia mudar Inclusive a recorrência se você quiser para anual semestral pro período que você quiser tá aqui a gente vai fazer mensal e apenas usuários logados podem assinar Então esse é um primeiro cheque que a gente tem que
ter e a gente tem que utilizar o stripe como provedor de assinaturas depois e aqui tem algumas dicas tá não vou ler elas Depois você dá uma olhada nessas dicas implemente a funcionalidade cancelamento de assinaturas implemente a funcionalidade trocar de de pagamento Ou seja eu quero trocar o meu cartão de crédito o meu cartão de crédito venceu eu posso pelo site pela nossa plataforma ali pelo SAS trocar e eu também quero proteger as rotas do ebook do mês para só poder ser acessado essa rota por quem é assinante ativo e também remover botões de assinatura
caso o usuário já seja assinante aqui é a gente tem no nosso template na nossa Landing page em todos os lugares do site um botão assine agora assine agora assine agora pra gente tentar vender a nossa assinatura quando o usuário já é assinante eu quero que esses botões não apareçam porque é poluição adicional né Não Faz Sentido um usuário que já está assinando ver ficar sendo disparado essas mensagens esses botões Call to Actions para assinar design a gente tem um design no figma tá se você quiser pode dar uma olhada mas não é necessário muito
tempo aqui se você quiser para ver o design ótimo Maravilha tá aqui nesse link mas ele não é necessário porque este projeto Já tá pronto pra gente eu vou mostrar agora na na agora em seguida é como a gente vai fazer o fork e o clone e vai ver que tudo já tá funcionando na nossa máquina tá então não precisa se preocupar que que a gente vai aprender nextjs stripe e os pré-requisitos é a gente conhecer um pouquinho de nextjs conhecer react JavaScript é claro a gente vai aprender principalmente mais sobre next e mais sobre
o stripe e a integração entre os dois belezinha espero que você esteja animado eu tô super empolgado pra gente começar essa resolução deste mini projeto estamos aqui então na página do repositório do projeto e aqui veja que já tem já existem vários arquivos Então o que a gente vai fazer é fazer o fork então fazer o fork pra minha conta criar esse fork Aqui estamos criando fork ótimo E agora eu vou pegar aqui o endereço do SSH abrir meu terminal e vou colar na vou vou fazer o Git clone no meu desktop então desktop Clone
Git Clone e vou colar esse endereço aqui estou colando dentro do meu desktop e vou fazer um code MP SAS con nextjs e stripe vou entrar nele Opa code MP SAS Connect stripe vou entrar aqui no meu vs code e aqui temos o nosso projeto que está no vs code eu vou rodar aqui o npm rev e vamos ver o que acontece ó comando não foi encontrado porque a gente não rodou o install npm install o npm e tanto faz para instalar aqui todos os pacotes vamos ver o que aconteceu tá lembrando aqui ó como
eu disse agora há um pouco tempo a gente tá usando next 15 e react 19 existem vários pacotes que ainda não dão suporte porque o react 19 tá em RC ainda não é a versão estável do react então se eu mostrar aqui ó nesse cuidado aqui ó a gente tem uma solução para esses erros que podem acontecer que é rodar o npm install traço traço Force que ele vai forçar aí não precisar fazer esse cheque de dependências que D dão esses erros né então vou rodar npm install TR Force Agora sim ele deve instalar tudo
vou dar o npm Run Dev pra gente rodar o nosso servidor vou abrir o nosso servidor e agora veja vamos ver se vai rodar URL inválido e aqui ó dentro do nosso dot env nosso ponto env aqui a gente precisa colocar aquelas urls do tso e do next out então vou fazer isso agora pra gente começar a rodar o projeto e depois aí sim a gente vai começar instalar o stripe no projeto Tudo bem então voltando Aqui estamos com o nosso repositório já com Praticamente tudo pronto vou mostrar mostrar agora assim que colocar essas urls
e ele rodando e agora é a hora de gente estudar o que a gente tem aqui o que a gente vai precisar fazer bom como a gente pode ver a gente tem esse ponto en. cop eu vou copiar Por que que ele vem pon encop porque se fosse só ponto env o nosso Git Ignore iria ignorar ó veja que o Git ignor tem um ponto env aqui para ignorar então eu vou copiar esse ponto en. copy e vou transformá-lo em ponto N veja que ele vai ficar agora ó meio apagadinho não sei se dá para
ver bem eu vou dar um zoom aqui tá vendo que o ponto en tá apagadinho isso significa que ele não está entrando no nosso controle de versão tá então a gente pode colocar aqui as nossas variáveis tranquilamente que não vamos entrar no controle de versão Então veja que eu preciso preencher essas esses dados aqui do tso e do next out o do next out é mais mais fácil tá o Next vamos começar pelo next out basicamente o que eu vou ter que colocar aqui é http 2 p bar bar local host 3000 tá quando eu
for subir isso pra produção eu vou ter que substituir para URL final isso tudo bem E aqui qualquer string serve tá isso aqui é para codificar e decodificar os dados de sessão do next out qualquer string serve agora no tso a gente precisa ter uma conta tá eu não vou explicar como fazer essa conta eu vou entrar na minha conta nos.te e vou pegar de lá os dados tudo bem Bom vou logar aqui na minha conta lar com giub mesmo Entrar em databases e eu tenho aqui o codante sas al eu vou aqui pegar em
token Create token vamos criar uma nova token aqui eu vou copiar esse arquivo aqui para a token depois eu vou trocar Claro e vou copiar a minha URL aqui pro Database URL com isso tudo deve funcionar vamos ver se tá funcionando mesmo vamos voltar pro nosso livro SAS aliás pro nosso local host 3000 e veja está funcionando só que eu tô vendo um erro aqui e g jwt s error vamos limpar os nossos cookies aqui deixa eu tirar tudo aqui Fechar todas as outras Abas e vamos limpar os cookies Clear cookie Clear Cash e vou
dar um Reload era isso mesmo era o problema de cookie porque eu acho que eu tinha na aplicação anterior enfim bom eu tô aqui na minha aplicação entãoo Esse é o é o que vem inicialmente tá que que a gente tem inicialmente ó Então a gente tem uma Landing page aqui o funcionamento ele traz pra própria Landing page a parte funciona e o preço própria L page se eu clicar aqui assim agora nada aparece agora nada aparece eu posso logar E aí eu já tenho o meu usuário porque eu já tinha criado vou clicar em
login e devo logar ó loguei Então veja que a funcionalidade login já está funcionando ó tanto é que se eu clicar aqui já aparece o meu nome então login está funcionando já vem de graça pra gente isso livro de mesa e minha assinatura também vem mas com dados todos dados escritos hardcoded né ou seja são Dados dam dados que não são reais tá nenhum desses botões funciona e o livro do mês está desprotegido veja que eu posso inclusive fazer o download desse livro aqui inclusive Esse é um livro aberto tá é um livro gratuito que
tem na internet ela com JavaScript recomendo inclusive é um livro muito bom para quem quer aprender mais a fundo ou iniciar no JavaScript Então esse é o esqueleto do nosso projeto a partir de agora a gente vai ter tudo aquilo para fazer vamos ter aqui eh colocar na proteger as rotas a gente vai ter que fazer a nossa dashboard também eh algumas páginas serem protegidas a funcionalidade de cancelar assinatura a funcionalidade de assinar quando eu clicar aqui ó em assine agora ou qualquer lugar eu poder assinar e eh cancelamento também eu paro de de de
ver essa tela que está protegida quando a minha assinatura for cancelada certo vamos começar o projeto que eu estou ansioso bom esse aqui é o site do stripe eh você deve est vendo algo parecido aí se você entrar no stripe.com e é o nosso provedor de pagamentos que a gente vai utilizar a ideia aqui é a gente criar uma conta do stripe e utilizar essa conta para receber os nossos pagamentos é claro que a gente vai usar tudo aqui no modo teste mas depois para você mudar do modo teste paraa produção e e receber de
fato pagamentos reais numa aplicação sua basta alterar duas coisinhas na sua aplicação é muito simples é tudo igual só muda o dmv você muda as chaves de ap para as chaves reais em produção Beleza então vamos aqui ó sign in vamos criar uma nova conta a gente é novo no stripe crie uma nova conta Talvez isso esteja em português para vocês Depende das configurações do navegador vou criar uma conta aqui então Vamos botar contato @code Roberto Robert cestar Brasil criei uma conta ótimo agora aqui a gente vai verificar o nosso e-mail aqui eu recebi o
meu e-mail vou verificar eu vou primeiro explorar as funcionalidades eu não quero adicionar informação de negócio explorar as funcional porque a gente vai começar a rodar aqui o quanto antes eu posso pular tudo isso ó skip and activate your account Beleza eu vou fechar essa parte aqui de ativar os pagamentos para ver se eu já consigo ótimo tá é isso que eu queria a gente tá no modo teste então a gente não precisa preencher nenhum perfil é claro se você quiser receber pagamento de verdade você vai precisar preencher tá eu tô no modo teste aqui
e agora já tá funcionando tanto é que se eu criar aqui ó e vier no meu settings eu coloco na busca aqui essa busca é muito boa vou botar Api para pegar as chaves api ó já tenho as chaves apis aqui para a gente começar a testar e a primeira coisa que a gente vai fazer é justamente colocar essa chave de api na nossa aplicação Vamos botar no nosso ponto env da nossa aplicação então eu tô aqui no ponto env e aqui que a gente vai adicionar essas chaves Então vou colocar aqui stripe eu vou
pegar aqui ó stripe publishable aqui e vou colar isso aqui e depois stripe Secret keyy e vou colar essa chave de teste aqui também veja que quando a gente tá falando das chaves secretas tem um s na frente e as chaves publishable né que são as chaves públicas tem um p de público de publicável aqui E lembrando que também temos esse teste na frente é bem importante você ter certeza que você sempre tá lidando com as chaves de teste vamos então começar a adicionar o stripe na nossa aplicação primeira coisa que eu vou fazer é
aqui no meu na minha Lib eu vou criar uma nova um novo arquivo que vai chamar stripe PTS tá E aqui eu vou de acordo com a documentação do stripe eu vou importar a classe do stripe para que ela funcione mas antes disso a gente precisa instalar o stripe né então vamos entrar aqui na documentação do stripe Então a primeira coisa a gente vai entrar no stripe vamos olhar aqui a documentação do stripe clicar aqui documentação começar a usar os pagamentos e aqui tem uma série de coisas que a gente pode fazer então tem pagamentos
presenciais que a gente não vai usar e outros produtos também que a gente não vai utilizar cenários de pagamentos aqui talvez seja importante pra gente estudar Quais são os cenários de pagamento e é importante até você ler para entender como funciona o fluxo de pagamento principalmente o fluxo dentro do stripe e aqui ó a gente vai iniciar uma integração é isso que eu quero aqui iniciar uma integração principalmente vendo aqui o checkout a gente vai utilizar o checkout do stripe para que seja mais simples é a integração tá então aqui eu quero botar para rodar
o mais rápido possível sem preocupar em muitos detalhes Então vamos lá visão geral aqui fala do checkout como que funciona o checkout e veja que em algumas páginas eu ainda tenho inglês né que que significa Ah aqui ó tradução tá pendente início rápido página hospedado pelo stripe Então você tem duas formas aqui basicamente de rodar o stripe a primeira é com páginas hospedadas pelo stripe Então você tá lá no teu botão no seu site Assine aqui quando você clica ele vai pro stripe você faz a compra no stripe depois volta pro seu site existe uma
forma um pouquinho mais moderna que é com formulários integrados esse embedded form aqui tá sem a tradução não tem ainda tradução para português mas esse formulário integrado aqui ele facilita um pouco as coisas e a gente não precisa sair da nossa plataforma para fazer o pagamento é um formulário que ele roda dentro da nossa própria plataforma e veja que aqui inclusive ele tem o Next aqui como um exemplo para usar o problema é que está usando aqui o Next na versão antiga a documentação no momento da gravação aqui desse vídeo eh a documentação do stripe
é uma documentação com pages né o do Next antes do Next 133 Então a gente vai ter que mudar algumas coisas aqui mas basicamente o que a gente tem que ver aqui são as dependências então isso aqui a gente vai instalar no nosso projeto depois e um end Point que a gente vai ter que fazer mas aqui de novo é o Next antigo né a versão antiga do Next a gente vai fazer o end Point na versão mais nova depois ter uma url de retorno isso a gente vai ter também no nosso front end do
Next uma RL de retorno então para onde vai quando deu certo depois definir o nosso produto esse produto nosso vai ser um produto recorrente né então aqui você cria um produto de teste dá para criar ex aqui mesmo né Olha que legal e depois mudar o modo né modo de subscrição porque você tem o modo de pagamento único e subscrição né então você tem o payment e subscription mode a gente vai utilizar aqui o subscription mode vai ficar cobrando o usuário correntemente por fim a gente vai montar o checkout no nosso app react loadout stripe
E aí usar o client Secret aqui inicializar o checkout e mostrar por fim uma página de retorno se deu certo ou se não deu certo certo Maravilha e aqui inclusive ele dá aqui a para colocar as variáveis de ambiente né ó é stripe Secret Key que a gente já colocou e next Public stripe publishable Key Por que isso porque isso aquii essa chave aqui strip publishable Key ela tem que estar pública para o nosso front end para o navegador então a gente coloca esse next Public na frente vamos fazer isso então aqui no nosso env
a gente vai colocar o Next Public Maravilha e agora is a chave fica pública e veja que o stripe é tão legal a documentação que tudo isso que tá mostrando aqui ó são as nossas Chaves mesmo Ó você pode dar uma olhada que é a nossa chave e a gente pode copiar e colar a nossa chave esse guia aqui é muito bom principalmente não pra gente seguir a a risca né porque tá usando a versão antiga no next Mas é muito bom pra gente seguir os passos né então setar o servidor depois setar fazer o
set do checkout depois mostrar uma página de retorno e por fim testar a nossa página a a gente vai ter um passo adicional que é proteger as nossas rotas a gente vai fazer isso também mas ah primeiro a gente precisa integrar o stripe Então vamos pro primeiro passo aqui ó que é instalar as dependências né então vou copiar aqui todas as dependências são duas dependentes o stripe e o stripe JS tá ele tá falando next aqui mas V instalar só esses dois vamos lá npm install stripe e o stripe JS Maravilha e agora a gente
vai ter que setar lá um erro Ah de novo é É aquilo do react 19 né a gente tem que agora lembrar pelo menos por enquanto npm install stripe stripe JS Force ótimo agora a gente vai lá no nosso backend e vamos instalar a parte da API Bom vamos lá então vou abrir aqui a nossa parna veja que a gente tem o nosso app aqui api e na api a gente só tem um al vamos criar uma nova pasta agora aqui que vai se chamar checkout eu vou botar entre parênteses Aliás não entre parênteses Não
eu quero que seja a rota checkout checkout e dentro dessa pasta checkout eu vou adicionar um route typescript tá então a gente vai ter uma outra rota de api que ela chama checkout agora e aqui a gente vai importar o stripe do stripe Então vamos lá Import stripe from stripe veja que é bem parecido com o que tem na documentação aqui só que ele tá usando require a gente vai usar o Import né const stripe eu vou fazer um stripe igual a new stripe e aqui no process.env P stripe Secret Key que é o que
tá no nosso env aqui para não dar erro de de Type script eu vou fazer uma coersão tá isso aqui eu quero na verdade vou usar só a rota de post veja aqui na documentação que ele mostra só a rota de post aqui do lado né até puar um pouquinho para cá veja que ele mostra só a rota de post Então vamos fazer a rota de post aqui com o novo next então Export ass function post isso é o Next né api do Next eu vou passar isso aqui para baixo ótimo e agora eu vou
seguir bem parecido com o que tá aqui na documentação tá então vamos lá ó try const session await stripe ponto e veja que aqui já me dá várias opções eu quero checkout pon sessions pon Create tá então eu vou chamar essa função aqui ó stripe checkout sessions Create veja que é aqui igual a documentação ó ó awa strip checkout sessions Create e aqui eu vou passar algumas coisas como argumento é um objeto né de configuração que eu vou passar e aqui eu passo o ui mode que vai ser embedded tá que é o nosso formulário
integrado eu tô dizendo isso agora e o Line items são os itens que eu quero vender então aqui eu vou botar um Array de itens na verdade eu quero um único objeto um único item e aqui eu vou ter a quantity que eu vou falar um porque é um objeto digital virtual e o price aqui não é o valor que a gente colocaria r$ 1 R 2,90 Não nada disso esse Price aqui é uma identificação da forma de cobrança do seu produto que você quer fazer Então veja aqui na documentação ó ele fala aqui ó
Defina um produto para vender então eu posso isso direto no no dashboard aliás eu vou fazer no dashboard que é melhor tá Vamos lá em cima stripe vamos pra página do stripe de novo vou entrar no dashboard entrar e aqui eu vou criar um preço um Na verdade eu vou criar aqui no meu catálogo de produtos melhor ainda eu vou entrar aqui no catálogo de produtos e vou criar um novo produto certo então vai ser livro SAS mensal pode ser assim assinatura mensal da plataforma livro SAS Ótimo então aqui eu estou criando o meu produto
que chama livro SAS mensal na verdade esse produto vai ser uma assinatura né então por isso aqui eu coloco recorrente o valor 29 e 90 e o período de faturamento aqui de novo trimestral anual semestral personalizado eu quero mensal eu tenho aqui mais opções de preço mas a gente não vai utilizar essas outras e opções de preços aqui tá vamos avançar Então veja que eu tenho um preço aqui ó tá que é R 29,90 por mês esse ID desse preço aqui é o que eu vou colocar aqui no meu então adicionar produto ele está adicionando
eu tenho aqui livro SAS mensal se eu clicar aqui e vier aqui ó pera aí onde que era deixa eu me lembrar aqui ó tá vendo aqui em preços ó livr SAS mensal que está ativo ven aqui em preços e coloco copiar ID do preço e aqui eu vou colar diretamente no meu Price é o ID do meu preço tá mas é claro que eu não quero deixar hardcode disso porque isso vai mudar na produção então o o que eu vou fazer é no meu ponto env eu vou colocar stripe Price id e vou colar
aqui e ali eu simplesmente coloco o process.env stripe Price ID É isso mesmo vamos só ver se é isso mesmo stripe Price ID ótimo maravilha vamos continuar então aqui a nossa documentação então a gente criou uma sessão que é embed puxar para cá Line items a gente passou o price id e aqui o mode que vem depois de Line items tá como payment mas no nosso caso vai ser subsp veja que ele tem três possibilidades payment setup e subscription payment é para um pagamento único setup é para você alterar meios de pagamento alterar a sua
conta e subscription é o que a gente quer que são pagamentos recorrentes depois a gente vai colocar Qual método de pagamento como a gente quer pagamento recorrente a gente vai querer apenas cartão de crédito então payment method payment method types a gente abre um Array e passa Card aqui veja que tem todos os tipos aqui ó ali pay coisas até que a gente não usa oxo também coisa que a gente não usa aqui no Brasil eu quero Card Maravilha quase pronto tá está faltando agora a gente colocar a nossa return URL return URL vai ser
aqui eu vou pegar dinamicamente a a nossa URL de retorno igual tá fazendo aqui na documentação ó Tá então vamos lá return URL eu vou P abrir um template Strings abrir uma variável que vai ser request P headers pget Origin então ele vai pegar Origin dos meus headers Então vai ser a URL que a gente tá trabalhando no caso de teste local host 3000 depois em produção isso já vai funcionar paraa produção também barra payment confirmation que vai ser minha rota de confirmação de pagamento e aqui eu tenho que passar como um query string como
uma uma variável adicional na minha URL o session id e esse session ID eu deixo desse jeito mesmo ó checkout session ID entre Chaves isso aqui não é do JavaScript tá eu tô passando como string mesmo veja que tá verdinho tudo mas o stripe por dentro por trás dos panos quando a gente chamar essa função Create aqui ele vai substituir e essa URL inteira com a minha session id e isso eu vou pegar lá no meu front end Quando eu tiver na minha página de retorno para que funcione tudo da forma como a gente espera
né que funcione ótimo aqui então acabei a minha session ten minha session aqui fechou agora eu vou retornar no meu post um next response que vem do Next server esse next response eu quero tornar um Jason que tenha o id o sessionid e o client Secret que vai vir dessa session aqui que a gente acabou de criar então vai gerar um client Secret client Secret que é uma senha né para essa sessão session client Secret maravilha eu vou retornar isso aqui ótimo e eu tenho depois o catch se algo der errado error return responsejson erro
status 400 certo então está pronto aqui a minha API de backend que eu vou utilizar para o meu formulário se comunicar com stripe e para que eu possa fazer livremente colocar aqui Chaves de api e tudo mais aqui vai acontecer só no servidor tá não vai acontecer no front end nada disso é vazado para o front end a não ser a resposta da minha api que é isso aqui se der certo se der errado com isso então a gente criou aqui a Nossa rota api agora até pela documentação do stripe o próximo passo é a
gente montar o nosso checkout Vamos então agora pro nosso livro SAS nossa página e aqui eu quero colocar como URL lembra que a gente fez uma página de payment confirmation então barra payment confirmation é foi só isso mesmo né payment confirmation que tem um 404 Vamos criar Então a nossa página de de confirmação para que depois dessa página a gente possa implementar o checkout normalmente Então vamos lá então pra gente criar essa página Vamos sair da pi então eu tô aqui dentro do app eu vou criar um uma nova pasta para organizar os itens do
checkout Mas eu não quero que seja uma rota Então vou botar entre parênteses vou botar checkout e aqui dentro dessa pasta checkout eu vou colocar a minha rota payment confirmation e dentro dela eu boto page.ts eu vou criar também um layout PSX Export default function layout Children aqui eu tenho Children react P react node maravilha aqui eu abro a nossa função e essa função vai retornar o nosso layout que vai ser composto de uma section que vai ter o nosso logo então eu vou pegar isso aqui da nossa layout de al aqui ó eu acho
que vai ser praticamente a mesma coisa vamos copiar igual tá tem o logo e tem o Children aqui vamos importar o link do Next link vamos importar o logo do nosso componente logo ótimo Então temos aqui o nosso nosso layout agora vamos criar a nossa página Export default ass function estamos falando de server components né checkout return page certo Vamos criar nosso checkout return page e aqui eu vou botar um return vamos começar a rodar ela aqui ó vamos botar um um card e vamos botar olá mundo só para aparecer alguma coisa beleza apareceu um
olá mundo maravilha É isso aí só que nesse Card eu vou botar um um Class name de Max wid LG depois Card content depois dentro do card cont Card header vamos importar Card content vamos importar o Card header e vamos colocar se a gente for ver o nosso figma eu vou olhar só o figma aqui pra gente ver como que é essa página aqui vamos entrar aqui no figma rapidamente pra gente ver como que é a nossa página então ele tem um assinatura confirmada um shopping bag aqui né um Icone Zinho de Shopping bag veja
que a gente tá bem próximo né disso aqui ó já temos o layout e esse texto aqui no card header então eu vou colocar um card title que vai chamar assinatura confirmada vamos aqui beleza depois eu tenho o Card description que vai ser obrigado por se juntar a nossa comunidade livro SAS ótimo e depois e a gente tem que botar um shopping bag né um Card aqui Shopping bag um um pouquinho antes do título Shopping bag no lucid react tem esse ícone ótimo que é esse aqui beleza agora depois do header a gente vai botar
uma div que vai ter um p com sua assinatura foi processada com sucesso e sua conta está ativa né da onde eu tô pegando isso aqui do nosso ST do nosso figma tá esse é o figma eu vou voltar lá vamos botar um outro p agora é só aproveitar o nosso conteúdo e no final eu vou colocar um botão aqui ainda dentro dessa div que vai ser um Button que eu posso fazer como link tá Acho que até melhor fazer como link ir para dashboard e veja que eu preciso do hrf antes dar o erro
né HF vai ser bar dashboard esse botão ele não tá estilizado E aí eu preciso estilizar ele como que eu posso fazer isso no Class name dele eu passo aqui uma variável eu chamo aquele CN do Shed CN aquela função de utilidade que a gente pode passar classes aqui e dentro dela eu passo um Button variants que tá exportado do nosso botão aqui do Shed CN ó tá E esse Button Variant é uma função e aí eu não preciso passar nada que ele abre meu botão default né padrão se eu quiser mudar o padrão do
botão eu teria que passar aqui e também eu quero passar um margem top 12 ótimo Maravilha Vamos ajeitar algumas coisas aqui no nosso no nosso Card né então V botar margem top 10 aqui para separar um pouco ótimo esse shopping bag Vamos mudar também vamos colocar um text Green 500 MX al Vamos botar marg Bottom de 4 e um tamanho de 12 Wi de 12 ótimo mais o que a gente queria no card header eu quero todo o Card header com text Center ótimo na verdade podia ser ser aqui né text Center no card tudo
é acho que não né É pode ser Tex Center no card tdo não precisar mais fazer Tex Center ótimo aqui nessa div desses textos eu quero text Grey 700 e eu vou botar um text XS SM text small aqui ótimo e aí ele vai paraa dashboard e tá funcionando Maravilha Então essa é a página de retorno a gente criou o layout dessa página de retorno só o layout por enquanto sem nada de funcionalidade porque agora o passo que a gente vai fazer é criar o checkout propriamente dito do react dentro do react n no nosso
front end Então vamos lá aqui ó vamos para o Mount checkout Então vamos instalar esses essas esses pacotes aqui V copiar lembrando de botar o force Se der algum erro de pe dependencies Maravilha instalei e agora aqui a gente vai ter que ladar o stripe pegar um client Secret aqui é quando a gente vai fazer a comunicação com o nosso backend com aquela rota P que a gente acabou de criar então a gente vai load a biblioteca do stripe a gente vai pegar o um client Secret veja ó aqui vamos voltar aqui ó deixa fechar
tudo no app checkout na nossa rota de api que a gente fez a gente criou uma sessão e depois ela devolve na nossa rota um Jason com id e com o client Secret da nossa sessão então o segredo da sessão e o ID da nossa sessão Então veja que ele ele retorna o ID então com isso a gente consegue pegar o client Secret que é essa parte aqui da documentação para inicializar o checkout certo a gente vai fazer isso na versão mais nova do stripe por isso que a gente não vai seguir muito aqui a
documentação Então vamos lá o que que eu quero fazer aqui eu quero criar um componente vamos aqui pro nosso livro SAS eu tô aqui no livro SAS vou entrar aqui na home certo eu quero que qualquer desses botões aqui assine agora ó ele me abra o checkout Então vamos ver aqui esse Price Card aqui ó Price card pricing card que é esse carinha aqui veja que ele tem um botão aqui assine agora esse botão assine agora do pricing card a gente vai mudar para que ele tenha mais funcionalidades por enquanto ele tem funcionalidade nenhuma né
veja que ele tá simplesmente com um texto aqui e não serve de nada eu tô clicando aqui não dá para ouvir Talvez mas nada está acontecendo Então o que que eu vou fazer aqui eu vou substituir esse botão por um botão um pouco mais funcional vamos fazer isso agora então vamos lá aqui vamos na nossa app aliás em components eu vou criar junto aqui com pricing Card eu vou criar um componente chama payment Button tsx certo vamos criar esse botão então Export default function payment Button e esse botão aqui vai ser cliente tá use client
vai ser um componente cliente porque ele vai ter interatividade dentro dele retornar aqui por enquanto um Button aliás vamos copiar do pricing card esse botão aqui ó Então por enquanto eu vou retornar esse mesmo botão que tava lá certo vamos voltar agora lá no nosso pricing Card e agora em vés do Button aqui eu vou tirar o Button ó veja que ele vai sair eu vou colocar o payment payment Button e passando alguma coisa veja que esse alguma coisa não está funcionando porque eu fiz um hardcoded lá que que ele tá reclamando tá ele tá
deixa eu pegar o Children porque ele não deixa pegar o Children por enquanto então vamos botar o children e aqui aliás vamos fazer por fora aqui nosso botão vai ficar até mais complexo Type payment Button props é igual um objeto que tem Children que é react react node por enquanto só isso depois vão ter mais coisas tá payment Button props Ótimo então aqui de botar agora eu passar meu Children E com isso Apareceu alguma coisa que era no pricing card que eu tinha colocado alguma coisa então botão de compra vamos botar aqui distinguir ess botão
mesmo agora não mais tratando botão mas tá tratando de um botão de compra vamos voltar payment but Aqui estamos no payment Button e aqui antes de retornar eu vou criar uma Promise con stripe Promise que vai ser load stripe process env pon next e por isso que aqui eu tive que botar next Public ó next Public stripe publishable Key eu vou botar ou nada tá esse load stripe ele vai vir do stripe JS ele não nenhuma sugestão Mas eu importo aqui Import Import load stripe from aqui @ stripe bar strip GS da onde que eu
sei da onde que eu tô tirando tudo isso aqui ó eu tô pegando da nossa documentação quer ver a gente tem a stripe Promise tá então tô seguindo a documentação aqui que é esse load stripe que eu importei do stripe JS ótimo agora eu tenho que fazer esse use callback aqui ó fatch client Secret use callback vamos copiar isso aqui vou copiar isso aqui então tô usando o US callback do react só que aqui eu vou mudar um pouco em vez de ser barapi bar checkout sessions É bar api bar checkout lembra que a gente
fez a nossa rota aqui ó app api checkout tá aqui então barra api bar checkout método é post eu vou passar o headers só para garantir que é content Type application Jason só para ter certeza que eu quero um Jason tô passando Jon aqui maravilha eu tô passando um post aqui e agora assim que eu termino eu vou receber a resposta vou transformar ela em Jason e depois o que eu tiver de dados eu vou pegar o client Secret que eu peguei lá que eu passei lá né lembra se a gente ver aqui ó a
nossa rota lembra que eu retorno um client Secret Então é isso que eu vou fazer agora pegar o client Secret mas o client Secret tá assim ó escritos client Secret underline né ó client Secret Beleza então cuidado para copiar coisas diretamente da internet né do da documentação você tem que adequar os nomes né então aqui a gente adequou a rota de api adequamos também o nome da variável client Secret isso vai rodar sem nenhuma dependência esse use callback aqui certo ótimo temos aqui essa callback agora vamos voltar na documentação eu vou passar um provider aliás
faltou uma última linha aqui né que a gente pegar esse fat client Secret e passar para um um objeto que vai chamar options vamos lá então fazer isso então esse objeto vai chamar const options vai ser o f Cent Secret na verdade que fazendo aqui aqui Cent Secret tá então eu tô criando um objeto de opções que eu vou passar esse objeto de opções aqui eu vou passar para dentro do meu embeded checkout provider que é o componente react que vai receber aqui a promise né que é da biblioteca e vai receber opções que são
essas opções aqui que é essa função aqui ó fat client Secret aqui eu poderia tudo fazer em Line mas a gente fez aqui em várias variáveis tá Tá mas tudo isso aqui que eu fiz toda essa parte de cima aqui em verde a gente fez PR adicionar aqui como como props desse componente embeded checkout provider e é esse componente que a gente vai colocar agora só que esse é um botra disso aqui é um botão Não é vamos volt para esse botão quando eu clicar esse botão eu quero que abra um modal Então vamos lá
botão de compra vai abrir o modal primeira coisa que eu tenho que fazer é instalar o dialog aqui do Shed CN então npx Shed CN add dialog beleza e aqui ele vai me dar uma mensagem acho que por causa do rect 19 ó parece usando react 19 quer usar o force sim veja que o próprio shads já já trouxe isso para instala de todo jeito vai aí ótimo instalamos o nosso modal agora aqui em vez de retornar um botão que eu tô retornando Vamos botar o parênteses aqui esse botão vai ser parte do meu dialog
não sei se você conhece o dialog dá uma olhada Como funciona o dialog mas eu vou abrir aqui um dialog que é o modal certo dentro desse dialog vai ter um dialog Trigger Cuidado para importar aqui ó que eu posso importar tanto radix como o meu que já veio do CH eu quero do CH que esse de baixo tá dialog Trigger beleza e eu vou passar para esse dialog Trigger a função child por porque eu quero que o Trigger seja Exatamente esse botão senão ele vai ficar dois botões aqui ó Então esse Trigger vai ter
um botão aqui que vai dar um Trigger do dialog beleza ótimo agora a gente tem um dialog content dialog content vamos botar uma div olá mundo deixa eu pegar da log content vamos ver se isso está funcionando ó olha que legal já funcionou aqui ó quando eu clico ele aparece um olá mundo e tem um monte de erro aqui porque esse erro Ah é por causa de acessibilidade Então esse título olá mundo a gente vai ter que colocar ele dentro Vamos fazer assim ó vou abrir aqui uma eu tenho que botar ele dentro de um
visually Hidden root aqui ó tá vendo do jeito que ele tá falando aqui então vamos lá eu vou abrir uma um fragmento isso aqui é só coisas de acessibilidade Tá eu vou pegar um vis Hidden P root tá esse vde ali ridden aqui eu vou importar do radix Ó visual ridden do radix porque o o o sheden ele usa esse aqui é sheden tá o sheden ele usa por trás dos panos o radix e alguns componentes não tem no Shed CN então não tem nada de errado se a gente instalar o componente diretamente do radix
Então vou pegar aqui ó npm install lembrando de botar o force tô instalando ótimo e aqui eu vou fazer exatamente como a documentação tá falando Vou importar o virual Hidden Isso é só questão de acessibilidade para não ter aquele erro tá então vou importar isso com virual ridden e aqui eu já tenho ven P root eu vou colocar um dialog title Vou importar aqui da log title e vamos já colocar o nome certo que vai chamar assinatura pro beleza veja que agora ele não tá me dando mais o erro aqui porque eu coloquei um título
is aqui ele tá escondido mas é um título eh para leitores de tela para quem não consegue tem dificuldade visual e tudo mais então isso aqui é uma parte deess ilidade apenas e não vai ficar visível aqui quando a gente clica tá o que vai ficar visível é justamente o a parte do stripe tá e qual que é a parte do stripe não é o Há mundo né vamos voltar aqui a parte do stripe é justamente essa aqui ó lembra que a gente tinha falado o embedded checkout provider Então vamos colocar isso aqui tudo junto
copiando e colando esse checkout provider eu vou importar do stripe vamos lá pegar aqui as importações ó copiar essas importações Maravilha ótimo E aqui lembra de novo novamente né ó eu tenho o embed checkout provider que eu passo a promise e eu passo as as opções aqui eu tenho aquele F aquela funin lá pegar da minha Api para pegar a Secret né da minha api e essa strip Promise é o própria eu abo com a chave do react do stripe vamos lá Prom com a chave dop começa uma Promise do stripe e aquelas options lá
tem aquele fat que eu acabei de falar que para pegar o Secret tudo isso a gente passa diretamente pro stripe e a gente não se preocupe em mais nada Vamos ver que que aconteceu aqui vamos lá vamos ver o que aconteceu aqui no livro SAS eu tô no meu botão de compra clico aqui Opa parece que está fazendo um loading e deu certo olha que maravilha já temos então o formulário todo pronto pra gente começar a assinar eu vou assinar com meu e-mail aqui ó Roberto Star vamos ver o que que ele vai falar aí
vamos usar o cartão 42 42 42 12 24 1 2 3 Roberto cestar Vamos botar 1225 depois eu vou salvar aqui é para que esses dados Fiquem prontos tá Fiquem sempre salvos aqui eu não precise mais colocá-los várias vezes então vou clicar em assinar que que vai acontecer vamos ver ele vai fazer a assinatura do stripe deu Ok e veio aqui assinatura confirmada certo se a gente for Então veja como é simples né a gente já já fez a a o grosso da aplicação né o grosso da do pagamento se a gente vier pro stripe
aqui ó vamos aqui no nosso dashboard do stripe vamos ver aqui na par Inicial Eu tô no dashboard tá lembrando que eu tenho que estar no modo teste transações Olha aqui que legal já tem a transação que eu acabei de fazer então se eu clicar aqui eu tenho toda tudo que aconteceu eu tenho o ID do pagamento eu tenho aqui que o pagamento foi bem sucedido os dados do cliente aqui os dados do cliente a assinatura que foi feito o ID da assinatura e veja que o stripe é muito intuitivo que eu vou clicando aqui
ó na assinatura veja que eu entro na assinatura do Roberto Cestari no livro SAS Então a gente tem um plano né que é o produto esse produto tem várias assinaturas uma assinatura para cada cliente né ou um cliente pode ter várias assinatura se ele quiser então essa assinatura com aquele ID aqui ó tá vendo aqui que tá aqui é essa daqui então tem todos os detalhes Quando que vai ser a recorrência Então ela começa dia 20 de novembro vai até 20 de dezembro a criação dela e tudo mais eu já recebi o dinheiro então a
parte mais importante está feita é claro que agora a gente vai ter que ajustar a nossa aplicação para algumas coisas mais tá mas o importante é que a assinatura foi feita agora na nossa aplicação a gente precisa Reconhecer essa assinatura e a gente precisa permitir que o usuário com a assinatura ativa consiga acessar a o nosso livro do mês e da mesma forma um usuário que não tem uma assinatura ativa ele não pode acessar a assinatura do livro do mês vamos ajustar algumas coisas mais para deixar mais Redonda a nossa aplicação do livro SAS maravilha
a gente tem aqui uma aplicação que já está funcionando parcialmente com esse botão de compra abrindo o nosso stripe agora a gente a gente precisa saber se o nosso usuário tem ou não uma assinatura ativa para que a gente libere as rotas na nossa aplicação Vamos lá fazer isso Então a primeira rota que eu quero ver é a rota do dashboard e o livro do mês essa rota aqui ó essa rota aqui ela deveria estar travada para quem não tem assinatura ativa e para quem tem assinatura ativa ela deveria estar liberada vamos lá nessa rota
então do livro do mês que tá aqui em app dashboard page Essa é a rota do livro do mês tá Tá então vamos ver aqui ó a gente tem o download do PDF e sempre que a gente abrir aqui ela vem para a rota correta acontece que antes de retornar veja que esse é um componente de servidor tá antes de retornar a gente pode colocar algo do tipo assim ó con session né await out Isso é do pra gente pegar a nossa sessão do Next auth e vamos pegar o e-mail do usuário então const user
email é igual session user. email tá ótimo se a gente tiver um e-mail maravilha se a gente não tiver a gente não vamos ver se o e-mail tá aqui se a gente não tiver é significa que o usuário não tá logado mas esse cheque de logado ou não a gente já fez lá na nossa na nossa no nosso layout aqui ó tá vendo Então com certeza todo mundo que tiver aqui nessa página ele já tá logado então isso aqui vai existir tá eu só vou mostrar aqui nosso user email só para ter certeza aqui ó
tá vendo que ele existe tá então a gente tá pegando da nossa sessão ótimo se a gente tiver uma subscription ativa vamos botar subscription aqui vamos botar true ou false por enquanto tá Se tiver uma subscription vai mostrar isso aqui se não tiver uma subscription ele vai mostrar essa daqui ó você não tem esse banner warning aqui tá Então vamos lá if vamos fazer aqui um if aqui ó a gente tem livro do mês atir daqui do H1 eu vou fazer um if né que o if não existe aqui no jsx então a gente faz
um um ternário ou qualquer coisa do tipo eu vou botar if subscription e se tiver subscrição eu quero mostrar isso certo com o download e tudo mais eu vou precisar fazer um fragmento Ótimo então se eu mudar para false aqui ó ele não mostra mais nada tá deixa eu tirar esse meu e-mail aqui não preciso mais do e-mail Se eu mudar para true el mostra o livro do mês e não só não mostra nada eu quero que mostre quando for falso eu quero que mostre um banner aqui e o botão de assinatura o card de
assinatura novamente então se for falso Vamos colocar aqui ó se não existir subscription eu quero que apareça um banner e aqui vamos botar um novo fragmento eu quero banner warning que eu tenho lá aliás eu vou pegar direto da página aqui ó e o pricing Card então tem o banner warning e o pricing Card que eu vou importar aqui maravilha então ó se subscription se eu tenho subscription apare o livro O o link para fazer o download se false não aparece nada aparece um warning Ó você precisa de uma sinatur ativa que tá o assinar
agora e com o botão de compra que eu posso comprar diretamente por aqui também que a gente já fez Então olha que legal que ficou né agora a gente precisa de uma função que vai lá no stripe olhar isso para ver se essa assinatura tá ativa ou não aqui Existem algumas estratégias que a gente pode utilizar por exemplo a gente pode marcar na nossa base de dados e isso seria o o ideal uma aplicação maior tá marcar na nossa base de dados que o usuário é pro que o usuário tem uma sinatura ativa a gente
olha na nossa base de dados se tá ele tá ativo Ok sen não não não libera mas para fins de simplicidade e como a gente quer mostrar mais o stripe aqui eu não vou fazer essa integração aqui com a base de dados a gente já tem uma base de dados o tso né só que eu vou apenas procurar diretamente no stripe se já tem essa assinatura ativa Então vamos criar essa função para ver se o usuário tem uma assinatura ativa baseado no email dele ó eu vou entrar aqui no nosso vamos fechar tudo vamos aqui
no nosso Lib no stripe aqui que eu tinha criado né esse vamos vamos criar essa função aqui ó function Aim function fetch subscription by email tá E aqui eu vou receber o e-mail que é uma string vamos abrir a função Export porque a gente vai importar lá certo então tô criando essa função fet subscription by email essa função a gente vai acessar a api do stripe tá então a primeira coisa que a gente vai fazer é acessar a parte da api que pega o customer o usuário do stripe vamos lá no stripe API documentação e
aqui ó tem a documentação do stripe deixa eu ver aqui que eu tenho aqui ó eu vou pegar essa api aqui customer para pegar o nosso usuário através do e-mail tá então eu posso pegar o retrieve customer aqui com o get que é ise aqui ó stripe customers retrieve e aqui eu tô pegando pelo id do customer Mas eu posso pegar o customer pelo e-mail usando não é o retrieve desculpa é o list aqui ó e aí eu posso passar o parâmetro tá então eu venho stripe customer list e passo como parâmetro o e-mail aqui
ó Tá então vamos fazer isso aqui ó Então vamos lá eu tenho o stripe lembra que é aquilo lá const vou fazer a mesma coisa con stripe igual New stripe process.env P stripe Secret Key ou uma string vazia esse stripe aqui vai me dar a tudo da api stripe P customers pon list E aí eu passo os parâmetros limit por exemplo quantos de customer que eu quero Eu quero um só e eu posso passar também o e-mail do usuário que eu peguei diretamente aqui na minha subscription certo uma outra coisa que eu quero trazer aqui
e mostrar que é muito legal é uma funcionalidade do stripe na api Na verdade uma funcionalidade na api do stripe que é um padrão de projeto até interessante e para aplicar nos nos projetos né de apis no backend que é e quando a gente tem relacionamento entre entre modelos então no caso do user com uma subscription o user tem várias subscription o user tem é o dados de conta uma subscription tem um plano você aqui no endpoint de customers eu tô pegando o usuário o customer mas eu quero evitar um segundo um segundo fat né
uma segunda chamada para api porque eu vou ter que pegar o usuário daí eu pego a subscrição dele o ID eu faço um outro Fed paraa subscrição para pegar os dados da subscrição porque eu quero pegar na aqui na verdade eu quero pegar subscrição e não usuário eu quero pegar a assinatura melhor dizendo né não é subscrição não existe essa palavra eu quero pegar a assinatura ativa saber se ela tá ativa ou não então eu passo aqui olha que legal eu passo um expand essa chave expand eu passo o que que eu quero expandir né
porque por padrão ele vem só o ID do subscription da assinatura mas eu quero que venha todo o objeto assinatura então vou passar aqui ó data pon subscriptions E aí ele vai mostrar todas as assinaturas do usuário e elas expandidas para que eu possa pegar se elas estão ativas ou não então vamos lá ó const customers então eu tô atribuindo a variável customers aqui e obviamente só vai ter um customers mas eu vou deixar em letra maiúscula porque isso aqui vai vir num Array tá então se não vier nenhum usuário const customers pdata a aliás
if customers pdata length igual a z0 ou seja não veio nenhum customer nenhum usuário eu vou retornar nul ou seja não existe nenhuma subscrição certo aqui tá dando erro porque faltou dar uma await aqui beleza então se eu não tiver nenhum usuário eu não retorno nenuma subscrição obviamente não ten nenhum usuário como é que eu vou ter subscrição agora se eu tenho usuri mas não tenho nenhuma subscrição customers P datata zer então eu sei que eu vou receber um único usuário né e data zero ponto subscriptions aliás eu vou até botar aqui ó const customer
é igual customers customers pdata Então o meu usuário vai tá aqui no data na chave zero então se as assinaturas tiverem o tamanho de zero eu também vou retornar nul certo ou seja se não tiver nenhuma assinatura e a assinatura vai ser justamente o customers Aliás o customer p subscript Ops P data na chave zero Ou seja eu vou ter uma assinatura por usuário isso eu posso controlar né lá no meu front por exemplo se o usuário já é assinante eu não vou deixar ele assinar mais para ter certeza que eu vou ter uma assinatura
tá então eu tô partindo desse pressuposto que eu vou ter apenas uma única assinatura tá E aqui eu retorno a subscription maravilha então tá feita a minha função aqui ó fet subscription by email agora lá na minha página do dashboard a invés de botar true ou fals na mão vamos lá no no livro SAS eu vou pegar aqui ó fetch subscription by email passando user e-mail e aqui ou vai vir uma subscrição ou não vai vir nulo né inclusive aqui é faltou uma wait aqui e aqui eu posso fazer o check porque a subscription vai
vir uma subscription do stripe ou no ou undefined então vai funcionar bem se vier a subscrição ótimo senão e não vou poder acessar e veja que aqui de fato já funcionou Deixa eu botar só o typ script aqui para ele não ficar triste veja que aqui de fato ele já funcionou significou ó tô acessando aqui significa que eu já tenho uma assinatura ativa Será que isso é verdade vamos ver aqui a minha assinatura Vamos fazer uma um cancelamento dessa assinatura vou cancelar cancelei imediatamente ó a assinatura está cancelada certo e a partir desse momento no
meu livro SAS eu não posso ter mais acesso concorda Vamos dar um Reload aqui Opa maravilha ó de Reload e não existe mais assinatura A partir do momento que eu comprar vamos ver aqui se eu colocar o código 00 vai iar ó aqui ó modo de teste ótimo Estou comprando ó vou clicar em assinar e essa página deve funcionar a partir desse momento que eu comprei assinatura confirmada vou pra dashboard e maravilha eu tenho acesso Então veja que é simples né o controle de acesso é relativamente simples ó com essa linha aqui eu sei se
o usuário tem uma assinatura ativa ou não e eu consigo controlar Praticamente tudo né o que tem aqui na plataforma se ele tem assinatura ativa ou não se ele pode comprar de novo ou não né então aquele botão aqui por exemplo a gente pode usar isso para aquele botão de assinar não aparecer mais esse botão de compra aqui vamos fazer isso então vamos lá vamos no nosso pricing Card aqui e eu não quero que esse botão apareça para quem está assinando veja que eu sou um assinante né eu assinei aqui vamos lá no pricing card
e aqui esse payment Button vai tá subscription se não tiver subscription eu mostro ele certo vamos fazer uma con subscription aqui con subscription é igual true ó Então minha subscription é true de errado se é true a subscrição não mostra ele se é false mostra ele e aqui de novo o que que eu tenho que fazer eu só substituir por R8 fetch subscription by e-mail E aí eu pego passo o e-mail do usuário então aqui eu vou fazer Todas aquelas coisas const session igual a wait out const user email é igual session user. email igualzinho
a gente fez aqui ó no na página aqui do dashboard até copiar passo o user mail para cá e maravilha a gente tem a subscription como eu já tenho assinatura ele não está mostrando nada vamos cancelar de novo a assinatura pra gente ver e agora eu vou cancelar aqui a minha assinatura e veja que eu clico aqui cancelar a assinatura imediatamente veja que agora o botão se eu dou um Reload ele aparece funcionando da forma como a gente queria vamos assinar aqui para eu mostrar mais uma coisa que está faltando é aqui no nosso livro
SAS no dashboard do livro SAS a gente precisa lá no dashboard preenche esses dados aqui da minha assinatura esses dados aqui todos estão escrito à mão se a gente for ver aqui na página de minha a minha assinatura essa página aqui como dá pra gente ver ela tem esse plan Card que é isso aqui em vermelho Esse é o plan Card e ela tem o Action Card que é o que tá em verde que é esse aqui tá vamos pro plan Card o plan Card tá aqui embaixo ó detalhes da assinatura informações seu plano atual
plano plano pro status ativo se eu botar na letra maiúscula já muda aqui na hora só que eu quero colocar isso com os dados do plano propriamente dito e não dados que estão escrito na mão para isso então eu vou passar aqui pro plan Card eu vou passar o subscription como prop e aqui eu vou colocar subscription como sendo n tá vou pedir essa permissão porque senão eu teria que tipar o subscription que é um um objeto que vem do stripe vou passar aqui então o subscript que eu já peguei aqui ó fat subscription by
email então eu coloco isso aqui na verdade eu copiei de todo aquele mesmo dado que tem todas as outras páginas né eu pego a minha sessão pego meu e-mail e uso Aquela minha função Zinha fet subscription by email passando o e-mail E aí eu tenho uma subscription e eu vou passar subscription para o plan Card passei ela aqui e agora eu tenho ela aqui posso utilizá-la para colocar o nome do plano eu vou usar aqui o subscription plan nickname E aí veja que ele veio livro SAS mensal se não vi nada aqui você significa que
o seu o seu preço lra que o preço é uma propriedade do produto né lemb Que produto noso é Liv SAS mensal V aqui no preço editar oço eí ven aqui descrição do preço Esse é o nome que vai aqui no subscription plan tá a gente tá usando esse aqui poderia usar outro também sem problema nenhum livro SAS mensal aqui no status eu vou pegar da subscription ponto status veja que já vem um status e o ativo virou Active tá em inglês eu vou depois traduzir isso para português eu vou usar uma função que traduz
tudo para português também depois a próxima cobrança e aí eu pego isso tudo a gente vê na api tá Vê e pode ver como que recebe a gente pode dar um um console log na subscription ver que que recebe aqui eu venho aqui subscription ponto current period and esse current period and aqui é um time stamp que vai vir ó tá vendo aqui ele veem um time stamp em segundos a gente vai ter que transformar isso para milissegundos para usar o new date do JavaScript pra gente poder formatar isso de uma forma melhor né então
vamos lá ó isso daqui em milissegundos eu multiplico por 1000 boto entre parênteses New date do JavaScript abro aqui E aí eu boto ponto loc date string passo pt br que é o nosso local e veja que ele vai deixar a data já da forma correta dia 20/12 de2 e 24 o valor não é 29 vamos pegar aqui ó subscription é 29 mas não é esse não é esse 29 escrito na mão pon plan P amount se eu vier aqui ele vai trazer em centavos eu preciso transformar isso para reais então eu tenho que dividir
por 100 certo vamos dividir isso por 100 e aí eu vou ter 29.9 mas eu não quero 29.9 porque isso é em inglês o ponto né é nos Estados Unidos que usa assim a gente usa vírgula usa o BRL tem uma forma fácil de fazer isso a gente pega isso aqui esse subscription plan amount vou botar entre parênteses E aí eu boto pon string posso passar o Pt Br como como primeiro argumento aqui aí eu já tenho a vírgula dá para notar que veio uma vírgula mas eu posso passar um segundo argumento que é um
objeto de configurações da International api que é a Vou até escrever aqui ó essa intl api depois dá uma olhada nela é uma adição relativamente recente mas muito boa para fazer esse tipo de coisa né formatação de número de listas de várias coisinhas interessantes aqui eu V botar Style currency e também vou colocar currency que é BRL Então veja que op veja que agora ele vai mostrar em Reais ó mostrou em reais e é isso que a gente queria e o ciclo aqui em vez de mensal eu vou colocar o subscription P plan interval o
intervalo do plano que vai vir month esse month aqui a gente vai ter que traduzir Então são duas informações que a gente vai ter que traduzir para português né Active e month vamos usar aquela aquele arquivo que chama stripts que tá lá dentro de Lib Lib stripts vamos usar esse arquinho aqui ó se entrar aqui eu vou criar uma função function Translate subscription status e aqui eu vou receber o status como string e vou retornar vou fazer um Switch Case tá então Switch status Case Active return ativo Case cancel return cancelado E aí quando a
gente for precisando de novos status a gente pode adicionar aqui e default return status para retornar o próprio status aqui aqui não tenho dois pontos Beleza então eu vou usar esse Translate subscription status ao invés de usar o status puro ali vamos lá na minha assinatura aqui vamos ver status aqui ó isso aqui eu vou botar dentro de translate subscription Ah Pera aí que faltou eu exportar Export function translate agora ele aparece aqui ó e colo o subscription status veja que o ativo vai se tornar agora ativo português com letra maiúscula do jeito que a
gente queria a mesma coisa a gente vai fazer aqui para o ciclo né então a gente vai fazer uma outra função que chama translate Export function translate subscription interval E aí de novo o intervalo string e aqui eu tô deixando dentro do stripe porque isso daqui é vem esses estados intervalos são estados intervalos que vem do stripe né às vezes em outro me de pagamento poderia vir monthly poderia ver outro vir outro nome então como vem do stripe é uma tradução especificamente pro stripe por isso que eu tô deixando aqui então mesma coisa Switch interval
Case month return mensal e Opa abrir rado aqui default return interval fechar aqui Maravilha depois a gente pode botar outros aqui se a gente quiser um plano anual casier turn anual e por aí vai essa nossa função vamos lá pra nossa página e aqui no ciclo eu vou pegar isso translate subscription interval passando o intervalo que é subscription plan interval veja que month aqui vai virar vamos ver mensal pronto a gente colocou aqui todos os dados esses dados agora vem do stripe são Dados dinâmicos e serve pra gente e falar sobre a nossa assinatura pro
nosso usuário certinho então a agora o próximo passo é a gente fazer esse botão para cancelar a nossa assinatura Bom vamos lá então no botão de cancelar assinatura A gente tá nessa mesma página aqui eh deixa eu minimizar o plan Card e veja que a gente tem esse Action Card aqui que é justamente esse card de ações vamos lá no Action Card e eu quero aqui no cancelar assinatura Eu tenho esse botão aqui todo bonito que chama cancelar assinatura é nele que a gente vai trabalhar agora pra gente utilizar o máximo do Next 14 aliás
next 15 agora a gente vai colocar esse botão envolvido num form só que esse form vai vir com letra maiúscula que vem do Next Isso é uma novidade do Next 15 hein nem no next 14 tinha esse form aqui com letra maiúscula tá Por que que a gente vai envolver esse form porque eu não quero mudar eu poderia fazer isso diretamente aqui com react Mas eu não quero eu quero usar eh a api da web mesmo eu quero usar uma submissão de formulário para cancelar essa assinatura então venho aqui e eu tenho form aqui de
cancelar assinatura ele já vai me reclamar aqui falando que ele quer uma Action Então vamos botar Action aqui e a Action desse form com letra maiúsculo é a página que a gente vai levar seja página ou seja uma função de de action de server actions enfim ou uma função qualquer que você queira rodar neste caso aqui a gente vai fazer uma server Action que eu vou chamar de cancel subscription Action então eu vou rodar uma server Action diretamente no meu form tá poderia ser com letra minúscula poderia mas com letra maiúscula é otimizado porque nem
sempre você vai querer rodar uma server Action eventualmente você vai querer mandar para uma outra página esse formulário E aí conforme com letra maiúscula você não tem aquela aquela tela que pisca né que faz o Reload com letra maiúscula ele vai fazer isso tudo essa navegação esse roteamento vai fazer no client Side e não vai a tela recarregar Então vale a pena a partir de agora no next 15 tá next 15 utilizar o form com letra maiúscula a gente não tem essa cancel subscription Action é por isso que a gente vai criar ela agora vamos
lá eu vou abrir aqui ó dentro de minha assinatura Vou botar aqui mesmo tá cancel subscription Action PTS Export assn function cancel default a Sync function Quem é seu subscription Action e eu vou passar aqui tá Então essa função que a gente vai criar agora uma server Action no next se você já está acostumado ela recebe um form data que é um form data tá aqui é uma API da web um form data Beleza ela recebe um form data que que eu vou receber nesse form data a princípio lá na minha página eu tenho apenas
um botão então não vou receber nada mas eu quero receber um dado e qual dado eu quero saber qual que é o subscription ID dessa dessa subscrição para eu poder cancelar lá no meu backend né na minha Action E para isso então eu vou botar um input Existem várias formas de fazer isso tá eu tô fazendo uma das formas mas eu vou botar um input Hidden input Hidden ou seja um input que não vai aparecer e que vai passar uma informação e nesse caso a informação é um subscription id e o vue é igual eu
vou receber também agora aqui nesse Action Card subscription subscription um n aqui e eu vou receber nesse Card um ID É isso mesmo vamos ver se isso vai funcionar beleza subscription ID subscription vamos chamar essa cancel subscription Action agora e lá na cancel subscription Action aqui eu vou dar só um console log para ver o que tá chegando console log form data ele vai receber um form data e vamos ver aqui o que que vai chegar Vamos abrir nosso terminal ó server cancel subscription Action not defined Pera aí que eu não pastar Eu tenho um
erro ainda aqui que eu coloquei aqui para receber nesse Action Card subscription mas lá em cima ó o vermelhinho aqui mostrando o erro ó bem grande aqui eu esqueci de passar o subscription para este componente Ótimo vamos ver aqui tá faltou mais uma coisa isso sempre acontece faltou a gente passar o US server porque a gente está numa server Action vamos ver agora agora vai eu vou clicar em cancelar assinatura e a partir desse momento eu vou submeter um formulário para essa Action aqui que vai dar um console log aqui no meu terminal porque é
a gente está com server components né estamos trabalhando aqui com server Actions vamos lá cancelar a assinatura e olha só que legal ele veio um form data com subscription ID pronto isso é suficiente para eu chamar a função para cancelar a assinatura lá no stripe diretamente vamos fazer isso então vamos lá na cancel subscription Action aqui eu vou pegar const subscription ID é igual form datata pget isso é da api do form data tá eu passo qual é a chave que eu quero que é subscription ID que eu passei na P input ridden vou passar
aqui como string para não dar erro de typescript porque um form data pode vir tanto uma string Como pode vir um arquivo também ou pode vir und defin e agora eu vou pegar subscription do stripe e vou cancelar ela então vou não só pegar como cancelar então con subscription é igual agora eu vou fazer um cancelamento lembra do stripe pon subscriptions ponto e aqui eu tenho cancel só que eu não tenho strip aimport stripe stripe e aqui eu vou pegar stripe iG New stripe passando process strip Secret vazia Beleza agora eu tenho o meu stripe
e eu posso cancelar vamos ver aqui ó cancel Já venho aqui cancel e eu preciso passar o quê um ID um subscription ID que é o que eu tenho aqui ó subscription ID passei subscription ID eu quero fazer mais uma coisa eu vou passar um objeto de configurações aqui que vai ser o expand lembra que eu falei do expand que ele traz outras informações eu quero que traga o consumidor também o customer aliás eu tava querendo fazer um negócio talvez depois eu use mas por enquanto não vamos vamos só cancelar aqui tá depois eu vou
dar bom só isso que eu vou fazer o que que vai acontecer aqui ele vai cancelar a minha assinatura quando eu clicar O problema é que eu quero que essa tela ela se dê um refresh né ela recarregue novamente porque isso daqui tem que sumir a partir do momento que eu tiver uma sinatura cancelada eu quero que já mostre Ó você quer comprar uma nova assinatura Você não tem nenhuma assinatura ativa você não pode est vendo essa página então eu vou usar do Next um uma função inha que chama revalidate path e eu passo qual
path que eu quero revalidar Qual a rota que eu quero revalidar e nesse caso é dashboard barra minha assinatura beleza aqui por enquanto eu não tô usando a subscription e vamos ver se isso vai funcionar ó vamos lá então cancelar a assinatura olha que maravilha já está cancelado eu já automaticamente não consigo ver essa página porque eu já tinha colocado uma proteção dessa Rota e eu cancelei a minha assinatura minha assinatura está cancelada lá no stripe e aqui na minha página eu não consigo ver mais nada se eu clicar aqui comprar novamente vamos lá assinar
Lembrando que eu tô no teste modo né Eu tô no modo testes aqui assinatura confirmada vou para dashboard consigo ver os dados da minha assinatura eu poderia até botar o ID da minha assinatura Vamos botar o ID da assinatura também só pra gente ver que são assinaturas novas vamos lá plano onde tá aqui plano Vamos criar criar mais uma aqui de plano eu vou colocar Aliás o plano em cima depois embaixo vou botar o ID da assinatura subscription plan aliás subscription ID Maravilha só que vou ter que botar bem pequeno Tex XS aí between Tex
é Center item Center só para centralizar aqui ó que tá mais alto do que aí agora centralizamos então agora eu tenho também o nosso ID veja que o final é a4l vou cancelar essa assinatura e assinar uma nova ó cancelei tô assinando uma nova assinei uma nova assinatura vou para dashboard veja que o ID é novo ou seja é uma nova assinatura que tá permitindo que eu veja essa página novamente legal né muita coisa aqui a gente fez nessas últimas duas etapas dessa parte da minha assinatura Agora falta a gente atualizar o método de pagamento
no stripe Existe uma forma mais simples do que a gente querer implementar isso na mão de mexer com cartão de crédito que é uma página do um portal do Consumidor tá então eu vou entrar lá no stripe pra gente ver ó on lá em catálogo de produtos vamos sair aqui eu vou nas minhas configurações vamos ver se eu acho aqui portal do cliente portal do cliente esse portal do cliente aqui é uma página do stripe que o cliente entra né ele vai ter eh um uma url que ele vai ver e ele vai conseguir trocar
o seu plano e tudo mais tá então eu venho aqui eu clico em Abrir o portal do cliente com link ativar link de teste e aqui eu copio esse link aqui ó tá então quando a gente vier no livro SAS aqui no atualizar método de pagamento vamos lá atualizar método de pagamento atualizar método tá aqui ó estamos aqui tá Quando a gente vem aqui isso aqui em vez de ser um botão eu vou colocar como sendo um link tá então link Maravilha tá aqui deixa eu importar o link e o hrf que tá faltando é
aquele que eu peguei que é é o portal do cliente esse aqui ó certo peguei exatamente aqui is aqui a gente tem que colocar numa variável de ambiente também porque ess aqui é do teste né lembra que em produção vai ser outro vamos lá no livro SAS quando eu clicar atualizar método de pagamento ele vai me trazer pra página que eu vou botar meu e-mail roberto@gmail.com ele vai me enviar um dado de e-mail eu preciso colocar um um cliente no modo de teste deixa eu tentar colocar o meu aqui ó contato @c.a Maravilha é porque
eu preciso para mandar para outras pessoas e-mail eu preciso e ter cadastrar Preciso terminar a configuração da minha conta Coisa que eu não fiz né a gente lembra a gente só criou a conta e boa tá recebi o e-mail aqui para fazer o login no portal do cliente e agora eu com portal do cliente eu posso fazer todas as modificações que eu queira eu posso inclusive cancelar minha assinatura por aqui eu posso atualizar as informações adicionar novas formas de pagamento novos cartões de crédito atualizar tudo eu faço aqui e eu não preciso codar isso na
minha eh página eu posso sair aqui e Maravilha uma coisa que eu quero fazer é eu preciso colocar esse link que a gente fez paraa conta do do do cliente aqui no dashboard vamos lá deixa eu até deslogue aqui pera aí aqui esse link para atualizar método de pagamento vamos entrar aqui de novo eu vou colocar como um target Blank para que ele abra numa nova aba e não feche essa minha aba certo então agora última coisa que falta é pegar esse link e botar num process.env ponto stripe Custom customer Portal URL vamos lá no
ponto env stripe Custom Portal URL e vou jogar ela aqui para que eu consiga acessar Maravilha E se eu não tiver nada ou uma string vazia aqui Ótimo vamos ver se tá tudo funcionando e agora isso daqui está dinâmico essa URL do strip para atualizar o método de pagamento porque eu estou pegando do ponto env e vamos ver funcionou Maravilha funcionou a gente tem aqui o portal da assinatura então é uma forma simples de atualizar o método de pagamento se a gente não fosse fazer por aqui a gente poderia fazer na mão mas lidar com
cartões de crédito no Fronte Exige uma série de outras precauções eh de segurança principalmente você tem que ser compliant com um monte de regra você tem que seguir uma série de regras por exemplo você não pode mandar para seu servidor os dados de cartão de crédito isso é totalmente proibido eh você não pode armazenar no seu servidor dados de pagamento como cartão de crédito a não ser que você tenha outras certificações de segurança que é não é o caso de uma um SAS pequeno tá então por isso que vale a pena quando a gente for
lidar com o cartão ou a gente faz um checkout do stripe né no nosso site que ele dá essa possibilidade foi o que a gente fez e para atualizar o pagamento a gente tá utilizando esse portal do Consumidor do próprio stripe que também ajuda a gente a não ter que fazer toda essa série de coisas em relação à segurança Tudo bem então essa página aqui está completa né agora vamos ver o que tá faltando na nossa aplicação pra gente Fin as funcionalidades por fim uma última coisa que está faltando lembra que eu retirei esse botão
que estava aqui quando a gente já é assinante eu vou tirar também toda essa C Action aqui quando a gente for assinante não precisa mostrar isso porque a pessoa já está mudando a sua vida ela já é assinante da livro Sasa vamos lá então vamos na nossa página primeira página aqui vamos procurar pronto para mudar sua vida essa section aqui ó que eu quero colocar ela deixa eu até comentar para ver se ela SA some é mas eu tirei aqui também tem o futter né essa parte aqui ó que eu vou tirar vamos ver agora
sim eu Ten o footer só que ela ficou com esse pading feio né eu vou fazer o seguinte esse pading eu vou botar dentro dessa div aqui vamos trocar esse padin aqui para dessa div só ver aqui que que tá fazendo esse espaço ficar maior é um margem top tá é top do foter Ótimo vou tirar essa margem top do footer beleza ótimo E essa div aqui vamos ver se agora é isso mesmo eu vou comentar ela vamos ver se ela sai isso Maravilha exatamente que eu quero quando então eu tiver assinatura eu não quero
mostrar essa div toda certo então aqui que que eu vou fazer vou botar subscription eu tem essa subscription lá em cima acho que não não tem eu vou ter que pegar aqui na página tá se não tiver subscription eu quero que mostre se tiver eu não quero que mostre E aí essa div toda vou dar um cont contrl x jogar aqui ótimo e a subscription eu vou ter que pegar aqui ó do mesmo jeito que eu peguei em todos os lugares Então vamos lá na minha assinatura pegar aqui a subscription vou pegar ess essas três
linhas tá jogar aqui de novo F subscription by mail ótimo olha só que maravilha veja que agora sumiu só que tá faltando o foter tem que botar um pading pading 10 tô logado tá ele apareceu como tô logado mas eu tô logado agora quando eu clicar aqui em cancelar assinatura não mais tenho assinatura lá no stripe volto paraa home e veja que agora eu tenho todos os botões assine agora assina agora e a sessão de pronto para mudar sua vida bom era isso que eu queria mostrar para vocês agora o próximo passo é a gente
fazer o Deploy quando a gente for fazer o Deploy algumas coisas para atentar primeiro essas chaves de api aqui ó tá então a gente já tinha essas quatro Maravilha isso dos outros mini projetos mas agora a gente tem essas outras Chaves api se você quiser eh fazer uma aplicação real é claro que aí você vai ter que trocar essas variáveis todas por variáveis de produção porque essas aquii são de teste tá então isso tem que ficar atento e se você for também subir isso mesmo que seja o teste por exemplo na vercel você tem que
lembrar de subir essas variáveis também que estão aqui para que a plataforma funcione normalmente né certo então é isso nossa plataforma está pronta para receber compras é claro que existem outras coisas a serem feitas nessa plataforma aqui é foi uma simplificação né Óbvio Se esse for um produto real você pode começar daqui e a partir disso melhorando ter uma melhor integração com a sua própria base de dados coisa que a gente não fez aqui também e de propósito né não fizemos isso mas é um início para a gente entender como que funciona um meio de
pagamento um SAS aqui que que é muito interessante usando o stripe que é uma plataforma a maior plataforma provavelmente de meios de pagamento para pequenas empresas online Espero que você tenha gostado Eu adorei esse caminho que a gente trilhou até aqui né foram três mini projetos um mais o layout CSS né como a gente transformado figma para essa página bonita aqui o segundo foi a parte de a parte de login com next out e o terceiro foi a parte de pagamentos com o stripe que é esse aqui que a gente acabou de finalizar a gente
se vê numa próxima e até mais
Related Videos
Copyright © 2025. Made with ♥ in London by YTScribe.com