Stack Exchange
Getting error while using paypal-rest-sdk.Please help me
when I have used payable amount is $1 in below code then it is working fine.
working code)
const express = require("express");
const router = express.Router();
const paypal = require("paypal-rest-sdk");
paypal.configure({
  mode: "sandbox", //sandbox or live
  client_id: process.env.ID,
  client_secret: process.env.SECRET,
});

router.get("/success", (req, res) => {
 
  const payerId = req.query.PayerID;
  const paymentId = req.query.paymentId;
  const execute_payment_json = {
    payer_id: payerId,
    transactions: [
      {
        amount: {
          currency: "USD",
          total: "1.00",
        },
      },
    ],
  };

  paypal.payment.execute(
    paymentId,
    execute_payment_json,
    async (error, payment) => {
      if (error) {
        console.log(error.response);
        throw error;
      } else {
        // await Cart.deleteMany({});
        // req.flash("success", " order placed ");
        res.send("success")
      }
    }
  );
});

router.post("/pay", (req, res) => {
  console.log("hii balajee.....")
  const create_payment_json = {
    intent: "sale",
    payer: {
      payment_method: "paypal",
    },
    redirect_urls: {
      return_url:
        process.env.RETURN_URL || "http://localhost:3000/success",
      cancel_url:
        process.env.CANCEL_URL || "http://localhost:3000/cancel",
    },
    transactions: [
      {
        item_list: {
          items: [
            {
              name: "Red Sox Hat",
              sku: "001",
              price: "1.00",
              currency: "USD",
              quantity: 1,
            },
          ],
        },
        amount: {
          currency: "USD",
          total: "1.00",
        },
        description: "This is the payment description.",
      },
    ],
  };

  paypal.payment.create(create_payment_json, function (error, payment) {
    if (error) {
      throw error;
    } else {
      for (let i = 0; i < payment.links.length; i++) {
        if (payment.links[i].rel === "approval_url") {
          res.redirect(payment.links[i].href);
        }
      }
    }
  });
});

router.get("/cancel", (req, res) => {
//   req.flash("error", "payment cancelled try again");
//   res.redirect("/");
    res.send("done");
});
module.exports = router;

But when payable amount is not hard-coded. I mean payable payment is coming from client side then I am getting error):
{
  name: 'VALIDATION_ERROR',
  details: [
    {
      field: 'purchase_units[0]',
      issue: 'Item amount must add up to specified amount subtotal (or total if amount details not specified)'
    }
  ],
  message: 'Invalid request - see details',
  information_link: 'https://developer.paypal.com/docs/api/payments/#errors',
  debug_id: 'c683329377177',
  httpStatusCode: 400
}
(node:17812) UnhandledPromiseRejectionWarning: Error: Response Status : 400

when data is coming from client side I am using below code.Just some modification of above code):
const express = require("express");
const router = express.Router();
const paypal = require("paypal-rest-sdk");
var fees=0;
paypal.configure({
  mode: "sandbox", //sandbox or live
  client_id: process.env.ID,
  client_secret: process.env.SECRET,
});

router.get("/success", (req, res) => {
 
  const payerId = req.query.PayerID;
  const paymentId = req.query.paymentId;
  const execute_payment_json = {
    payer_id: payerId,
    transactions: [
      {
        amount: {
          currency: "USD",
          total: fees,
        },
      },
    ],
  };

  paypal.payment.execute(
    paymentId,
    execute_payment_json,
    async (error, payment) => {
      if (error) {
        console.log(error.response);
        throw error;
      } else {
        // await Cart.deleteMany({});
        // req.flash("success", " order placed ");
        res.send("success")
      }
    }
  );
});

router.post("/pay", (req, res) => {

  fees= parseInt(req.body.paided);
  console.log(fees);
  const create_payment_json = {
    intent: "sale",
    payer: {
      payment_method: "paypal",
    },
    redirect_urls: {
      return_url:
        process.env.RETURN_URL || "http://localhost:3000/success",
      cancel_url:
        process.env.CANCEL_URL || "http://localhost:3000/cancel",
    },
    transactions: [
      {
        item_list: {
          items: [
            {
              name: "Red Sox Hat",
              sku: "001",
              price: parseInt(req.body.paided),
              currency: "USD",
              quantity: 1,
            },
          ],
        },
        amount: {
          currency: "USD",
          total: parseInt(req.body.paided),
        },
        description: "This is the payment description.",
      },
    ],
  };

  paypal.payment.create(create_payment_json, function (error, payment) {
    if (error) {
      throw error;
    } else {
      for (let i = 0; i < payment.links.length; i++) {
        if (payment.links[i].rel === "approval_url") {
          res.redirect(payment.links[i].href);
        }
      }
    }
  });
});

router.get("/cancel", (req, res) => {
//   req.flash("error", "payment cancelled try again");
//   res.redirect("/");
    res.send("done");
});
module.exports = router;

I don't know what is going wrong here.I am totally lost.I have tried much but couldn't resolved this error.Please help me.
Thank you.

You are using a deprecated SDK, for a deprecated v1/payments REST API.
Use the v2/checkout/orders API instead. There is a Checkout-NodeJS-SDK available.
Follow the Set up standard payments guide and make 2 routes on your server, one for 'Create Order' and one for 'Capture Order', documented here. Both routes should return only JSON data (no HTML or text). Inside the 2nd route, when the capture API is successful you should store its resulting payment details in your database (particularly purchase_units[0].payments.captures[0].id, which is the PayPal transaction ID) and perform any necessary business logic (such as sending confirmation emails or reserving product) immediately before forwarding your return JSON to the frontend caller.
Pair those 2 routes with the frontend approval flow: https://developer.paypal.com/demo/checkout/#/pattern/server
This solution does not use any redirects. There should be no redirecting away from your site to an approval URL.
