PayPal Javascript PHP SDK

In this tutorial, we are going to teach you how you can receive payments online via the PayPal payment gateway using Javascript and PHP. This tutorial uses simple Javascript and PHP, so you will be able to apply this tutorial to any framework like React, Vue, Laravel, etc.

It also goes with any backend framework like Laravel, WordPress, or even if your backend is in Node JS or Python, not just PHP.

Video Tutorial: (Client-Side)

Server side:

# Step 1

The first step is to include PayPal Javascript SDK in your website. Paste the following code into your HTML page where you want to receive the payments.

<!-- Load the required checkout.js script -->
<script src="https://www.paypalobjects.com/api/checkout.js" data-version-4></script>

<!-- Load the required Braintree components. -->
<script src="https://js.braintreegateway.com/web/3.39.0/js/client.min.js"></script>
<script src="https://js.braintreegateway.com/web/3.39.0/js/paypal-checkout.min.js"></script>

Refresh the page now and check your browser console, if all goes well, then you are ready to render the payment button.

# Step 2

Then you need to go to this link and create an app on your PayPal dashboard and copy the Client ID of both (Sandbox and Live) accounts.

# Step 3

Finally, you need to render the payment button using the following code:

<!-- paypal button will be rendered here using Javascript -->
<div id="btn-paypal-checkout"></div>

<script>
    window.addEventListener("load", function () {
        var cartItems = [{
            name: "Product 1",
            description: "Description of product 1",
            quantity: 1,
            price: 50,
            sku: "prod1",
            currency: "USD"
        }, {
            name: "Product 2",
            description: "Description of product 2",
            quantity: 3,
            price: 20,
            sku: "prod2",
            currency: "USD"
        }, {
            name: "Product 3",
            description: "Description of product 3",
            quantity: 4,
            price: 10,
            sku: "prod3",
            currency: "USD"
        }];

        var total = 0;
        for (var a = 0; a < cartItems.length; a++) {
            total += (cartItems[a].price * cartItems[a].quantity);
        }

        // Render the PayPal button
        paypal.Button.render({

            // Set your environment
            env: 'sandbox', // sandbox | production

            // Specify the style of the button
            style: {
                label: 'checkout',
                size: 'medium', // small | medium | large | responsive
                shape: 'pill', // pill | rect
                color: 'gold', // gold | blue | silver | black,
                layout: 'vertical'
            },

            // PayPal Client IDs - replace with your own
            // Create a PayPal app: https://developer.paypal.com/developer/applications/create

            client: {
                sandbox: '',
                production: ''
            },

            funding: {
                allowed: [
                    paypal.FUNDING.CARD,
                    paypal.FUNDING.ELV
                ]
            },

            payment: function(data, actions) {
                return actions.payment.create({
                    payment: {
                        transactions: [{
                            amount: {
                                total: total,
                                currency: 'USD'
                            },
                            item_list: {
                                // custom cartItems array created specifically for PayPal
                                items: cartItems
                            }
                        }]
                    }
                });
            },

            onAuthorize: function(data, actions) {
                return actions.payment.execute().then(function() {
                    // you can use all the values received from PayPal as you want
                    console.log({
                        "intent": data.intent,
                        "orderID": data.orderID,
                        "payerID": data.payerID,
                        "paymentID": data.paymentID,
                        "paymentToken": data.paymentToken
                    });

                    // [call AJAX here]
                });
            },
            
            onCancel: function (data, actions) {
                console.log(data);
            }

        }, '#btn-paypal-checkout');
    });
</script>

Refresh the page now and you will a Paypal payment button. On clicking, will open the pop-up from Paypal itself from where your users can make the payment and it will automatically be received in your PayPal business account.

# Step 4

Now we need to validate the payment on the server-side. After payment is made, you might want to activate your user’s account or perform any action.

So you will call an AJAX to the server to perform that action, but the AJAX can be manipulated by the client-side. So the payment must be validated first.

Write the following code in the [call AJAX here] section:

paymentMade(data.orderID, data.payerID, data.paymentID, data.paymentToken);

Then you need to create a Javascript function that will call the AJAX request:

function paymentMade(orderID, payerID, paymentID, paymentToken) {
    var ajax = new XMLHttpRequest();
    ajax.open("POST", "paypal.php", true);

    ajax.onreadystatechange = function () {
        if (this.readyState == 4) {
            if (this.status == 200) {
                var response = JSON.parse(this.responseText);
                console.log(response);
            }

            if (this.status == 500) {
                console.log(this.responseText);
            }
        }
    };

    var formData = new FormData();
    formData.append("orderID", orderID);
    formData.append("payerID", payerID);
    formData.append("paymentID", paymentID);
    formData.append("paymentToken", paymentToken);
    ajax.send(formData);
}

Now we need to create a PHP file named paypal.php that will handle this request. It will have the following code:

<?php

// show all errors
ini_set('display_errors', 1);
ini_set('display_startup_errors', 1);
error_reporting(E_ALL);

// initialize CURL
$ch = curl_init();

// set path to PayPal API to generate token
// remove "sandbox" from URL when in live
curl_setopt($ch, CURLOPT_URL, 'https://api-m.sandbox.paypal.com/v1/oauth2/token');
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_POSTFIELDS, "grant_type=client_credentials");
// write your own client ID and client secret in following format:
// {client_id}:{client_secret}
curl_setopt($ch, CURLOPT_USERPWD, '{client_id}:{client_secret}');

// set headers
$headers = array();
$headers[] = 'Accept: application/json';
$headers[] = 'Accept-Language: en_US';
$headers[] = 'Content-Type: application/x-www-form-urlencoded';
curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);

// call the CURL request
$result = curl_exec($ch);

// check if there is any error in generating token
if (curl_errno($ch))
{
    echo json_encode([
    	"status" => "error",
    	"message" => curl_error($ch)
    ]);
    exit();
}
curl_close($ch);

// the response will be a JSON string, so you need to decode it
$result = json_decode($result);

// get the access token
$access_token = $result->access_token;

// we only need the second part of orderID variable from client side
$payment_token_parts = explode("-", $_POST["orderID"]);
$payment_id = "";

if (count($payment_token_parts) > 1)
{
    $payment_id = $payment_token_parts[1];
}

// initialize another CURL for verifying the order
$curl = curl_init();

// call API and send the payment ID as parameter
curl_setopt($curl, CURLOPT_URL, 'https://api-m.sandbox.paypal.com/v2/checkout/orders/' . $payment_id);
curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($curl, CURLOPT_CUSTOMREQUEST, 'GET');

// set headers for this request, along with access token
$headers = array();
$headers[] = 'Content-Type: application/json';
$headers[] = 'Authorization: Bearer ' . $access_token;
curl_setopt($curl, CURLOPT_HTTPHEADER, $headers);

// executing the request
$result = curl_exec($curl);

// check if there is any error
if (curl_errno($curl))
{
    echo json_encode([
    	"status" => "error",
    	"message" => "Payment not verified. " . curl_error($curl)
    ]);
    exit();
}
curl_close($curl);

// get the response JSON decoded
$result = json_decode($result);

// you can use the following if statement to make sure the payment is verified
// if ($result->status == "COMPLETED")

// send the response back to client
echo json_encode([
	"status" => "success",
	"message" => "Payment verified.",
	"result" => $result
]);
exit();

Comments have been added with each line for an explanation. Now you will be able to accept payments online via PayPal Javascript and PHP SDK.

If you want to accept payments from the Stripe payment gateway too, you can check our tutorial on Stripe as well.

If you have any questions or facing any problems, feel free to contact us in the comments section below.

Note: I will add PayPal payment gateway in your website in just $5.

19 Replies to “PayPal Javascript PHP SDK”

  1. Hello Good day,

    I integrated this API in Odoo XML and python but when verfying the order I’m facing this error. URL “url = ‘https://api-m.sandbox.paypal.com/v2/checkout/orders/:’ + order_id”. I also confirmed the order_id and access_token but still having this issue.

    {“status”: “error”, “message”: “Error verifying payment: b'{\”name\”:\”RESOURCE_NOT_FOUND\”,\”details\”:[{\”issue\”:\”INVALID_RESOURCE_ID\”,\”description\”:\”Specified resource ID does not exist. Please check the resource ID and try again.\”}],\”message\”:\”The specified resource does not exist.\”,\”debug_id\”:\”…..\”,\”links\”:[{\”href\”:\”https://developer.paypal.com/docs/api/orders/v2/#error-INVALID_RESOURCE_ID\”,\”rel\”:\”information_link\”,\”method\”:\”GET\”}]}'”}

  2. HI and good day!
    I used the above PAYPAL JAVASCRIPT PHP SDK, and integrated it into my website and it worked great. (currently it is not totally posted- I am working in local environment only) When checking in my business sandbox account, I could not get a reference to the paymentid that is capturable in the above code. I actually capture it and update that info into a database. My challenge is that I cant find the referece to the paymentid in the paypal sandbox business account. Ideally, I would like to capture the transactionid from the paypal sandbox account and store that value in the database. Can the above code be updated to accomodate for that request? If so, How?
    Thanks

    1. You can get the transaction ID from $result object from “https://api-m.sandbox.paypal.com/v2/checkout/orders/$payment_id” API. You can print_r($result) to see the complete result.

  3. I was wondering if I was on the right track with the following?

    onAuthorize: function(data, actions) {
    return actions.payment.execute().then(function() {
    // you can use all the values received from PayPal as you want
    console.log({
    “intent”: data.intent,
    “orderID”: data.orderID,
    “payerID”: data.payerID,
    “paymentID”: data.paymentID,
    “paymentToken”: data.paymentToken,
    “transaction_id”: data.transaction_id
    });

    // [call AJAX here]
    paymentMade(data.orderID, data.payerID, data.paymentID, data.paymentToken, data.transaction_id);

    function paymentMade(orderID, payerID, paymentID, paymentToken, transaction_id) {
    var ajax = new XMLHttpRequest();
    ajax.open(“POST”, “paypal.php”, true);

    ajax.onreadystatechange = function () {
    if (this.readyState == 4) {
    if (this.status == 200) {
    var response = JSON.parse(this.responseText);
    console.log(response);
    }

    if (this.status == 500) {
    console.log(this.responseText);
    }
    }
    };

    var formData = new FormData();
    formData.append(“orderID”, orderID);
    formData.append(“payerID”, payerID);
    formData.append(“paymentID”, paymentID);
    formData.append(“paymentToken”, paymentToken);
    formData.append(“transaction_id”, transaction_id);
    ajax.send(formData);

    Thanks

      1. Hi
        Hope all is well.

        Yeah, I get the following on the console:

        intent: “sale”
        orderID: “EC-4C927447S9823280H”
        payerID: “ZNGLVEZJ5TYJJ”
        paymentID: “PAYID-MRXCCBI4Y783867C9155891D”
        paymentToken: “EC-4C927447S9823280H”
        transaction_id: undefined

        Thanks

        1. Hi

          Hope all is well.

          I am not sure about it being from the AJAX’s response (I don’t know how to identify it as an AJAX response), but the transaction was complete. There were no errors except for the statement from the console:

          transaction_id: undefined

          The process of updateing a database and sending an email notification were not interrupted and are only executed when the transaction is successful.

          I did not modify the contents of the file

          ‘paypal.php’

          Should it be modified as well?

          Thanks
          Frank

  4. Hi
    Hope all is well.

    I was wondering if the transaction id would be part of the profile as in

    $result = json_decode($result);

    Would I be able to parse the value from the $result variable?

    Thanks
    Frank

      1. Hi
        Hope all is well.

        I ended up using:

        // extract the PayPal transaction ID
        $transactionId = “”;
        if (isset($result->purchase_units[0]->payments->captures[0]->id)) {
        $transactionId = $result->purchase_units[0]->payments->captures[0]->id;
        $_SESSION[‘transactionId’] = $transactionId;
        }

        I set the id to a global variable and it worked like a charm.

        Thanks very much!!
        Frank

  5. Hi
    Hope all is well.

    Since I am on a roll, I tried adding information which I would like to include with the paypal transaction (email and userID). I modified the code of the payment function as follows, but now the paypal rendering refuses to open. Am I on the right track?

    Thanks

    Frank

    var total = curval;
    var emailAddress = “”;
    var userId2 = “”;

    payment: function(data, actions) {
    return actions.payment.create({
    payment: {
    transactions: [{
    amount: {
    total: total,
    currency: ‘USD’
    },
    item_list: {
    shipping_address: {
    recipient_name: emailAddress
    },
    items: [{
    description: ‘User ID: ‘ + userId2
    }]
    }
    }]
    }
    });
    },

  6. Hi
    Hope all is well.
    I thank you again. The console had errors but I ended up using two unused fields to satisfy my requirements:

    transactions: [{
    amount: {
    total: total,
    currency: ‘USD’
    },
    custom: emailAddress,
    invoice_number: userId2
    }]

    Works great. ’til next time.

    Thanks
    Frank

Comments are closed.