Skip to content

Commit

Permalink
Merge pull request #107 from fdhhhdjd/developer
Browse files Browse the repository at this point in the history
#106 backend
  • Loading branch information
fdhhhdjd committed Nov 4, 2022
2 parents 7a0f2a7 + a205997 commit be85898
Show file tree
Hide file tree
Showing 5 changed files with 288 additions and 30 deletions.
65 changes: 65 additions & 0 deletions backend/src/v1/user_api/controllers/payment.controllers.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,9 @@ const {
handlePaymentTotal,
handleCheckInStock,
handlePaymentPaypal,
handlePaymentStripe,
handlePaymentStripeSuccess,
handlePaymentStripeCancel
} = require("../services/payment.service/payment.service");
const paymentCtrl = {
totalPayment: async (req, res) => {
Expand Down Expand Up @@ -68,5 +71,67 @@ const paymentCtrl = {
});
}
},
paymentStripe: async (req, res) => {
try {
let user_id = req.user.id || req.user.user_id;
const { status, success, element } = await handlePaymentStripe({
user_id,
req
});
return res.status(status).json({
status,
success,
msg: returnReasons(status.toString()),
element,
});
} catch (error) {
return res.status(503).json({
status: 503,
success: false,
element: returnReasons("503"),
});
}
},
paymentStripeSuccess: async (req, res) => {
try {
let payment_id = req.params.id;
let user_id = req.params.user_id;

const { status, success, element } = await handlePaymentStripeSuccess({
payment_id,
user_id
});
return res.status(status).json({
status,
success,
msg: returnReasons(status.toString()),
element,
});
} catch (error) {
return res.status(503).json({
status: 503,
success: false,
element: returnReasons("503"),
});
}
},
paymentStripeCancel: async (req, res) => {
try {

const { status, success, element } = await handlePaymentStripeCancel();
return res.status(status).json({
status,
success,
msg: returnReasons(status.toString()),
element,
});
} catch (error) {
return res.status(503).json({
status: 503,
success: false,
element: returnReasons("503"),
});
}
},
};
module.exports = paymentCtrl;
12 changes: 12 additions & 0 deletions backend/src/v1/user_api/routes/payment.routes.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,4 +9,16 @@ router.get("/payment/check/stock", VerifyAcceptToken, paymentCtrl.countInStock);

//* payment paypal
router.post("/payment/paypal", VerifyAcceptToken, paymentCtrl.paymentPaypal);

//* payment stripe
router.post("/payment/stripe", VerifyAcceptToken, paymentCtrl.paymentStripe);

//* Payment Success
router.get("/payment/stripe/success/:id/:user_id", paymentCtrl.paymentStripeSuccess);

//* Payment Cancel
router.get("/payment/cancel", paymentCtrl.paymentStripeCancel);



module.exports = router;
Original file line number Diff line number Diff line change
@@ -1,6 +1,13 @@
const mongoose = require("mongoose");
const Payments = require("../../../models/PaymentModel");
const Users = require("../../../models/userModel");
const Products = require("../../../models/ProductModel");
const STORAGE = require("../../../utils/storage");
const REDIS = require("../../../db/redis_db")
const {
get,
hgetall
} = require("../../../utils/limited_redis");
const createPayment = async ({
user_id,
cart,
Expand Down Expand Up @@ -52,7 +59,40 @@ const getUserId = async (user_id) => {
"name email total_cart discount voucher"
);
};
const handlePayment = async ({ user_id }) => {
const data = await hgetall(user_id);
var cart = [];
for (var key in data) {
cart.push({
cart: await Products.find({ _id: key }),
quantity: data[key],
});
}
let total = 0;
let total_apply_voucher = 0;
const voucher = await get(`voucher_userId:${user_id}`);
for (let i = 0; i < cart.length; i++) {
total += cart[i].cart[0].price * cart[i].quantity;
}
total_apply_voucher = (total * JSON.parse(voucher)) / 100;

return { cart, total, total_apply_voucher, voucher: JSON.parse(voucher) };
}
const handlePaymentSuccess = async ({ cart, user_id }) => {
for (let i = 0; i < cart.length; i++) {
STORAGE.sold(cart[i].cart[0]._id, cart[i].quantity, cart[i].cart[0].sold);
STORAGE.stock(
cart[i].cart[0]._id,
cart[i].quantity,
cart[i].cart[0].countInStock
);
}
let redis_multi = REDIS.pipeline().del(`cartUserId:${user_id}`).del("product_user").del(`voucher_userId:${user_id}`)
redis_multi.exec()
}
module.exports = {
createPayment,
getUserId,
handlePayment,
handlePaymentSuccess
};
201 changes: 171 additions & 30 deletions backend/src/v1/user_api/services/payment.service/payment.service.js
Original file line number Diff line number Diff line change
@@ -1,14 +1,14 @@
const Stripe = require("stripe");
const {
hgetall,
sumQuantity,
get,
del,
RedisPub,
} = require("../../../utils/limited_redis");
const { createPayment } = require("./curd_payment.service");
const { createPayment, handlePayment, handlePaymentSuccess } = require("./curd_payment.service");
const Products = require("../../../models/ProductModel");
const STORAGE = require("../../../utils/storage");
const REDIS = require("../../../db/redis_db")
const CONFIGS = require("../../../configs/config")
const stripe = new Stripe(CONFIGS.STRIPE_KEY);
module.exports = {
handlePaymentTotal: async ({ user_id }) => {
try {
Expand Down Expand Up @@ -98,29 +98,16 @@ module.exports = {
},
handlePaymentPaypal: async ({ user_id, paymentID, address }) => {
try {
const data = await hgetall(user_id);
var cart = [];
for (var key in data) {
cart.push({
cart: await Products.find({ _id: key }),
quantity: data[key],
});
}
let total = 0;
let total_apply_voucher = 0;
const voucher = await get(`voucher_userId:${user_id}`);
for (let i = 0; i < cart.length; i++) {
total += cart[i].cart[0].price * cart[i].quantity;
}
total_apply_voucher = (total * JSON.parse(voucher)) / 100;
let { cart, total, total_apply_voucher, voucher } = await handlePayment({ user_id });

const { success, element } = await createPayment({
user_id,
cart,
paymentID,
address,
total,
total_apply_voucher,
voucher: JSON.parse(voucher),
voucher: voucher,
});
if (!success) {
return {
Expand All @@ -138,16 +125,7 @@ module.exports = {
name: element?.name,
})
);
for (let i = 0; i < cart.length; i++) {
STORAGE.sold(cart[i].cart[0]._id, cart[i].quantity, cart[i].cart[0].sold);
STORAGE.stock(
cart[i].cart[0]._id,
cart[i].quantity,
cart[i].cart[0].countInStock
);
}
let redis_multi = REDIS.pipeline().del(`cartUserId:${user_id}`).del("product_user").del(`voucher_userId:${user_id}`)
redis_multi.exec()
handlePaymentSuccess({ cart, user_id })
return {
status: 200,
success: true,
Expand All @@ -165,4 +143,167 @@ module.exports = {
};
}
},
handlePaymentStripe: async ({ user_id, req }) => {
let UserId = await get(`userId:${user_id}`)
let data = await hgetall(user_id);
UserId = JSON.parse(UserId)
var cart = [];
for (var key in data) {
cart.push({
cart: await Products.find({ _id: key }),
quantity: data[key],
});
}
const params = {
submit_type: "pay",
mode: "payment",
payment_method_types: ["card"],
billing_address_collection: "auto",
shipping_address_collection: {
allowed_countries: ["US", "CA", "KE"],
},
shipping_options: [
{
shipping_rate_data: {
type: "fixed_amount",
fixed_amount: {
amount: 0,
currency: "usd",
},
display_name: "Free shipping",
// Delivers between 5-7 business days
delivery_estimate: {
minimum: {
unit: "business_day",
value: 5,
},
maximum: {
unit: "business_day",
value: 7,
},
},
},
},
{
shipping_rate_data: {
type: "fixed_amount",
fixed_amount: {
amount: 1500,
currency: "usd",
},
display_name: "Next day air",
// Delivers in exactly 1 business day
delivery_estimate: {
minimum: {
unit: "business_day",
value: 1,
},
maximum: {
unit: "business_day",
value: 1,
},
},
},
},
],
phone_number_collection: {
enabled: true,
},
customer_email: UserId.email,
line_items: cart.map((item) => {
return {
price_data: {
currency: "usd",
product_data: {
name: item.cart[0].name,
images: [item.cart[0].image.url],
description: item.cart[0].description,
},
unit_amount: item.cart[0].price * 100,
},
adjustable_quantity: {
enabled: true,
minimum: 1,
},
quantity: item.quantity,
};
}),

success_url: `${req.protocol}://${req.get("host")}/api/payment/stripe/success/{CHECKOUT_SESSION_ID}/${UserId._id}`,
cancel_url: `${req.protocol}://${req.get("host")}/api/payment/cancel`,
// success_url: `http:localhost:3000/api/payment/stripe/success/{CHECKOUT_SESSION_ID}/${UserId._id}`,
// cancel_url: `http:localhost:3000/api/payment/cancel`,
};
// Create Checkout Sessions from body params.
const session = await stripe.checkout.sessions.create(params);

return {
status: 200,
success: true,
element: {
payment_url: session.url,
msg: "Url Payment Stripe !!",
},
};
},
handlePaymentStripeSuccess: async ({ payment_id, user_id }) => {
try {
//data Stripe
const session = await stripe.checkout.sessions.retrieve(payment_id);
const customer = await stripe.customers.retrieve(session.customer);

//Save Db
let { cart, total, total_apply_voucher, voucher } = await handlePayment({ user_id });
const { success, element } = await createPayment({
user_id,
cart,
paymentID: customer.id,
address: customer.shipping.address,
total,
total_apply_voucher,
voucher: voucher,
});
if (!success) {
return {
status: 400,
success: false,
element: {
msg: "Payment Paypal Fail !!!",
},
};
}
RedisPub(
"user_payment_success",
JSON.stringify({
email: element?.email,
name: element?.name,
})
);
handlePaymentSuccess({ cart, user_id })
return {
status: 200,
success: true,
element: {
msg: "Payment Stripe Success !!",
},
};
} catch (error) {
return {
status: 503,
success: false,
element: {
msg: "Server busy !!",
},
};
}
},
handlePaymentStripeCancel: async () => {
return {
status: 200,
success: true,
element: {
msg: "Payment Paypal Cancel !!",
},
};
}
};
Binary file modified dump.rdb
Binary file not shown.

2 comments on commit be85898

@vercel
Copy link

@vercel vercel bot commented on be85898 Nov 4, 2022

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@vercel
Copy link

@vercel vercel bot commented on be85898 Nov 4, 2022

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Successfully deployed to the following URLs:

serversendemailshopshoes – ./server_send_email

serversendemailshopshoes-fdhhhdjd.vercel.app
full-stack-shop-shoes-bootstrap.vercel.app
serversendemailshopshoes-git-main-fdhhhdjd.vercel.app

Please sign in to comment.