Skip to content

Commit

Permalink
Merge branch 'demo-bn-19-07' into ft-seller-dashboard
Browse files Browse the repository at this point in the history
  • Loading branch information
sevelinCa authored Jul 20, 2024
2 parents b53cc86 + 0cff03d commit 4402995
Show file tree
Hide file tree
Showing 16 changed files with 223 additions and 26 deletions.
29 changes: 23 additions & 6 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,7 @@
"sequelize-typescript": "^2.1.6",
"sinon": "^18.0.0",
"socket.io": "^4.7.5",
"stripe": "^16.2.0",
"supertest": "^7.0.0",
"swagger-jsdoc": "^6.2.8",
"swagger-ui-express": "^5.0.0",
Expand Down
99 changes: 99 additions & 0 deletions src/controllers/Payment.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,99 @@
import express, { Request, Response } from "express";
import Stripe from "stripe";
import dotenv from "dotenv";
import { findOrderById, findProductById } from "../services/paymentService";

dotenv.config();

const stripe = new Stripe(`${process.env.STRIPE_SECRET_KEY}`);
export const checkout = async (req: Request, res: Response) => {
try {
const orderId = req.params.id;
const order = await findOrderById(orderId);
if (!order) {
return res.status(404).json({ message: "Order not found" });
}
const line_items: any[] = await Promise.all(
order.products.map(async (item: any) => {
const productDetails:any = await findProductById(item.productId);
const unit_amount = Math.round(productDetails!.price * 100);
return {
price_data: {
currency: "usd",
product_data: {
name: productDetails?.name,
images: [productDetails?.image[0]],
},
unit_amount: unit_amount,
},
quantity: item.quantity,
};
})
);
console.log(line_items)


const session = await stripe.checkout.sessions.create({
line_items,
mode: "payment",
success_url: process.env.SUCCESS_PAYMENT_URL,
cancel_url: process.env.CANCEL_PAYMENT_URL,
metadata: {
orderId: orderId,
},
});


res.status(200).json({ url: session.url });
} catch (error: any) {
res.status(500).json({ message: error.message });
}
};

export const webhook = async (req: Request, res: Response) => {
const sig: any = req.headers["stripe-signature"];
const webhookSecret: any = process.env.WEBHOOK_SECRET_KEY;
let event: any;
try {
event = stripe.webhooks.constructEvent(req.body, sig, webhookSecret);
} catch (err: any) {
console.log(`⚠️ Webhook signature verification failed.`, err.message);
return res.status(400).send(`Webhook Error: ${err.message}`);
}

switch (event.type) {
case "checkout.session.completed":
const session = event.data.object;

try {
const lineItems = await stripe.checkout.sessions.listLineItems(
session.id
);

const orderId = session.metadata.orderId;
const order = await findOrderById(orderId);
if (order) {
order.status = "paid";
await order.save();
} else {
console.error("Order not found:", orderId);
}
} catch (err) {
console.error("Error processing session completed event:", err);
}
break;

case "payment_intent.succeeded":
const paymentIntent = event.data.object;
console.log("Payment Intent succeeded: ", paymentIntent);
break;
case "payment_method.attached":
const paymentMethod = event.data.object;
console.log("Payment Method attached: ", paymentMethod);
break;

default:
console.log(`Unhandled event type ${event.type}`);
}
res.json({ received: true });
};
6 changes: 5 additions & 1 deletion src/controllers/cart.controller.ts
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,11 @@ export const getCart = async (req: Request, res: Response) => {
if (!cart) {
return res.status(404).json({ message: "Cart not found" });
}
const cartitem = await CartItem.findAll({ where: { cartId: cart.cartId }, include: {model: Product,as:"Product"}},);
const cartitem = await CartItem.findAll({ where: { cartId: cart.cartId }, include: {
model: Product,
as: "Product"
} });


return res.status(200).json({ cartitem });
} catch (error: any) {
Expand Down
1 change: 0 additions & 1 deletion src/controllers/checkout.controller.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,6 @@ import { v4 as uuidv4 } from 'uuid';

export const createOrder = async (req: Request, res: Response) => {
const { userId, deliveryAddress, paymentMethod,client } = req.body;

if(!userId || !deliveryAddress || !paymentMethod) {
return res.status(400).json({ message: 'All fields are required' })
}
Expand Down
37 changes: 32 additions & 5 deletions src/controllers/orderController.ts
Original file line number Diff line number Diff line change
Expand Up @@ -69,15 +69,34 @@ export const modifyOrderStatus = async (req: Request, res: Response) => {
export const getAllOrders = async (req: Request, res: Response) => {
try {
const userId = (req as any).token.id;
const vendor = await findVendorByUserId(userId);
const vendorId = req.params.vendorId;

let orders: any;

if(vendorId){
const allOrders: any = await Order.findAll({
include: [{ model: Product, as: 'products' }]
});

let orders;
if(allOrders.length === 0){
return res.status(404).json({ message: "No orders found" });
}

orders = await Order.findAll({ where: { userId }})
orders = allOrders.filter(order =>
order.products.some(product => product.vendorId === vendorId)
)


} else {
orders = await Order.findAll({ where: { userId }})

}


return res.status(200).json(orders);
} catch (error: any) {
return res.status(500).json({ error: error.message });
} catch(error: any){
console.error(error);
return res.status(500).json({ error: error.message})
}
};

Expand Down Expand Up @@ -105,6 +124,14 @@ export const getOrder = async (req: Request, res: Response) => {
}
};

export const getSellerOrder = async (req: Request, res: Response) => {
try {
const vendorId = req.params.vendorId;
const orders: any = await Order.findAll();
if (!orders) {
return res.status(404).json({ message: "No order found" });
}

export const getSellerOrder = async (req: Request, res: Response) => {
try {
const vendorId = req.params.vendorId;
Expand Down
1 change: 0 additions & 1 deletion src/database/config/config.js
Original file line number Diff line number Diff line change
Expand Up @@ -29,4 +29,3 @@ const config = {
};

module.exports = config;

2 changes: 1 addition & 1 deletion src/database/models/cartitem.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ class CartItem extends Model {
});
CartItem.belongsTo(models.Product,{
foreignKey: "productId",
as:"Product"
as: "Product"
})
}
static initModel(sequelize: Sequelize) {
Expand Down
1 change: 1 addition & 0 deletions src/database/models/order.ts
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ class Order extends Model {
client: { type: DataTypes.STRING, allowNull: false },
paymentMethod: { type: DataTypes.INTEGER, allowNull: false },
status: { type: DataTypes.STRING, allowNull: false },
client: { type: DataTypes.STRING, allowNull: false },
products: { type: DataTypes.JSONB, allowNull: false },
totalAmount: { type: DataTypes.INTEGER, allowNull: false },
expectedDeliveryDate: { type: DataTypes.DATE, allowNull: true },
Expand Down
1 change: 1 addition & 0 deletions src/database/seeders/20240522075149-seed-orders.js
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ module.exports = {

const [products] = await queryInterface.sequelize.query(`
SELECT "productId","name","image","price" FROM "Products"
LIMIT 3;
`);

Expand Down
26 changes: 22 additions & 4 deletions src/helpers/generateToken.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@

import jwt from "jsonwebtoken";
import User from "../database/models/user";
import dotenv from "dotenv";
Expand All @@ -7,10 +8,27 @@ import { where } from "sequelize";
dotenv.config();

const generateToken = async (userData: User) => {
const vendor = await Vendor.findOne({
where: { userId: userData?.userId },
});
const vendorId = vendor ? vendor.vendorId : null;
const vendor = await Vendor.findOne({
where: { userId: userData?.userId },
});
const vendorId = vendor ? vendor.vendorId : null;

return jwt.sign(
{
role: userData.role,
email: userData.email,
id: userData.userId,
vendor: vendorId,
password: userData.password,
},
"crafters1234",
{
expiresIn: "1d",
}
);
};

export { generateToken };

return jwt.sign(
{
Expand Down
7 changes: 7 additions & 0 deletions src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,13 @@ app.use(
);

app.use(cookieParser());
app.use((req, res, next) => {
if (req.originalUrl === '/webhook') {
next();
} else {
express.json()(req, res, next);
}
});
app.use(express.urlencoded({ extended: true }));
app.use(
session({
Expand Down
15 changes: 14 additions & 1 deletion src/routes/checkout.router.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,20 @@
import express from 'express'
import express, { Request, Response } from 'express'
import { createOrder } from '../controllers/checkout.controller'
import { checkout, webhook } from '../controllers/Payment';
import { VerifyAccessToken } from '../middleware/verfiyToken';
const router = express.Router()

router.post('/checkout', createOrder)

router.post("/payment/:id", VerifyAccessToken, checkout);

router.post('/webhook', express.raw({ type: 'application/json' }), webhook);

router.get("/success", async(req:Request,res:Response)=>{
res.send("Succesfully")
});
router.get("/cancel", async(req:Request,res:Response)=>{
res.send("Cancel")
});

export default router
Loading

0 comments on commit 4402995

Please sign in to comment.