Shopping Cart with PayPal Integration in PHP

In previous tutorial you have learned how to create shopping cart with Ajax, PHP and MySQL to add items to the cart using Ajax. But its still needs further steps to handle payment of the cart items. So in this tutorial, you will learn how to integrate PayPal payment gateway into shopping cart to handle payment. We will use same shopping cart example to add payment functionality. As in previous shopping cart example, we have already handled to show cart detail to checkout and review cart details before placing order with payable amount. So now we will handle to get customer shipping details and then handle payment with PayPal gateway.

Step1: Create PayPal Sandbox Account
As we will learn to integrate PayPal payment gateway, so we need to test it before live. For this we will need to create PayPal sandbox account to test PayPal payment gateway on your website without real payment. So if you have not PayPal sandbox account then create it.

Step2: Create Database Tables
We will use following MySQL database tables to handle entire shopping cart.

the product details are stored into the shop_products table.
CREATE TABLE `shop_products` (
`id` int(11) NOT NULL,
`product_name` varchar(60) NOT NULL,
`product_desc` text NOT NULL,
`product_code` varchar(60) NOT NULL,
`product_image` varchar(60) NOT NULL,
`product_price` int(11) NOT NULL

the order details will be stored in shop_order table.

CREATE TABLE `shop_order` (
`id` int(11) NOT NULL,
`member_id` int(11) NOT NULL,
`name` varchar(100) NOT NULL,
`address` varchar(100) NOT NULL,
`mobile` int(11) NOT NULL,
`email` varchar(100) NOT NULL,
`order_status` varchar(255) NOT NULL,
`order_at` datetime NOT NULL,
`payment_type` varchar(255) NOT NULL

the order item details will be stored in shop_order_item table.
CREATE TABLE `shop_order_item` (
`id` int(11) NOT NULL,
`order_id` int(11) NOT NULL,
`product_id` int(11) NOT NULL,
`item_price` double NOT NULL,
`quantity` int(11) NOT NULL

and the paymen details will be stored in shop_payment table.

CREATE TABLE `shop_payment` (
`id` int(11) NOT NULL,
`order_id` int(11) NOT NULL,
`payment_status` varchar(255) NOT NULL,
`payment_response` text NOT NULL,

Step3: Customer Shipping Details
As we have already covered product add to cart, checkout and review order details before placing order. So now we will place order and get customer shipping details. We will design HTML form in user.php file to ask customer to enter shipping details to save before making payment. Then the form will take to payment page to handle payment.

<h2>Customer Shipping Details</h2>
<div class="col-md-8">
<form class="form-horizontal" method="post" enctype="multipart/form-data" action="payment.php">
<div class="form-group">
<div class="col-sm-6">
<input type="text" class="form-control" placeholder="First Name" name="firstName" required />
<div class="form-group">
<div class="col-sm-6">
<input type="text" class="form-control" placeholder="Last Name" name="lastName" required />
<div class="form-group">
<div class="col-sm-6">
<textarea class="form-control" rows="5" placeholder="Address" name="address" required ></textarea>
<div class="form-group">
<div class="col-sm-8">
<input type="number" class="form-control" min="9" placeholder="Contact number" name="contactNumber" required />
<div class="form-group">
<div class="col-sm-6">
<input type="email" class="form-control" placeholder="Email" name="emailAddress" required />
<div class="form-group">
<div class="col-sm-4">
<input class="btn btn-primary" type="submit" name="proceedPayment" value="Proceed to payment"/>

Step4: Save Order Details
Now we will handle functionality to save order details into table shop_order with customer shipping details.
if(!empty($_POST["proceedPayment"])) {
$firstName = $_POST ['firstName'];
$lastName = $_POST ['lastName'];
$address = $_POST ['address'];
$contactNumber = $_POST ['contactNumber'];
$emailAddress = $_POST ['emailAddress'];
$insertOrderSQL = "INSERT INTO shop_order(member_id, name, address, mobile, email, order_status, order_at, payment_type)VALUES('".$member_id."', '".$firstName." ".$lastName."', '".$address."', '".$contactNumber."', '".$emailAddress."', 'PENDING', '".date("Y-m-d H:i:s")."', 'PAYPAL')";
mysqli_query($conn, $insertOrderSQL) or die("database error:". mysqli_error($conn));
$order_id = mysqli_insert_id($conn);

we will also save order item details into table shop_order_item.

if($order_id) {
if(isset($_SESSION["products"]) && count($_SESSION["products"])>0) {
foreach($_SESSION["products"] as $product){
$insertOrderItem = "INSERT INTO shop_order_item(order_id, product_id, item_price, quantity)VALUES('".$order_id."', '".$product["product_code"]."', '". $product["product_price"]."', '".$product["product_qty"]."')";
mysqli_query($conn, $insertOrderItem) or die("database error:". mysqli_error($conn));

Step5: Handle Order Place
Now in payment.php, we will handle order place functionality to handle payment with PayPal. We will pass required value like item_numer, amount, currency_code, notify_url, return_url and more to sent to the PayPal to handle payment.

<form class="form-horizontal" action="" method="POST">
<input type='hidden' name='business' value='Your Business Email Address'>
<input type='hidden' name='item_name' value='<?php echo $_SESSION["cartItems"]; ?>'>
<input type='hidden' name='item_number' value="<?php echo $order_id; ?>">
<input type='hidden' name='amount' value='<?php echo $_SESSION["payableAmount"]; ?>'>
<input type='hidden' name='currency_code' value='USD'>
<input type='hidden' name='notify_url' value=''>
<input type='hidden' name='return' value=''>
<input type="hidden" name="cmd" value="_xclick">
<input type="hidden" name="order" value="<?php echo $_SESSION["orderNumber"]; ?>">
<div class="form-group">
<div class="col-sm-2">
<input type="submit" class="btn btn-lg btn-block btn-danger" name="continue_payment" value="Pay Now">

Step6: Process Payment
When Pay Now button clicked, the buyer redirected to PayPal payment page to pay for his order. After successful payment, the notify_url notify.php file called to notify about payment status. The payment verified with PayPal in notify.php and payment updated with order status update.

$postData = file_get_contents('php://input');
$postArray = explode('&', $postData);
$postValue = array();
foreach ($postArray as $value) {
$value = explode ('=', $value);
if (count($value) == 2)
$postValue[$value[0]] = urldecode($value[1]);
// read the post from PayPal system and add 'cmd'
$req = 'cmd=_notify-validate';
if(function_exists('get_magic_quotes_gpc')) {
$get_magic_quotes_exists = true;
foreach ($postValue as $key => $value) {
if($get_magic_quotes_exists == true && get_magic_quotes_gpc() == 1) {
$value = urlencode(stripslashes($value));
} else {
$value = urlencode($value);
$req .= "&$key=$value";
// The post IPN data back to PayPal to validate the IPN data
$ch = curl_init("");
if ($ch == FALSE) {
return FALSE;
curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_RETURNTRANSFER,1);
curl_setopt($ch, CURLOPT_POSTFIELDS, $req);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, 1);
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, 2);
curl_setopt($ch, CURLOPT_FORBID_REUSE, 1);
curl_setopt($ch, CURLOPT_HEADER, 1);
curl_setopt($ch, CURLINFO_HEADER_OUT, 1);
curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 30);
curl_setopt($ch, CURLOPT_HTTPHEADER, array('Connection: Close'));
$res = curl_exec($ch);
if (curl_errno($ch) != 0) {
error_log(date('[Y-m-d H:i e] '). "Can't connect to PayPal to validate IPN message: " . curl_error($ch) . PHP_EOL, 3, 'app.log');
} else {
error_log(date('[Y-m-d H:i e] '). "HTTP request of validation request:". curl_getinfo($ch, CURLINFO_HEADER_OUT) ." for IPN payload: $req" . PHP_EOL, 3, 'app.log');
error_log(date('[Y-m-d H:i e] '). "HTTP response of validation request: $res" . PHP_EOL, 3, 'app.log');
// Inspect IPN validation result and act accordingly
$payment_response = $res;
$tokens = explode("\r\n\r\n", trim($res));
$res = trim(end($tokens));
if (strcmp ($res, "VERIFIED") == 0) {
$item_name = $_POST['item_name'];
$item_number = $_POST['item_number'];
$payment_status = $_POST['payment_status'];
$payment_amount = $_POST['mc_gross'];
$payment_currency = $_POST['mc_currency'];
$txn_id = $_POST['txn_id'];
$receiver_email = $_POST['receiver_email'];
$payer_email = $_POST['payer_email'];
$isPaymentCompleted = false;
if($payment_status == "Completed") {
$isPaymentCompleted = true;
// insert payment details
$insertPayment = "INSERT INTO shop_payment(order_id, payment_status, payment_response)VALUES('".$order_id."', '".$payment_status."', '".$payment_response."')";
mysqli_query($conn, $insertPayment) or die("database error:". mysqli_error($conn));
// update order status after payment
$updateOrder = "UPDATE shop_order set order_status = 'PAID' WHERE id = '".$item_number."'";
mysqli_query($conn, $updateOrder) or die("database error:". mysqli_error($conn));
error_log(date('[Y-m-d H:i e] '). "Verified IPN: $req ". PHP_EOL, 3, 'app.log');
} else if (strcmp ($res, "INVALID") == 0) {
error_log(date('[Y-m-d H:i e] '). "Invalid IPN: $req" . PHP_EOL, 3, 'app.log');

Step7: Payment Success
After successful payment at PayPal, it return to success page success.php. We can get basic payment details from PayPal using $_GET method like transaction ID, gross payment amount, currency code, and payment status. You can cross check payment details with stored payment details to display order payment success page.

You can view the live demo from the Demo link and can download the script from the Download link below.
Demo [sociallocker]Download[/sociallocker]

You may like these posts