PayPal Express Checkout with PHP and MySQL

768

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.

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

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.

Make sure choose account type as bussiness and give some PayPal balanace number.

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.

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

Application Credentials
Here you will find both Sandbox and Live Client ID and Secret values.

PHP Development
Project structure.

 

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.phpfile 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.