Bu eğitimde, Stripe ödeme ağ geçidini tam yığın uygulamalarımıza nasıl sorunsuz bir şekilde entegre edeceğimizi ve bunları FL0'da zahmetsizce nasıl barındıracağımızı keşfedeceğiz. 🚀
İster e-ticaret ister SaaS uygulaması olsun, ödeme ağ geçitleri projelerimizin merkezi bir bileşenidir. 💳
Bu kılavuzda, özellikle çevrimiçi ödeme işlemleri için Stripe Checkout'a odaklanarak bu entegrasyonların nasıl basitleştirileceğini keşfedeceğiz.
Stripe'ın geliştirici dostu API'si, geliştirme süremizi kısaltırken güvenli ve verimli işlemler sağlar.
Örnek olarak, SaaS uygulamalarının ödeme sayfasını ele aldık.
Arka uç için NodeJs
ve veritabanımız olarak Postgres'i kullanacağız. Ön uçta ReactJs
vite
ile kullanıyoruz.
Daha sonra devam edip projemizi FL0'da zahmetsizce barındıracaktık. ⬆️
O halde bir tutam mizahla başlayalım:
🧑💻 Bu eğitimde kullanıcının kaydolabileceği, planını seçebileceği ve kredi kartıyla ödeme yapabileceği basit bir demo uygulaması oluşturacağız.
Bunun için biri backend
, diğeri frontend
için olmak üzere 2 ayrı depo oluşturmamız gerekecek.
🗂️ Referans olması açısından her iki klasör yapımız da şu şekilde görünecektir:
Şimdi başlayalım.
Verimlilik adına bu eğitimde " fl0zone/blog-express-pg-sequelize " şablonundan yararlanacağız.
Daha sonra projemiz için önemli olmayan tüm dosya veya klasörleri kaldırırdık. 🧑💻
Öğreticinin daha kapsamlı anlaşılması için bu blog gönderisine başvurmak isteyebilirsiniz.
Şablonumuz temel bir Node.js
uygulamasını ve yerleşik bir PostgreSQL
veritabanını kapsar.
İşte kurulumumuza karşılık gelen docker-compose.yaml
dosyası 🐳:
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:
Şimdi devam edip bazı temel paketleri kuracağız 📦
npm install bcrypt cookie-parser cors jsonwebtoken pg-hstore stripe
Şimdi Stripe API anahtarlarımızı 🔑 almamız gerekiyor. Bunun için Stripe'ta yeni bir hesap oluşturmamız gerekecek.
Burada demo için Test Mode
kullanıyor olacağız.
İşte bu proje için ihtiyaç duyacağımız ortam değişkenlerinin listesi.
.env.example
STRIPE_PUBLISHABLE_KEY= STRIPE_SECRET_KEY= POSTGRES_DB_URI= secretKey= CLIENT_URL=
Şimdi veritabanımızı kurarak başlayalım. 🐘
Sequelize ORM'yi kullandığımız için kullanıcı verilerimiz için bir model oluşturmamız gerekecek.
İşte modelimizin kodu 👇
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; };
Şimdi devam edelim ve rotalarımızı oluşturalım
POST /login
- Kullanıcının oturum açmasına ve oturumu kaydetmesine yardımcı olur
POST /signup
- Yeni bir hesap oluşturmaya yardımcı olur
POST /create-checkout-session
- Şerit ödeme sayfası bağlantısını oluşturur ve döndürür
Bu 3 rota aşağıdaki gibi 2 dosyaya ayrılmıştır:
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;
🧑💻 Kullanıcı profilini ayarlamak için öncelikle kayıt sırasında yeni bir kullanıcının e-posta adresinin veritabanında mevcut olup olmadığını kontrol edecek bir ara katman yazılımı tanımlayacağız.
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, };
Daha sonra devam edip giriş ve kayıt fonksiyonlarımızı tanımlayacağız 👇
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, };
Stripe Checkout
uygulamamıza entegre edeceğimiz yer burasıdır.
Ödemeleri yönetmek ve kullanıcı aboneliklerini yönetmek için Stripe API
kullanacağız.
Aşağıdaki kod yeni bir Stripe ödeme oturumu oluşturur. 💳
Ödeme yöntemi türünü, ürün verilerini ve miktarını sağlayacağız.
Ayrıca, başarılı bir ödeme durumunda veya işlemin iptal edilmesi durumunda kullanıcının yönlendirileceği URL'leri de belirtmemiz gerekir.
Ve eğer her şey yolundaysa sunucu Stripe Oturumunun URL'siyle yanıt verecektir. ✅
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, };
Son olarak tüm rotalarımızı giriş noktamız olan server.js
eklememiz gerekecek.
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) {} });
Ve arka uçla işimiz bitti ✅
Şimdi devam edelim ve bunu FL0
üzerinde konuşlandırmayı deneyelim. 🔼
🚀 Projemizi FL0'a dağıtmak için öncelikle repo'muzu yeni bir GitHub deposuna iterek başlayacağız.
Referans için depomuzun bağlantısı budur: https://github.com/dalefl0/stripe-fl0-backend
Şimdi dağıtıma başlamak için app.fl0.dev'e gideceğiz.
Burada yeni bir proje oluşturmamız gerekecek, örneğin stripe-fl0
adını verelim.
Şimdi yeni bir Postgres örneği oluşturmamız gerekecek. Fl0 ile bu işlem 30 saniyeden kısa sürer! ⏳
Veritabanımızın tamamını kurduktan sonra, devam edip arka ucumuzu aynı projede konuşlandırmamız gerekecek.
Arka uç konuşlandırıldıktan sonra veritabanı bağlantı dizemizi yukarıda gösterildiği gibi içe aktarmamız gerekir ☝️
🙌 Artık arka ucumuz çalışır durumda.
Kullanıcı arayüzü zamanı ✨
Ön ucu ayarlamak için şablon-react-vite ile başlayacağız. ⚡️
Bu, React-Vite
projemizi çalışır duruma getirmek için ihtiyacımız olan her şeyi içerir.
Şimdi devam edip birkaç paket kuracağız.
npm install @heroicons/react axios react-router-dom npm install postcss tailwindcss autoprefixer --save-dev
Kullanıcı arayüzü bileşenlerimizi hızlı bir şekilde oluşturmak için, arka rüzgar kullanıcı arayüzündeki Fiyatlandırma Bölümü Bileşeni ve Oturum Açma ve Kayıt Bileşeninden yardım alırız.
Kısalık olması açısından sadece ön yüzün önemli işlevlerine bakacağız.
Projenin tamamı şu adreste bulunabilir: https://github.com/dalefl0/stripe-fl0-frontend
Şimdi şerit kontrollerini yönetecek bir fonksiyon eklememiz gerekecek
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")); }; ...
Bu işlev arka uçumuzun /create-checkout-session
rotasını çağırır, bir bağlantı alır ve kullanıcıyı ödeme sayfasına yönlendirir. 📄
Bunun dışında signup
ve login
sayfalarımızı da ilgili rotalara bağlamamız ve kullanıcı verilerini localstorage
saklamamız gerekiyor.
Ön uç için tekrar yeni bir depo oluşturmamız ve onu aynı projede benzer şekilde dağıtmamız gerekecek.
Daha sonra, arka ucumuzun URL'sine ayarlanması gereken ön uç dağıtımına VITE_APP_API_BASE_URL
ortam değişkenini eklememiz gerekir.
Ayrıca arka uçtaki CLIENT_URL
ortam değişkenini ön ucun barındırılan URL'sine ayarlamamız gerekir.
Tamamlandığında FL0 projemiz şöyle görünecek 👇
Şimdi devam edelim ve bu canlı demo bağlantısını kullanarak uygulamamızı deneyelim: https://stripe-fl0-frontend-q8oo-dev.fl0.io/
Sonuna kadar sadık kaldığınız için teşekkürler!
Bu eğitimde Stripe Checkout
tam kapsamlı uygulamalarımıza kolayca entegre ederek ödeme sayfalarının nasıl oluşturulacağını öğrendik. 🎉
Ayrıca projemizin dağıtımlarını FL0 kullanarak inanılmaz hızlı bir şekilde gerçekleştirdik.
Ödeme özelliklerine sahip kendi uygulamalarınızı oluşturmaya başlamak için fl0.com'a gidin 🚀