114 lines
3.3 KiB
JavaScript
114 lines
3.3 KiB
JavaScript
var express = require("express");
|
|
var router = express.Router();
|
|
var db = require("../models");
|
|
const stripe = require("stripe")(process.env.STRIPE_TEST_KEY); // Replace with your Stripe test secret key
|
|
|
|
/* GET home page. */
|
|
router.get("/", async function (req, res, next) {
|
|
try {
|
|
const products = await db.product.findAll();
|
|
res.render("index", { title: "Products", products });
|
|
} catch (err) {
|
|
next(err);
|
|
}
|
|
});
|
|
|
|
router.get("/product/:id", async function (req, res, next) {
|
|
try {
|
|
const product = await db.product.findByPk(req.params.id);
|
|
if (!product) return res.status(404).send("Product not found");
|
|
res.render("product", { title: product.title, product });
|
|
} catch (err) {
|
|
next(err);
|
|
}
|
|
});
|
|
|
|
router.post("/buy/:id", async function (req, res, next) {
|
|
try {
|
|
const product = await db.product.findByPk(req.params.id);
|
|
if (!product) return res.status(404).send("Product not found");
|
|
const session = await stripe.checkout.sessions.create({
|
|
payment_method_types: ["card"],
|
|
line_items: [
|
|
{
|
|
price_data: {
|
|
currency: "usd",
|
|
product_data: {
|
|
name: product.title,
|
|
images: product.image ? [product.image] : [],
|
|
},
|
|
unit_amount: Math.round(product.price * 100),
|
|
},
|
|
quantity: 1,
|
|
},
|
|
],
|
|
mode: "payment",
|
|
success_url:
|
|
req.protocol +
|
|
"://" +
|
|
req.get("host") +
|
|
"/success?session_id={CHECKOUT_SESSION_ID}",
|
|
cancel_url:
|
|
req.protocol + "://" + req.get("host") + "/product/" + product.id,
|
|
});
|
|
res.redirect(303, session.url);
|
|
} catch (err) {
|
|
next(err);
|
|
}
|
|
});
|
|
|
|
router.get("/success", async function (req, res, next) {
|
|
try {
|
|
const session_id = req.query.session_id;
|
|
if (!session_id) return res.status(400).send("Missing session ID");
|
|
const session = await stripe.checkout.sessions.retrieve(session_id);
|
|
// Find or create order
|
|
let order = await db.order.findOne({ where: { stripe_id: session.id } });
|
|
if (!order) {
|
|
// Get product_id from session metadata or line_items
|
|
const lineItems = await stripe.checkout.sessions.listLineItems(
|
|
session.id,
|
|
{ limit: 1 }
|
|
);
|
|
const productName =
|
|
lineItems.data[0].description || lineItems.data[0].price.product;
|
|
const dbProduct = await db.product.findOne({
|
|
where: { title: productName },
|
|
});
|
|
await db.order.create({
|
|
product_id: dbProduct ? dbProduct.id : null,
|
|
total: session.amount_total,
|
|
stripe_id: session.id,
|
|
status: session.payment_status === "paid" ? 1 : 0,
|
|
});
|
|
}
|
|
res.render("success", { title: "Thank You", session });
|
|
} catch (err) {
|
|
next(err);
|
|
}
|
|
});
|
|
|
|
router.get("/create-product", function (req, res) {
|
|
res.render("create-product", { title: "Add Product" });
|
|
});
|
|
|
|
router.post("/create-product", async function (req, res, next) {
|
|
try {
|
|
const { title, description, price, image } = req.body;
|
|
if (!title || !description || !price) {
|
|
return res
|
|
.status(400)
|
|
.render("create-product", {
|
|
title: "Add Product",
|
|
error: "All fields except image are required.",
|
|
});
|
|
}
|
|
await db.product.create({ title, description, price, image });
|
|
res.redirect("/");
|
|
} catch (err) {
|
|
next(err);
|
|
}
|
|
});
|
|
|
|
module.exports = router;
|