paint-brush
Criando interfaces de pagamento perfeitas com Stripe e FL0por@dalefl0
728 leituras
728 leituras

Criando interfaces de pagamento perfeitas com Stripe e FL0

por Dale Brett12m2023/07/31
Read on Terminal Reader

Muito longo; Para ler

Neste tutorial, exploraremos como integrar perfeitamente o gateway de pagamento Stripe em nossos aplicativos full-stack e hospedá-los sem esforço no FL0. 🚀
featured image - Criando interfaces de pagamento perfeitas com Stripe e FL0
Dale Brett HackerNoon profile picture
0-item
1-item

TL;DR

Neste tutorial, exploraremos como integrar perfeitamente o gateway de pagamento Stripe em nossos aplicativos full-stack e hospedá-los sem esforço no FL0. 🚀

Introdução

Seja um aplicativo de comércio eletrônico ou SaaS, os gateways de pagamento são um componente central de nossos projetos. 💳


Neste guia, exploraremos como simplificar essas integrações, focando especificamente no Stripe Checkout para processamento de pagamentos online.


A API amigável ao desenvolvedor do Stripe garante transações seguras e eficientes enquanto reduz nosso tempo de desenvolvimento.


Apenas por exemplo, tomamos o caso de uma página de pagamento de aplicativos SaaS.

Estaríamos usando NodeJs para o back-end e Postgres como nosso banco de dados. No frontend estamos usando ReactJs com vite .


Mais tarde, iríamos em frente e hospedaríamos sem esforço nosso projeto no FL0. ⬆️


Então, vamos começar com uma pitada de humor:

História em Quadrinhos - Compras Online

Visão geral

🧑‍💻 Neste tutorial, criaremos um aplicativo de demonstração simples onde um usuário pode se inscrever, selecionar seu plano e finalizar a compra com seu cartão de crédito.


Diagrama de Jornada do Usuário


Para isso precisaríamos criar 2 repositórios separados, um para nosso backend e outro para frontend .

Visão geral de alto nível

Estrutura de pastas

🗂️ Veja como ficariam nossas duas estruturas de pastas, apenas para referência:

Estrutura de pastas

Agora, vamos começar.

Passo 1: Configurando o Back-end

Por uma questão de eficiência, neste tutorial, usaremos o modelo " fl0zone/blog-express-pg-sequelize ".


Em seguida, removeríamos todos os arquivos ou pastas não importantes para o nosso projeto. 🧑‍💻


Para uma compreensão mais abrangente do tutorial, consulte esta postagem no blog.


Nosso modelo encapsula um aplicativo Node.js básico e um banco de dados PostgreSQL dockerizado.

Aqui está o arquivo docker-compose.yaml correspondente para nossa configuração 🐳:


 version: "3" services: app: build: context: . target: development env_file: .env volumes: - ./src:/usr/src/app/src ports: - 8081:80 depends_on: - db db: image: postgres:14 restart: always environment: POSTGRES_USER: admin POSTGRES_PASSWORD: admin POSTGRES_DB: my-startup-db volumes: - postgres-data:/var/lib/postgresql/data ports: - 5432:5432 volumes: postgres-data:


Agora iríamos em frente e instalaríamos alguns pacotes essenciais 📦


 npm install bcrypt cookie-parser cors jsonwebtoken pg-hstore stripe 

Instalando Pacotes


Agora, precisaríamos obter nossas chaves de API do Stripe 🔑. Para isso precisaríamos criar uma nova conta no Stripe.


Aqui estaríamos usando Test Mode para demonstração.


https://cdn.hackernoon.com/images/KXkBVlE3hlee3glbm70CWnLV3s32-2023-07-31T16:00:01.958Z-h2z905rjviw7ovmsinqqxj3v

Aqui está a lista de variáveis de ambiente que precisaríamos para este projeto.

.env.example


 STRIPE_PUBLISHABLE_KEY= STRIPE_SECRET_KEY= POSTGRES_DB_URI= secretKey= CLIENT_URL=

Etapa 2: Criando modelos de banco de dados

Vamos começar configurando nosso banco de dados agora. 🐘


Como estamos utilizando o Sequelize ORM, precisaremos criar um modelo para nossos dados de usuário.


Aqui está o código para o nosso modelo 👇


models/userModel.js


 module.exports = (sequelize, DataTypes) => { const User = sequelize.define( "user", { email: { type: DataTypes.STRING, unique: true, isEmail: true, //checks for email format allowNull: false, }, password: { type: DataTypes.STRING, allowNull: false, }, tier: { type: DataTypes.STRING, allowNull: true, }, }, { timestamps: true } ); return User; };

Passo 2: Configurando as Rotas

Agora, vamos em frente e criar nossas rotas


POST /login - Ajuda a logar o usuário e armazenar a sessão

POST /signup - Ajuda a criar uma nova conta

POST /create-checkout-session - Gera e retorna o link da página de check-out stripe


Essas 3 rotas são separadas em 2 arquivos da seguinte forma:


routes/userRoutes.js


 const express = require("express"); const userController = require("../controllers/userController"); const { signup, login } = userController; const userAuth = require("../middleware/userAuth"); const router = express.Router(); router.post("/signup", userAuth.saveUser, signup); router.post("/login", login); module.exports = router;


routes/stripeRoute.js


 const express = require("express"); const { updatePlan } = require("../controllers/stripeController"); const router = express.Router(); router.post("/create-checkout-session", updatePlan); module.exports = router;

Etapa 3: Configurando o perfil do usuário

🧑‍💻 Para configurar o perfil do usuário, primeiro vamos definir um middleware para verificar se o endereço de e-mail de um novo usuário já existe no banco de dados durante o cadastro.


middleware/userAuth.js


 //importing modules const express = require("express"); const db = require("../models"); const User = db.users; const saveUser = async (req, res, next) => { console.log("here"); try { const checkEmail = await User.findOne({ where: { email: req.body.email, }, }); if (checkEmail) { return res.json(409).send("Authentication failed"); } next(); } catch (error) { console.log(error); } }; module.exports = { saveUser, };


Em seguida, definimos nossas funções de login e inscrição 👇


controllers/userController.js


 const bcrypt = require("bcrypt"); const db = require("../models"); const jwt = require("jsonwebtoken"); const User = db.users; const signup = async (req, res) => { try { const { email, password } = req.body; console.log(email); const data = { email, password: await bcrypt.hash(password, 10), }; //saving the user const user = await User.create(data); if (user) { let token = jwt.sign({ id: user.id }, process.env.secretKey, { expiresIn: 1 * 24 * 60 * 60 * 1000, }); res.cookie("jwt", token, { maxAge: 1 * 24 * 60 * 60, httpOnly: true }); console.log("user", JSON.stringify(user, null, 2)); console.log(token); return res.status(201).send(user); } else { return res.status(409).send("Details are not correct"); } } catch (error) { console.log(error); } }; // Login Authentication const login = async (req, res) => { try { const { email, password } = req.body; const user = await User.findOne({ where: { email: email, }, }); if (user) { const isSame = await bcrypt.compare(password, user.password); if (isSame) { let token = jwt.sign({ id: user.id }, process.env.secretKey, { expiresIn: 1 * 24 * 60 * 60 * 1000, }); res.cookie("jwt", token, { maxAge: 1 * 24 * 60 * 60, httpOnly: true }); //send user data return res.status(201).send(user); } else { return res.status(401).send("Authentication failed"); } } else { return res.status(401).send("Authentication failed"); } } catch (error) { console.log(error); } }; module.exports = { signup, login, };

Etapa 4: Configurando o Stripe Checkout

É aqui que integraremos Stripe Checkout em nosso aplicativo.


Usaremos a Stripe API para gerenciar pagamentos e lidar com assinaturas de usuários.


O código a seguir cria uma nova sessão de checkout Stripe. 💳


Forneceremos o tipo de forma de pagamento, os dados do produto e a quantidade.


Também precisamos especificar as URLs para onde o usuário será redirecionado após um pagamento bem-sucedido ou se cancelar a transação.


E o servidor responderá com o URL da Sessão Stripe se tudo estiver correto. ✅


controllers/stripeController.js


 const db = require("../models"); const Stripe = require("stripe"); const User = db.users; require("dotenv").config(); const stripe = Stripe(process.env.STRIPE_SECRET_KEY); const updatePlan = async (req, res) => { try { const { email, product } = req.body; const session = await stripe.checkout.sessions.create({ payment_method_types: ["card"], line_items: [ { price_data: { currency: "usd", product_data: { name: product.name, }, unit_amount: product.price * 100, }, quantity: product.quantity, }, ], mode: "payment", success_url: `${process.env.CLIENT_URL}/success`, cancel_url: `${process.env.CLIENT_URL}/`, }); //find a user by their email const user = await User.findOne({ where: { email: email, }, }); if (user) { await user.update({ tier: product.name }); return res.send({ url: session.url }); } else { return res.status(401).send("User not found"); } } catch (error) { console.log(error); } }; module.exports = { updatePlan, };


Por fim, precisaríamos adicionar todas as nossas rotas ao nosso ponto de entrada, que é server.js


server.js


 const cors = require("cors"); const express = require("express"); require("dotenv").config(); const cookieParser = require("cookie-parser"); const db = require("./models"); const userRoutes = require("./routes/userRoutes"); const PORT = process.env.PORT || 8080; const stripeRoute = require("./routes/stripeRoute"); const app = express(); // Middlewares app.use(express.json()); app.use(express.urlencoded({ extended: true })); app.use(cookieParser()); app.use(cors()); // Routes app.use("/api/v1/users", userRoutes); app.use("/api/v1/stripe", stripeRoute); app.listen(PORT, () => { console.log("Server started at port 8080"); try { db.sequelize.sync({ force: true }).then(() => { console.log("db has been re sync"); }); } catch (error) {} });


E terminamos com o back-end ✅


Agora vamos em frente e tentar implantá-lo em FL0 . 🔼

Etapa 5: Implantando com FL0

🚀 Para implantar nosso projeto no FL0, começaremos empurrando nosso repositório para um novo repositório GitHub primeiro.


Este é o link para nosso repositório para referência: https://github.com/dalefl0/stripe-fl0-backend


Agora iríamos para app.fl0.dev para começar a implantação.

  • Aqui precisaríamos criar um novo projeto, vamos chamá-lo stripe-fl0 por exemplo.

  • Agora precisaríamos criar uma nova instância do Postgres. Com Fl0, isso leva menos de 30 segundos! ⏳


    Criando uma instância do postgres


  • Depois de configurar nosso banco de dados, precisaríamos prosseguir e implantar nosso back-end no mesmo projeto.


    Implantando back-end


  • Após a implantação do back-end, precisaríamos importar nossa string de conexão com o banco de dados, conforme mostrado acima ☝️


🙌 Agora temos nosso back-end instalado e funcionando.

Hora da IU ✨

Passo 6: Configurando o Front-end

Para configurar o frontend, começaríamos com o template-react-vite . ⚡️


Isso inclui tudo o que precisamos para colocar nosso projeto React-Vite em funcionamento.


Agora iríamos em frente e instalaríamos alguns pacotes.


 npm install @heroicons/react axios react-router-dom npm install postcss tailwindcss autoprefixer --save-dev 

Instalando pacotes

Passo 7: Configurando o Front-end

Para construir nossos componentes de interface do usuário rapidamente, teríamos a ajuda do Componente da seção de preços e do Componente de login e registro da IU tailwind .


Por uma questão de brevidade, veremos apenas as funções importantes do frontend.


O projeto completo pode ser encontrado em: https://github.com/dalefl0/stripe-fl0-frontend

Agora, precisaríamos adicionar uma função para lidar com check-outs de stripe


src/components/PricingPlans.jsx


 ... const handleCheckout = (product) => { axios .post( `https://stripe-fl0-backend-dev.fl0.io/api/v1/stripe/create-checkout-session`, { email, product, } ) .then((res) => { if (res.data.url) { setTier(product.name); localStorage.setItem("tier", product.name); window.location.href = res.data.url; } }) .catch((err) => navigate("/cancel")); }; ...


Essa função chama a rota /create-checkout-session de nosso back-end, recebe um link e redireciona o usuário para a página de checkout. 📄


Além disso, também precisamos conectar nossas páginas signup e login às respectivas rotas e armazenar os dados do usuário em localstorage .

Etapa 8: implantando o front-end

Para o frontend, precisaríamos criar novamente um novo repositório e implantá-lo no mesmo projeto de maneira semelhante.


Em seguida, precisaríamos adicionar a variável de ambiente VITE_APP_API_BASE_URL à implantação do front-end, que deve ser definida como a URL do nosso back-end.


Também precisaríamos definir a variável de ambiente CLIENT_URL no back-end para o URL hospedado do front-end.


Feito isso, nosso projeto FL0 ficaria assim 👇


Painel do projeto FL0


Agora, vamos em frente e experimente nosso aplicativo usando este link de demonstração ao vivo: https://stripe-fl0-frontend-q8oo-dev.fl0.io/


Demonstração ao vivo

Empacotando

Obrigado por aguentar até o final!


Neste tutorial, aprendemos como criar páginas de pagamento integrando Stripe Checkout facilmente em nossos aplicativos full-stack. 🎉


Também fizemos implantações incrivelmente rápidas de nosso projeto usando FL0.


Para começar a criar seus próprios aplicativos com recursos de pagamento, acesse fl0.com 🚀

Construindo seus próprios aplicativos com stripe