Search code examples
node.jsexpresspaypalpaypal-rest-sdk

How to pass user details to paypal sdk from node js application?


I'm using JWT in my node.js application, and I'm receiving payment requests from the authorized (logged in) users. I have added Paypal REST SDK to my application and I'm successfully redirecting to the success route after the payment succeed, but how can I determine which user made the payment? I know I can use some values in the response about the payment, payer ID, and email. But I'm trying to figure out a better way to handle the situation where a user might pay from a different Paypal email.

Is there a way to pass maybe the user ID and receive it back in the success route? Do I miss something in this flow?

POST request coming from VUE JS:

app.post('/pay', (req, res) => {
   var userId = req.userId; // from the authorization header of the requset 

  const create_payment_json = {
    "intent": "sale",
    "payer": {
        "payment_method": "paypal"
    },
    "redirect_urls": {
        "return_url": "http://localhost:3000/success",
        "cancel_url": "http://localhost:3000/cancel"
    },
    "transactions": [{
        "item_list": {
            "items": [{
                "name": "Red Sox Hat",
                "sku": "001",
                "price": "25.00",
                "currency": "USD",
                "quantity": 1
            }]
        },
        "amount": {
            "currency": "USD",
            "total": "25.00"
        },
        "description": "Hat for the best team ever"
    }]
};

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);
        }
      }
  }
});

});

Success route, where I want to access userId and store some information about the user and the payment in my database:

app.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": "25.00"
        }
    }]
  };

  paypal.payment.execute(paymentId, execute_payment_json, function (error, payment) {
    if (error) {
        console.log(error.response);
        throw error;
    } else {
        console.log(JSON.stringify(payment));
        res.send('Success');
    }
});
});

Solution

    1. You are using a deprecated v1/payments SDK for which there is no support. Use the Checkout-NodeJS-SDK for v2/checkout/orders instead. See the documentation for 'Create Order' and 'Capture Order' here: https://developer.paypal.com/docs/business/checkout/server-side-api-calls/#server-side-api-calls , these are the two routes you will need

    2. To send data from the client to your server, add and include it as JSON-formatted POST data in the fetch/XHR call to your server from the client-side createOrder and captureOrder functions in this approval flow: https://developer.paypal.com/demo/checkout/#/pattern/server . The data you add will then be parsable and available on your server handling that route, in req.

    3. Since you are using VUE, you may find this driver useful: https://developer.paypal.com/docs/business/checkout/configure-payments/single-page-app/#vue , but note that the samples there are for a client-side create and capture. You should continue using routes on your server for these actions.