aboutsummaryrefslogblamecommitdiff
path: root/server/controllers/transaction.js
blob: 5143c2da2d96ae0edf5ad7403a5ebc11e98dedb7 (plain) (tree)
1
2
3
4
5
6
7
8
9

                                                      
                                           
                                             
                                         



                         




                          
                                
                        


                                


                               
                      


                                   

                         

           
                 

        
 















                                                                    
                                                                                          













                                                                                       


                              
                        

                              



                                                                                          

                                                            
                                              







                                                  
 








                                                                               


                           









                                                                                         


                                                                             
                
         
                                                    



                                 
 








                                                                            














                                                      


   
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,
      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!"});

    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'});
    let formattedResponse = [];

    orders.forEach(order => {
      formattedResponse.push({
        shipping: order.shipping,
        items: order.items,
        updatedAt: order.updatedAt
      });
    });

    res.json(formattedResponse);
  }

};