const paypal = require('@paypal/checkout-server-sdk');
const paypalClient = require('../config/paypal');
const {siteUrl} = require('../config/env');
const Product = require('../models/Product');
const Order = require('../models/Order');
module.exports = {
async setup(req, res) {
let newOrderObj = {
status: 'ordered',
paypalOrderId: null,
userId: req.user._id,
items: []
};
let transactionSetupData = {
intent: 'CAPTURE',
application_context: {
brand_name: "MEVN Store"
},
purchase_units: [{
amount: {
currency_code: 'USD',
value: null,
breakdown: {
item_total: {
currency_code: "USD",
value: null
}
}
},
items: []
}]
};
if (!req.body.items)
return res.status(400).json({status: "No items given."});
let totalToPay = 0;
for (let i = 0; i < req.body.items.length; i++) {
const itemId = req.body.items[i].id;
const itemQuantity = req.body.items[i].quantity;
if (!itemQuantity)
return res.status(400).json({status: "No quantity given."});
let item;
try {
item = await Product.findOne({_id: itemId});
}
catch {
return res.status(400).json({status: "Couldn't find one of the given items. CB"});
}
if (!item)
return res.status(400).json({status: "Couldn't find one of the given items."});
transactionSetupData.purchase_units[0].items.push({
name: item.name,
unit_amount: {
currency_code: "USD",
value: item.price
},
quantity: itemQuantity
});
totalToPay += item.price * itemQuantity;
newOrderObj.items.push({
productId: itemId,
name: item.name,
quantity: itemQuantity
});
}
transactionSetupData.purchase_units[0].amount.value = totalToPay;
transactionSetupData.purchase_units[0].amount.breakdown.item_total.value = totalToPay;
const request = new paypal.orders.OrdersCreateRequest();
request.prefer("return=representation");
request.requestBody(transactionSetupData);
let order;
try {
order = await paypalClient.execute(request);
} catch (err) {
console.error(err);
return res.sendStatus(500);
}
newOrderObj.paypalOrderId = order.result.id;
const dbOrder = new Order(newOrderObj);
dbOrder.save()
.then(() => res.status(200).json({orderId: order.result.id}))
.catch(err => {
res.status(500).json({status: "Couldn't save new order to database!"});
console.error(err);
});
},
async capture(req, res) {
let dbOrder;
try {
dbOrder = await Order.findOne({paypalOrderId: req.body.orderId});
}
catch {
return res.status(400).json({status: "Couldn't find given order in database! CB"});
}
if (!dbOrder)
return res.status(400).json({status: "Couldn't find given order in database!"});
if (!dbOrder.userId.equals(req.user._id))
return res.sendStatus(403);
const request = new paypal.orders.OrdersCaptureRequest(req.body.orderId);
request.requestBody({});
let capture;
try {
capture = await paypalClient.execute(request);
} catch (err) {
console.error(err);
return res.sendStatus(500);
}
dbOrder.status = 'paid';
dbOrder.shipping = capture.result.purchase_units[0].shipping;
dbOrder.save()
.then(() => res.sendStatus(200))
.catch(err => {
res.status(500).json({status: "Couldn't update order in database!"})
console.error(err);
});
},
async showPaid(req, res) {
const orders = await Order.find({status: 'paid'});
res.json(orders);
},
async showPaidByUser(req, res) {
const orders = await Order.find({status: 'paid', userId: req.user._id});
res.json(orders);
}
};