টিএল; ডিআর এই টিউটোরিয়ালে, আমরা কীভাবে নির্বিঘ্নে আমাদের ফুল-স্ট্যাক অ্যাপ্লিকেশনগুলিতে স্ট্রাইপ পেমেন্ট গেটওয়েকে একীভূত করতে এবং অনায়াসে সেগুলিকে FL0-এ হোস্ট করব তা অন্বেষণ করব। 🚀 ভূমিকা এটি একটি ই-কমার্স বা SaaS অ্যাপ্লিকেশন হোক না কেন, পেমেন্ট গেটওয়ে আমাদের প্রকল্পগুলির একটি কেন্দ্রীয় উপাদান। 💳 এই নির্দেশিকাতে, আমরা এই ইন্টিগ্রেশনগুলিকে কীভাবে সরল করা যায় তা অন্বেষণ করব, বিশেষত অনলাইন জন্য স্ট্রাইপ চেকআউটের উপর ফোকাস করে৷ পেমেন্ট প্রক্রিয়াকরণের স্ট্রাইপের ডেভেলপার-বান্ধব API আমাদের বিকাশের সময় কমিয়ে নিরাপদ এবং দক্ষ লেনদেন নিশ্চিত করে। উদাহরণস্বরূপ, আমরা একটি SaaS অ্যাপ্লিকেশন পেমেন্ট পৃষ্ঠার ক্ষেত্রে নিয়েছি। আমরা আমাদের ডাটাবেস হিসাবে ব্যাকএন্ড এবং Postgres এর জন্য ব্যবহার করব। ফ্রন্টএন্ডে আমরা এর সাথে ব্যবহার করছি। NodeJs vite ReactJs পরে আমরা এগিয়ে যাব এবং অনায়াসে FL0 তে আমাদের প্রকল্প হোস্ট করব। ⬆️ সুতরাং, আসুন এক চিমটি হাস্যরস দিয়ে শুরু করি: ওভারভিউ 🧑💻 এই টিউটোরিয়ালে, আমরা একটি সাধারণ ডেমো অ্যাপ্লিকেশন তৈরি করব যেখানে একজন ব্যবহারকারী সাইন আপ করতে, তাদের প্ল্যান নির্বাচন করতে এবং তাদের ক্রেডিট কার্ড দিয়ে চেকআউট করতে পারে। এর জন্য আমাদের 2টি আলাদা রিপোজিটরি তৈরি করতে হবে, একটি আমাদের জন্য এবং আরেকটি জন্য। backend frontend ফোল্ডার স্ট্রাকচার 🗂️ এখানে আমাদের উভয় ফোল্ডার স্ট্রাকচার দেখতে কেমন হবে, শুধুমাত্র রেফারেন্সের জন্য: এখন, শুরু করা যাক. ধাপ 1: ব্যাকএন্ড সেট আপ করা দক্ষতার জন্য, এই টিউটোরিয়ালে, আমরা " " টেমপ্লেটটি ব্যবহার করব। 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= ধাপ 2: ডেটাবেস মডেল তৈরি করা এখন আমাদের ডাটাবেস সেট আপ করে শুরু করা যাক। 🐘 যেহেতু আমরা সিক্যুয়েলাইজ ওআরএম ব্যবহার করছি, তাই আমাদের ব্যবহারকারীর ডেটার জন্য একটি মডেল তৈরি করতে হবে। এখানে আমাদের মডেলের কোড 👇 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; }; ধাপ 2: রুট সেট আপ করা এখন, এগিয়ে যান এবং আমাদের রুট তৈরি করা যাক - ব্যবহারকারীকে লগ ইন করতে এবং সেশন সংরক্ষণ করতে সহায়তা করে 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; ধাপ 3: ব্যবহারকারীর প্রোফাইল সেট আপ করা 🧑💻 ব্যবহারকারী প্রোফাইল সেট আপ করার জন্য, সাইনআপের সময় ডাটাবেসে ইতিমধ্যেই একটি নতুন ব্যবহারকারীর ইমেল ঠিকানা বিদ্যমান কিনা তা পরীক্ষা করার জন্য প্রথমে আমরা একটি মিডলওয়্যার সংজ্ঞায়িত করব। 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, }; ধাপ 4: স্ট্রাইপ চেকআউট সেট আপ করা এখানেই আমরা আমাদের অ্যাপ্লিকেশনে একীভূত করব। 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 ধাপ 5: FL0 এর সাথে স্থাপন করা 🚀 আমাদের প্রজেক্টকে FL0 এ স্থাপন করার জন্য আমরা প্রথমে শুরু করব। আমাদের রেপোকে একটি নতুন GitHub সংগ্রহস্থলে ঠেলে দিয়ে এটি রেফারেন্সের জন্য আমাদের সংগ্রহস্থলের লিঙ্ক: https://github.com/dalefl0/stripe-fl0-backend এখন আমরা মোতায়েন শুরু করতে এ যাব। app.fl0.dev এখানে আমাদের একটি নতুন প্রজেক্ট তৈরি করতে হবে, উদাহরণ স্বরূপ এটির নাম দেওয়া যাক। stripe-fl0 এখন আমাদের একটি নতুন পোস্টগ্রেস উদাহরণ তৈরি করতে হবে। Fl0 এর সাথে, এটি 30 সেকেন্ডেরও কম সময় নেয়! ⏳ আমাদের ডাটাবেস সব সেট আপ করার পরে, আমাদের এগিয়ে যেতে হবে এবং একই প্রকল্পে আমাদের ব্যাকএন্ড স্থাপন করতে হবে। ব্যাকএন্ড ডিপ্লোয়ড হওয়ার পর আমাদের ডাটাবেস কানেকশন স্ট্রিং ইম্পোর্ট করতে হবে যেমন উপরে দেখানো হয়েছে ☝️ 🙌 এখন আমরা আমাদের ব্যাকএন্ড আপ এবং চলমান আছে. UI এর জন্য সময় ✨ ধাপ 6: ফ্রন্টএন্ড সেট আপ করা ফ্রন্টএন্ড সেট আপ করার জন্য আমরা দিয়ে শুরু করব। ⚡️ টেমপ্লেট-প্রতিক্রিয়া-vite আমাদের প্রজেক্ট চালু করার জন্য যা যা প্রয়োজন তার মধ্যে রয়েছে। React-Vite এখন আমরা এগিয়ে যাব এবং কয়েকটি প্যাকেজ ইনস্টল করব। npm install @heroicons/react axios react-router-dom npm install postcss tailwindcss autoprefixer --save-dev ধাপ 7: ফ্রন্টএন্ড সেট আপ করা আমাদের 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 ধাপ 8: ফ্রন্টএন্ড স্থাপন করা ফ্রন্টএন্ডের জন্য আমাদের আবার একটি নতুন তৈরি করতে হবে এবং একই প্রকল্পে একই পদ্ধতিতে এটি স্থাপন করতে হবে। সংগ্রহস্থল আমাদের তখন ফ্রন্টএন্ড ডিপ্লয়মেন্টে এনভায়রনমেন্ট ভেরিয়েবল যোগ করতে হবে যা আমাদের ব্যাকএন্ডের URL-এ সেট করা উচিত। VITE_APP_API_BASE_URL আমাদের ব্যাকএন্ডে এনভায়রনমেন্ট ভেরিয়েবলকে ফ্রন্টএন্ডের হোস্ট করা URL-এ সেট করতে হবে। CLIENT_URL একবার হয়ে গেলে, আমাদের FL0 প্রজেক্টটি এরকম দেখাবে 👇 এখন, আসুন এগিয়ে যান এবং এই লাইভ ডেমো লিঙ্কটি ব্যবহার করে আমাদের অ্যাপ্লিকেশন চেষ্টা করুন: https://stripe-fl0-frontend-q8oo-dev.fl0.io/ মোড়ক উম্মচন শেষ পর্যন্ত লেগে থাকার জন্য ধন্যবাদ! এই টিউটোরিয়ালে, আমরা শিখেছি কীভাবে আমাদের ফুল-স্ট্যাক অ্যাপ্লিকেশনগুলিতে সহজেই একীভূত করে পেমেন্ট পেজ তৈরি করতে হয়। 🎉 Stripe Checkout আমরা FL0 ব্যবহার করে আমাদের প্রজেক্টের উজ্জ্বল-দ্রুত স্থাপনাও করেছি। অর্থপ্রদানের ক্ষমতা সহ আপনার নিজস্ব অ্যাপ্লিকেশন তৈরি করা শুরু করতে, fl0.com এ যান 🚀