PayPal Express Checkout with PHP and MySQL
Wall Script
MailxEngine
Follow Me:
Monday, September 25, 2017

PayPal Express Checkout with PHP and MySQL

Most of the people prefer to shop online which made eCommerce to grow rapidly. But, what makes an excellent eCommerce site for the customers? The answer is - an excellent checkout process. There are several different payment options available in the market today. Out of all, Paypal is the most popular and convenient way to get paid. Making it as easy as possible for your customers to pay is essential for increasing conversions and sales. This is why your checkout page is critical. I have already discussed 2 checkout options in my previous articles BrainTree PayPal using PHP and Payment System which were in most trend till day. Now, a new checkout option has been introduced by Paypal which is Paypal Express Checkout option.

PayPal Express Checkout with PHP and MySQL


Live Demo


Database Design
To build the user order system, you have to create three tables such as Users, Products, and Orders.

PayPal Express Checkout with PHP Design

Users
User table contains all the users registration details.
CREATE TABLE users(
uid int AUTO_INCREMENT PRIMARY KEY,
username varchar(50),
password varchar(300),
name varchar(200),
email varchar(300));

Products
This table contains product details.
CREATE TABLE products(
pid int PRIMARY KEY AUTO_INCREMENT,
product varchar(300),
product_img varchar(300),
price int,
currency varchar(10)
);

Orders
This table contains user order details.
CREATE TABLE orders(
oid int PRIMARY KEY AUTO_INCREMENT,
uid_fk int,
pid_fk int,
payerID varchar(300),
paymentID varchar(300),
token varchar(300),
created int
);

Video Tutorial
PayPal Express Checkout with PHP and MySQL


Getting started with PayPal Express Checkout

Create Sandbox Account
Go to PayPal Developer and create a sandbox account for development.
Getting started with PayPal Express Checkout

Make sure choose account type as bussiness and give some PayPal balanace number.
Getting started with PayPal Express Checkout

Create REST API Application
Now go to PayPal dashboard and scroll down, you will find a REST API apps and click on create app button.
Getting started with PayPal Express Checkout

Give your application name and choose your sandbox account. This only works with PayPal business accounts.
Getting started with PayPal Express Checkout

Application Credentials
Here you will find both Sandbox and Live Client ID and Secret values.
Getting started with PayPal Express Checkout

PHP Development
Project structure.
Getting started with PayPal Express Checkout

config.php
Database and PayPal checkout API configuration file. Here you have to modify PayPal credentials for Sandbox and Live. Function getDB() help you to create a PDO connection with MySQL database.
<?php
//ob_start();
error_reporting(0);
session_start();

/* DATABASE CONFIGURATION */
define('DB_SERVER', 'localhost');
define('DB_USERNAME', 'username');
define('DB_DATABASE', 'database_name');
define('DB_PASSWORD', 'password');
define("BASE_URL", "http://localhost/PHP-PayPal-ExpressCheckout/");
define('PRO_PayPal', 0); // PayPal live change 0 to 1


if(PRO_PayPal){
    define("PayPal_CLIENT_ID", "##Your Production/Live Client ID##");
    define("PayPal_SECRET", "##Your Production/Live Secret ID##");
    define("PayPal_BASE_URL", "https://api.paypal.com/v1/");
}
else{
    define("PayPal_CLIENT_ID", "##Your Sandbox Client ID##");
    define("PayPal_SECRET", "##Your Sandbox Secret ID##");
    define("PayPal_BASE_URL", "https://api.sandbox.paypal.com/v1/");
}

function getDB()
{
    $dbhost=DB_SERVER;
    $dbuser=DB_USERNAME;
    $dbpass=DB_PASSWORD;
    $dbname=DB_DATABASE;
    $dbConnection = new PDO("mysql:host=$dbhost;dbname=$dbname", $dbuser, $dbpass);
    $dbConnection->exec("set names utf8");
    $dbConnection->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
    return $dbConnection;
}
?>


paypalExpress.php
PHP class for all the project operations like user login, getting product details, PayPal backend check etc.
<?php
class paypalExpress
{
    public function userLogin($username,$password)
    {

        $db = getDB();
        $hash_password= hash('sha256', $password);
        $stmt = $db->prepare("SELECT uid FROM users WHERE  username=:username and password=:hash_password");
        $stmt->bindParam("username", $username, PDO::PARAM_STR) ;
        $stmt->bindParam("hash_password", $hash_password, PDO::PARAM_STR) ;
        $stmt->execute();
        $db = null;

        if($stmt->rowCount()==1)
        {
            $data = $stmt->fetch(PDO::FETCH_OBJ);
            $_SESSION['session_uid'] = $data->uid;
            return $data->uid;
        }
        else
        {
            return false;
        }
    }


    // Other functions
}
?>

index.php
Here index is a user login page. Using $paypalExpress->userLogin() function, verifing the user login details.
<?php
require 'config.php';
require 'class/paypalExpress.php';

$errorMsgLogin ='';
if (!empty($_POST['loginSubmit']))
{
    $usernameEmail=$_POST['username'];
    $password=$_POST['password'];
    if(strlen(trim($usernameEmail))>1 && strlen(trim($password))>1 )
    {
        $paypalExpress = new paypalExpress();
        $uid=$paypalExpress->userLogin($usernameEmail,$password);
        if($uid)
        {
            header("Location:home.php"); // Page redirecting to home.php
        }
        else
        {
            $errorMsgLogin="Please check login details.";
        }
    }
}
?>
<form action="" method="post">
    <label>Username</label>
    <input type="text" value="" name="username" class="input" />
    <label>Password</label>
    <input type="password" value="" name="password"  class="input" />
    <div>
    <input type="submit" value=" Log In" name="loginSubmit" />
    </div>
    <div> <?php echo $errorMsgLogin ?></div>
</form>

home.php
Displaying all of the product details. Clicking on order button this will redirect to checkout page for actual payment process.
<?php
require 'config.php';
require 'session.php';
require 'class/paypalExpress.php';
$paypalExpress = new paypalExpress();
$getAllProducts = $paypalExpress->getAllProducts();
?>
//Logout link
<a href="logout.php" class="logout">Logout</a>
<table>
<?php foreach($getAllProducts as $product){ ?>
<tr>
      <td >
      <img src="img/<?php echo $product->product_img; ?>" />
      </td>
      <td>$<?php echo $product->price; ?></td>
       <td >
      <a href="<?php echo BASE_URL.'checkout.php?pid='.$product->pid; ?>" class="wallButton">Order</a></td>
        </tr>
      <?php } ?>
</table>

getProducts
Getting all of the products.
public function getAllProducts()
    {
        $db = getDB();
        $stmt = $db->prepare("SELECT * FROM products");
        $stmt->bindParam("pid", $pid, PDO::PARAM_INT) ;
        $stmt->execute();
        $data = $stmt->fetchAll(PDO::FETCH_OBJ);
        $db=null;
        return $data;
}

checkout.php
Product information displaying here based on the product id. Here paypalButton.php file contains PayPal express API JavaScript client code.
<?php
require 'config.php';
require 'session.php';
require 'class/paypalExpress.php';
if(!empty($_GET['pid']) && $_GET['pid']>0){
    $paypalExpress = new paypalExpress();
    $product = $paypalExpress->getProduct($_GET['pid']);
}
else{
   header("Location:home.php");
}
?>
<table>
<tr>
<td >
<img src="img/<?php echo $product->product_img; ?>" />
</td>
<td >$<?php echo $product->price; ?> </td>
<td width="20%">
<?php require 'paypalButton.php'; ?>
</td>
</tr>
</table>

paypalButton.php
Dynamicly changing the product price details with PHP defined configuration values. You can control this file from config.php, like to swithing between Sandbox and Live. Once payment is successful, this will send payment information to the process.php file for cross checking.
<div id="paypal-button-container"></div>
<script src="https://www.paypalobjects.com/api/checkout.js"></script>
<script>
paypal.Button.render({
<?php if(PRO_PayPal) { ?>
      env: 'production',
<?php } else {?>
       env: 'sandbox',
<?php } ?>

client: {
     sandbox:    '<?php echo PayPal_CLIENT_ID; ?>',
     production: '<?php echo PayPal_CLIENT_ID; ?>'
},

// Show the buyer a 'Pay Now' button in the checkout flow
commit: true,

// payment() is called when the button is clicked
payment: function(data, actions) {

   // Make a call to the REST api to create the payment
   return actions.payment.create({
   payment: {
        transactions: [
       {
        amount: {
        total: '<?php echo $product->price ?>',
       currency: '<?php echo $product->currency ?>'
        }
        } ]
        }
        });
        },

        // onAuthorize() is called when the buyer approves the payment
         onAuthorize: function(data, actions) {
                // Make a call to the REST api to execute the payment
                return actions.payment.execute().then(function() {
                console.log('Payment Complete!');

                window.location = "<?php echo BASE_URL ?>process.php?paymentID="+data.paymentID+"&payerID="+data.payerID+"&token="+data.paymentToken+"&pid=<?php echo $product->pid  ?>";

                });
            }
        }, '#paypal-button-container');
</script>

process.php
Here is the most important process happen to create an user order.
<?php
require 'config.php';
require 'session.php';
require 'class/paypalExpress.php';
if(!empty($_GET['paymentID']) && !empty($_GET['payerID']) && !empty($_GET['token']) && !empty($_GET['pid']) ){
    $paypalExpress = new paypalExpress();
    $paymentID = $_GET['paymentID'];
    $payerID = $_GET['payerID'];
    $token = $_GET['token'];
    $pid = $_GET['pid'];

    $paypalCheck=$paypalExpress->paypalCheck($paymentID, $pid, $payerID, $token);
    if($paypalCheck){
        header('Location:orders.php'); // Success redirect to orders
    }
}
else{
    header('Location:home.php'); // Fail
}
?>

paypalCheck function
This contains a PHP curl functionality and in backend this will communicate with PayPal API for order cofirmation. Here it again cross verifies with package price and currency to avoid any bad payments.
<?php
public function paypalCheck($paymentID, $pid, $payerID, $paymentToken){

    $ch = curl_init();
    $clientId = PayPal_CLIENT_ID;
    $secret = PayPal_SECRET;
    curl_setopt($ch, CURLOPT_URL, PayPal_BASE_URL.'oauth2/token');
    curl_setopt($ch, CURLOPT_HEADER, false);
    curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
    curl_setopt($ch, CURLOPT_POST, true);
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
    curl_setopt($ch, CURLOPT_USERPWD, $clientId . ":" . $secret);
    curl_setopt($ch, CURLOPT_POSTFIELDS, "grant_type=client_credentials");
    $result = curl_exec($ch);
    $accessToken = null;


    if (empty($result)){
        return false;
    }

    else {
        $json = json_decode($result);
        $accessToken = $json->access_token;
        $curl = curl_init(PayPal_BASE_URL.'payments/payment/' . $paymentID);
        curl_setopt($curl, CURLOPT_POST, false);
        curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, false);
        curl_setopt($curl, CURLOPT_HEADER, false);
        curl_setopt($curl, CURLOPT_RETURNTRANSFER, true);
        curl_setopt($curl, CURLOPT_HTTPHEADER, array(
        'Authorization: Bearer ' . $accessToken,
        'Accept: application/json',
        'Content-Type: application/xml'
        ));
        $response = curl_exec($curl);
        $result = json_decode($response);


        $state = $result->state;
        $total = $result->transactions[0]->amount->total;
        $currency = $result->transactions[0]->amount->currency;
        $subtotal = $result->transactions[0]->amount->details->subtotal;
        $recipient_name = $result->transactions[0]->item_list->shipping_address->recipient_name;
        curl_close($ch);
        curl_close($curl);

        $product = $this->getProduct($pid);

        if($state == 'approved' && $currency == $product->currency && $product->price ==  $subtotal){
            $this->updateOrder($pid, $payerID, $paymentID, $paymentToken);
            return true;
 
        }
        else{
 
            return false;
        }

    }

}
?>

orders.php
Displaying all of the orders based on user session id.
<?php
require 'config.php';
require 'session.php';
require 'class/paypalExpress.php';
$paypalExpress = new paypalExpress();
$orders = $paypalExpress->orders();
?>
<?php if($orders) { ?>
<table>
<?php foreach($orders as $order){  ?>
<tr>
   <td>ORDER - <?php echo $order->oid; ?></td>
   <td><?php echo $order->product; ?></td>
   <td><?php echo $order->price.' '.$order->currency; ?></td>
   <td><?php echo $paypalExpress->timeFormat($order->created); ?></td>
</tr>
<?php } ?>
</table>
<?php }  else { ?>
<div> No Orders</div>
<?php } ?>


logout.php
Clearing user session.
<?php
$_SESSION['session_uid'] = '';
$sesson_uid = '';
session_destroy();
if(empty($_SESSION['session_uid']) &&  empty($sesson_uid)){
    header('Location:index.php');
}
?>


sessions.php
Common session code, you have to include this in all of the pages. If the user session is not found, this will redirect to index/login page.
<?php
$sesson_uid = '';
if(!empty($_SESSION['session_uid'] )){
    $sesson_uid = $_SESSION['session_uid'] ;
}
else{
    header('Location:index.php');
}
?>

Express Checkout gives your buyers a simplified checkout experience that keeps them local to your website or mobile app throughout the payment authorization process and lets them use their PayPal balance, bank account or credit card to pay without sharing or entering any sensitive information on your site. An order is stored immediately after payment is completed and this happens while the customer is actively engaged on your website. When payment is complete, the customer is redirected to your website, but your website is immediately informed by PayPal whether the transaction was successful or not. The Express Checkout flow keeps the buyer on your web page or mobile app throughout the entire checkout flow. All this process makes the buyer details more secured and also the process is fast. Hope you all like to integrate this PayPal Express Checkout process in your website and provide a good feel for the buyers to buy on the website.
Was this article helpful?
Thanks! Your feedback helps us to improve 9lessons.info


11 comments:

  1. Nice tutorial SIR. Are you asking? Sure will definitely integrate this system.. Wanna also know if it will work in Nigeria?

    ReplyDelete
  2. logout button does not working, redirect to home page instead of index page

    ReplyDelete
  3. Hello Sir,

    I follow above step and create my own page and it's works fine but if i replace our PayPal_CLIENT_ID and PayPal_SECRET to my then it not work.It was redirect successfully bit give "Things don’t appear to be working at the moment.".
    Please advice me.

    ReplyDelete
    Replies
    1. Are you getting this message from PayPal?

      Delete
  4. Thanks for such important information...
    I must say that these kind of works that your are doing is really hard to find.

    ReplyDelete
  5. It was such a nice article i amluv it
    keep on sharing

    ReplyDelete

Make in India