javascriptsecuritypaypalpaymentexpress-checkout

Paypal express checkout. Is it secure to store data in DB in the onAuthorize function?


I have a BIG problem of security in the flow of a payment in a website.

I have a nodejs server and a standard html page with a .js which uses Paypal Express checkout.

My server has to save the data of the payment due given the nature of my webapp. The point is that even using a Client-Server architecture to pay, the flow of data is going through the client browser.

The problem is that Paypal Express checkout uses a new window to execute payment, so the data MUST pass through client! (Or maybe not, just wait the end of the post)

This is my client side code:

paypal.Button.render({

        env : 'sandbox',
        commit: true, 
        style: {
            size: 'medium',
            color: 'gold',
            shape: 'pill',
            label: 'checkout'
        },
        locale: 'en_US',
        payment: function() {
            nickname = $("#nickname").val();
            amount = $("#amount").val();
            description = $("#description").val();
            data = {
                "nickname" : nickname,
                "amount" : amount,
                "description" : description
            };
            return new paypal.Promise(function(resolve, reject) {
                jQuery.post("/newPayment", data).done(function(data){
                    console.log("HEI I GOT THE PAYMENT JSON = " + data);
                    parsed_data = JSON.parse(data);
                    resolve(parsed_data['id']);
                });
            });
        },

        onAuthorize: function(data, actions) {
            // HERE IS WHERE I SHOULD CALL MY SERVER TO INSERT DATA INTO DB
            console.log("PAYMENT SUCCESSFUL");
            return actions.payment.execute();
        },
        onError: function(data, actions){
            console.log("ERRORRRRRR");
            $("#warning").show();
        }

    }, '#paypal-button');

If you look at my commented line there is a BIIIG problem. Whoever is a little bit skilled can copy-paste this .js and confirm a false payment to my server which will insert false data into DB.

The only way I thought to resolve this problem is to first (when the user clicks the "payment" button) create a "pending" payment into DB, then when authorized call my server with the data and check if the 2 payment are the same.

But this solution has another problem, nothing ensures my server that the Payment is actually executed, an attacker could perform the first POST to my server to create the payment, and then (even in the same function recovering the "ID" in parsed_data['id']) execute the second POST with the correct ID; he could do all this without actually go through paypal window.

My question is: Is there a way to recover payments related to my Paypal account from my server?

Or, am I missing something in PaypalSDK? Is there a way to let PAYPAL call my server when a payment is executed?


Solution

  • You are correct, nothing on the client side is ever secure. You should have your server verify that the payment was successful (and for the correct amount, etc.) PayPal has both REST APIs for the server and SDKs for specific languages.