এই টিউটোরিয়ালে, আমরা কীভাবে নির্বিঘ্নে আমাদের ফুল-স্ট্যাক অ্যাপ্লিকেশনগুলিতে স্ট্রাইপ পেমেন্ট গেটওয়েকে একীভূত করতে এবং অনায়াসে সেগুলিকে FL0-এ হোস্ট করব তা অন্বেষণ করব। 🚀
এটি একটি ই-কমার্স বা SaaS অ্যাপ্লিকেশন হোক না কেন, পেমেন্ট গেটওয়ে আমাদের প্রকল্পগুলির একটি কেন্দ্রীয় উপাদান। 💳
এই নির্দেশিকাতে, আমরা এই ইন্টিগ্রেশনগুলিকে কীভাবে সরল করা যায় তা অন্বেষণ করব, বিশেষত অনলাইন পেমেন্ট প্রক্রিয়াকরণের জন্য স্ট্রাইপ চেকআউটের উপর ফোকাস করে৷
স্ট্রাইপের ডেভেলপার-বান্ধব API আমাদের বিকাশের সময় কমিয়ে নিরাপদ এবং দক্ষ লেনদেন নিশ্চিত করে।
উদাহরণস্বরূপ, আমরা একটি SaaS অ্যাপ্লিকেশন পেমেন্ট পৃষ্ঠার ক্ষেত্রে নিয়েছি।
আমরা আমাদের ডাটাবেস হিসাবে ব্যাকএন্ড এবং Postgres এর জন্য NodeJs
ব্যবহার করব। ফ্রন্টএন্ডে আমরা vite
এর সাথে ReactJs
ব্যবহার করছি।
পরে আমরা এগিয়ে যাব এবং অনায়াসে FL0 তে আমাদের প্রকল্প হোস্ট করব। ⬆️
সুতরাং, আসুন এক চিমটি হাস্যরস দিয়ে শুরু করি:
🧑💻 এই টিউটোরিয়ালে, আমরা একটি সাধারণ ডেমো অ্যাপ্লিকেশন তৈরি করব যেখানে একজন ব্যবহারকারী সাইন আপ করতে, তাদের প্ল্যান নির্বাচন করতে এবং তাদের ক্রেডিট কার্ড দিয়ে চেকআউট করতে পারে।
এর জন্য আমাদের 2টি আলাদা রিপোজিটরি তৈরি করতে হবে, একটি আমাদের backend
জন্য এবং আরেকটি frontend
জন্য।
🗂️ এখানে আমাদের উভয় ফোল্ডার স্ট্রাকচার দেখতে কেমন হবে, শুধুমাত্র রেফারেন্সের জন্য:
এখন, শুরু করা যাক.
দক্ষতার জন্য, এই টিউটোরিয়ালে, আমরা " fl0zone/blog-express-pg-sequelize " টেমপ্লেটটি ব্যবহার করব।
তারপরে আমরা আমাদের প্রকল্পের জন্য গুরুত্বপূর্ণ নয় এমন কোনো ফাইল বা ফোল্ডার মুছে ফেলব। 🧑💻
টিউটোরিয়ালের আরও বিস্তৃত বোঝার জন্য, আপনি এই ব্লগ পোস্টটি উল্লেখ করতে চাইতে পারেন।
আমাদের টেমপ্লেট একটি মৌলিক Node.js
অ্যাপ্লিকেশন এবং একটি ডকারাইজড PostgreSQL
ডাটাবেসকে অন্তর্ভুক্ত করে।
এখানে আমাদের সেটআপের জন্য সংশ্লিষ্ট docker-compose.yaml
ফাইল রয়েছে 🐳:
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:
এখন আমরা এগিয়ে যাব এবং কিছু প্রয়োজনীয় প্যাকেজ ইনস্টল করব 📦
npm install bcrypt cookie-parser cors jsonwebtoken pg-hstore stripe
এখন, আমাদের স্ট্রাইপ এপিআই কী 🔑 পেতে হবে। এর জন্য আমাদের স্ট্রাইপে একটি নতুন অ্যাকাউন্ট তৈরি করতে হবে।
এখানে আমরা ডেমোর জন্য Test Mode
ব্যবহার করব।
এই প্রকল্পের জন্য আমাদের প্রয়োজন হবে এমন পরিবেশ ভেরিয়েবলের তালিকা এখানে রয়েছে।
.env.example
STRIPE_PUBLISHABLE_KEY= STRIPE_SECRET_KEY= POSTGRES_DB_URI= secretKey= CLIENT_URL=
এখন আমাদের ডাটাবেস সেট আপ করে শুরু করা যাক। 🐘
যেহেতু আমরা সিক্যুয়েলাইজ ওআরএম ব্যবহার করছি, তাই আমাদের ব্যবহারকারীর ডেটার জন্য একটি মডেল তৈরি করতে হবে।
এখানে আমাদের মডেলের কোড 👇
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; };
এখন, এগিয়ে যান এবং আমাদের রুট তৈরি করা যাক
POST /login
- ব্যবহারকারীকে লগ ইন করতে এবং সেশন সংরক্ষণ করতে সহায়তা করে
POST /signup
- একটি নতুন অ্যাকাউন্ট তৈরি করতে সাহায্য করে
POST /create-checkout-session
- স্ট্রাইপ চেকআউট পৃষ্ঠার লিঙ্ক তৈরি করে এবং ফেরত দেয়
এই 3টি রুটকে নিম্নরূপ 2টি ফাইলে বিভক্ত করা হয়েছে:
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;
🧑💻 ব্যবহারকারী প্রোফাইল সেট আপ করার জন্য, সাইনআপের সময় ডাটাবেসে ইতিমধ্যেই একটি নতুন ব্যবহারকারীর ইমেল ঠিকানা বিদ্যমান কিনা তা পরীক্ষা করার জন্য প্রথমে আমরা একটি মিডলওয়্যার সংজ্ঞায়িত করব।
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, };
তারপরে আমরা এগিয়ে যাব এবং আমাদের লগইন এবং সাইনআপ ফাংশনগুলি সংজ্ঞায়িত করব 👇
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
একীভূত করব।
আমরা পেমেন্ট পরিচালনা করতে এবং ব্যবহারকারীর সদস্যতা পরিচালনা করতে Stripe API
ব্যবহার করব।
নিম্নলিখিত কোডটি একটি নতুন স্ট্রাইপ চেকআউট সেশন তৈরি করে। 💳
আমরা এটিকে অর্থপ্রদানের পদ্ধতির ধরন, পণ্যের ডেটা এবং পরিমাণ প্রদান করব।
আমাদের সেই URLগুলিও নির্দিষ্ট করতে হবে যেখানে ব্যবহারকারীকে সফল অর্থপ্রদানের পরে পুনঃনির্দেশিত করা হবে বা তারা লেনদেন বাতিল করলে।
এবং, সবকিছু ঠিক থাকলে সার্ভার স্ট্রাইপ সেশনের URL-এর সাথে প্রতিক্রিয়া জানাবে। ✅
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, };
শেষ পর্যন্ত, আমাদের সমস্ত রুটগুলিকে আমাদের এন্ট্রি পয়েন্টে যুক্ত করতে হবে, যা হল 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) {} });
এবং আমরা ব্যাকএন্ড দিয়ে সম্পন্ন করেছি ✅
এখন এগিয়ে যান এবং এটি FL0
এ স্থাপন করার চেষ্টা করুন। 🔼
🚀 আমাদের প্রজেক্টকে FL0 এ স্থাপন করার জন্য আমরা প্রথমে আমাদের রেপোকে একটি নতুন GitHub সংগ্রহস্থলে ঠেলে দিয়ে শুরু করব।
এটি রেফারেন্সের জন্য আমাদের সংগ্রহস্থলের লিঙ্ক: https://github.com/dalefl0/stripe-fl0-backend
এখন আমরা মোতায়েন শুরু করতে app.fl0.dev এ যাব।
এখানে আমাদের একটি নতুন প্রজেক্ট তৈরি করতে হবে, উদাহরণ স্বরূপ এটির নাম stripe-fl0
দেওয়া যাক।
এখন আমাদের একটি নতুন পোস্টগ্রেস উদাহরণ তৈরি করতে হবে। Fl0 এর সাথে, এটি 30 সেকেন্ডেরও কম সময় নেয়! ⏳
আমাদের ডাটাবেস সব সেট আপ করার পরে, আমাদের এগিয়ে যেতে হবে এবং একই প্রকল্পে আমাদের ব্যাকএন্ড স্থাপন করতে হবে।
ব্যাকএন্ড ডিপ্লোয়ড হওয়ার পর আমাদের ডাটাবেস কানেকশন স্ট্রিং ইম্পোর্ট করতে হবে যেমন উপরে দেখানো হয়েছে ☝️
🙌 এখন আমরা আমাদের ব্যাকএন্ড আপ এবং চলমান আছে.
UI এর জন্য সময় ✨
ফ্রন্টএন্ড সেট আপ করার জন্য আমরা টেমপ্লেট-প্রতিক্রিয়া-vite দিয়ে শুরু করব। ⚡️
আমাদের React-Vite
প্রজেক্ট চালু করার জন্য যা যা প্রয়োজন তার মধ্যে রয়েছে।
এখন আমরা এগিয়ে যাব এবং কয়েকটি প্যাকেজ ইনস্টল করব।
npm install @heroicons/react axios react-router-dom npm install postcss tailwindcss autoprefixer --save-dev
আমাদের UI উপাদানগুলি দ্রুত তৈরি করতে আমরা tailwind UI থেকে প্রাইসিং সেকশন কম্পোনেন্ট এবং সাইন-ইন এবং রেজিস্ট্রেশন কম্পোনেন্টের সাহায্য নেব।
সংক্ষিপ্ততার জন্য, আমরা শুধুমাত্র ফ্রন্টএন্ডের গুরুত্বপূর্ণ ফাংশনগুলি দেখব।
সম্পূর্ণ প্রকল্পটি এখানে পাওয়া যেতে পারে: https://github.com/dalefl0/stripe-fl0-frontend
এখন, স্ট্রাইপ চেকআউটগুলি পরিচালনা করার জন্য আমাদের একটি ফাংশন যুক্ত করতে হবে
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")); }; ...
এই ফাংশনটি আমাদের ব্যাকএন্ডের /create-checkout-session
রুটকে কল করে, একটি লিঙ্ক গ্রহণ করে এবং ব্যবহারকারীকে চেকআউট পৃষ্ঠায় পুনঃনির্দেশ করে। 📄
এর পাশাপাশি, আমাদের signup
এবং login
পৃষ্ঠাগুলিকে সংশ্লিষ্ট রুটে সংযুক্ত করতে হবে এবং localstorage
ব্যবহারকারীর ডেটা সংরক্ষণ করতে হবে।
ফ্রন্টএন্ডের জন্য আমাদের আবার একটি নতুন সংগ্রহস্থল তৈরি করতে হবে এবং একই প্রকল্পে একই পদ্ধতিতে এটি স্থাপন করতে হবে।
আমাদের তখন ফ্রন্টএন্ড ডিপ্লয়মেন্টে VITE_APP_API_BASE_URL
এনভায়রনমেন্ট ভেরিয়েবল যোগ করতে হবে যা আমাদের ব্যাকএন্ডের URL-এ সেট করা উচিত।
আমাদের ব্যাকএন্ডে CLIENT_URL
এনভায়রনমেন্ট ভেরিয়েবলকে ফ্রন্টএন্ডের হোস্ট করা URL-এ সেট করতে হবে।
একবার হয়ে গেলে, আমাদের FL0 প্রজেক্টটি এরকম দেখাবে 👇
এখন, আসুন এগিয়ে যান এবং এই লাইভ ডেমো লিঙ্কটি ব্যবহার করে আমাদের অ্যাপ্লিকেশন চেষ্টা করুন: https://stripe-fl0-frontend-q8oo-dev.fl0.io/
শেষ পর্যন্ত লেগে থাকার জন্য ধন্যবাদ!
এই টিউটোরিয়ালে, আমরা শিখেছি কীভাবে আমাদের ফুল-স্ট্যাক অ্যাপ্লিকেশনগুলিতে Stripe Checkout
সহজেই একীভূত করে পেমেন্ট পেজ তৈরি করতে হয়। 🎉
আমরা FL0 ব্যবহার করে আমাদের প্রজেক্টের উজ্জ্বল-দ্রুত স্থাপনাও করেছি।
অর্থপ্রদানের ক্ষমতা সহ আপনার নিজস্ব অ্যাপ্লিকেশন তৈরি করা শুরু করতে, fl0.com এ যান 🚀