Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Payment using stripe #103

Open
wants to merge 3 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
149 changes: 63 additions & 86 deletions controllers/orderController.js
Original file line number Diff line number Diff line change
@@ -1,145 +1,122 @@
const Order = require('../models/order');
const Cart = require('../models/cart');
const User = require('../models/user');
const mongoose = require('mongoose');
const Book = require('../models/book');
require('dotenv').config();
const stripe = require('stripe')(process.env.STRIPE_SECRET_KEY);
// Display list of all Orders.
exports.order_list = async (req, res) => {
try {
const cart = await Cart.findOne({ user: req.user._id }).populate('books');
const cart = await Cart.findOne({ user: req.user._id }).populate(
'books',
);
const user = await User.findById(req.user._id);

let wallet_amount = user.wallet_amount;
let total_price = 0;
cart.books.forEach(book => {
cart.books.forEach((book) => {
total_price += book.price;
});

// render checkout view
res.render('checkout', { cart, total_price, wallet_amount });
}
catch(err) {
} catch (err) {
console.log(err);
res.status(500).json(err);
}
};


// ...

// Handle Order create on POST.
exports.order_create_post = async (req, res) => {
// Start a new session for the transaction
const session = await mongoose.startSession();
session.startTransaction();

try {
console.log('Creating order')
const cart = await Cart.findOne({ user: req.user._id }).populate('books');
let total_price = 0;
for (let book of cart.books) {
total_price += book.price;
}
console.log('Creating order');
const cart = await Cart.findOne({ user: req.user._id }).populate(
'books',
);

const user = await User.findById(req.user._id);
if (user.wallet_amount < total_price) {
req.flash('error', 'Insufficient funds in wallet');
res.redirect('back');
if (!cart || !Array.isArray(cart.books)) {
res.status(400).send('Cart is not properly defined');
return;
}

// decrement the quantity of each book in the cart
for (let book of cart.books) {
book.quantity -= 1;
await book.save({ session });
}
const stripe_session = await stripe.checkout.sessions.create({
payment_method_types: ['card'],
mode: 'payment',
line_items: cart.books.map((book) => {
return {
price_data: {
currency: 'usd',
product_data: {
name: book.title,
},
unit_amount: Math.round(book.price * 100),
},
quantity: 1,
};
}),
success_url: `${process.env.DOMAIN}/orders/mybooks`,
cancel_url: `${process.env.DOMAIN}/orders/`,
});

// for each seller in the cart, give them 97% of the total price of their books
let sellers = [];
let total_price = 0;
for (let book of cart.books) {
if (!sellers.includes(book.seller)) {
sellers.push(book.seller);
}
}

for (let seller of sellers) {
let seller_total = 0;
for (let book of cart.books) {
if (book.seller.equals(seller)) {
seller_total += book.price;
}
}
const seller_user = await User.findById(seller);
seller_user.wallet_amount += seller_total * 0.97;
seller_user.wallet_amount = Math.round(seller_user.wallet_amount * 100) / 100;

// the 3% profit goes to the admin
// not yet implemented

await seller_user.save({session});
total_price += book.price;
}

// Create a new order
const order = new Order({
user: req.user._id,
bought_books: cart.books,
total_price: total_price,
bought_books: cart.books.map((book) => book._id),
total_price: total_price, // Ensure total_price is defined
order_date: Date.now(),
});

// Clear the user's cart
cart.books = [];
await cart.save({ session });

// Save the order
await order.save({ session });
await order.save();

// Deduct the total price of the order from the user's wallet
user.wallet_amount -= total_price;
await user.save({ session });
// Update book quantities
for (let book of cart.books) {
book.quantity -= 1;
await book.save();
}

// Commit the transaction
await session.commitTransaction();
session.endSession();
// Clear the user's cart
cart.books = [];
await cart.save();

// redirect to 'books' and display success message

res.json({ url: stripe_session.url });
req.flash('success', 'Order placed successfully');
res.redirect('/orders/mybooks');

} catch (err) {
// If an error occurred, abort the transaction
await session.abortTransaction();
session.endSession();

console.log(err);
console.error(err.message);
res.status(500).json(err);
}
};


// Display list of all books bought by the user.
exports.order_mybooks = async (req, res) => {
try {
let books;
if (req.user.type === 'buyer') {
const orders = await Order.find({ user: req.user._id }).populate('bought_books');
books = orders.flatMap(order => order.bought_books);
const orders = await Order.find({ user: req.user._id }).populate(
'bought_books',
);
books = orders.flatMap((order) => order.bought_books);
} else if (req.user.type === 'seller') {
books = await Book.find({ seller: req.user._id });
}

// Loop over each book and populate
books = await Promise.all(books.map(async (book) => {
return await Book.populate(book, [
{path: 'authors'},
{path: 'publisher', select: 'name'},
{path: 'categories', select: 'name'}
]);
}));

res.render('mybooks', {books: books});
}
catch(err) {
books = await Promise.all(
books.map(async (book) => {
return await Book.populate(book, [
{ path: 'authors' },
{ path: 'publisher', select: 'name' },
{ path: 'categories', select: 'name' },
]);
}),
);

res.render('mybooks', { books: books });
} catch (err) {
console.log(err);
res.status(500).json(err);
}
Expand Down
Loading