Payment System with BrainTree PayPal using PHP
Wall Script
Follow Me:
Monday, October 05, 2015

Payment System with BrainTree PayPal using PHP

Are you working for e-commerce project? Then you should have a better and secure payment system. I suggest you setup you project with BrainTree API, it is very powerful and quick. This is accepting most commonly used Cards, PayPal, Android Pay and etc. This post will explain you how to design a cart and order system with BrainTree payment process using PHP and MySQL. Take a quick look the live demo and try demo transaction.

Payment System with BrainTree PayPal using PHP


Download Script     Live Demo

Database Design
To build the eCommerce system, you have to create four basic tables such as Users, Producs, Orders and Cart.

User Table
User table contains all the users registration details.
CREATE TABLE Users(
user_id INT  PRIMARY KEY AUTO_INCREMENT,
username VARCHAR(50),
password VARCHAR(100),
email VARCHAR(100)
);

Payment System User Table

Products Table
This contains all of the product details.
CREATE TABLE Products(
product_id INT PRIMARY KEY AUTO_INCREMENT,
product_name VARCHAR(200),
product_desc TEXT,
price FLOAT
);

Payment System Products Table

Orders Table
User successful orders store here with BrainTree status code.
CREATE TABLE Orders(
order_id INT PRIMARY KEY AUTO_INCREMENT,
user_id_fk INT,
created INT,
price FLOAT,
FOREIGN KEY(user_id_fk) REFERENCES Users(user_id)
);

Payment System Orders Table

Payment System with BrainTree PayPal User table design

Cart Table
This table contains all the user cart details. Cart order_id_fk is a foreign key, it references to Orders order_id. This will update once the user Order is successful.
CREATE TABLE Cart(
cart_id INT PRIMARY KEY AUTO_INCREMENT,
product_id_fk INT,
user_id_fk INT,
order_id_fk INT,
cart_status enum('0','1') DEFAULT '0',
FOREIGN KEY(product_id_fk) REFERENCES Products(product_id),
FOREIGN KEY(user_id_fk) REFERENCES Users(user_id),
FOREIGN KEY(order_id_fk) REFERENCES Orders(order_id)
);

Payment System Cart Table

Payment System with BrainTree PayPal cart database design

Payment Form & System Design
This project contains three folders called js,includes and uploads with PHP files.

braintree
-- braintree.php //BrainTree library file
js
-- jquery.min.js
-- jquery.creditCardValidator.js
index.php
cardProcess.php
functions.php
db.php

Payment form contains Card Number, Card Name, Expiry Date and CVV(Secure Number).

Payment System with BrainTree PayPal cart database design

HTML5 Code
Simple HTML5 code
<form method="post"  id="paymentForm">
Payment details
<ul>

<li>
<label>Card Number </label>
<input type="text" name="card_number" id="card_number"  maxlength="20" placeholder="1234 5678 9012 3456"/>
</li>
<li>
<label>Name on Card</label>
<input type="text" name="card_name" id="card_name" placeholder="Srinivas Tamada"/>
</li>
<li class="vertical">

<ul>
<li>
<label>Expires</label>
<input type="text" name="expiry_month" id="expiry_month" maxlength="2" placeholder="MM" />
<input type="text" name="expiry_year" id="expiry_year" maxlength="2" placeholder="YY" />
</li>
<li>
<label>CVV</label>
<input type="text" name="cvv" id="cvv" maxlength="3" placeholder="123" />
</li>
</ul>

</li>
<li>
<input type="submit" id="paymentButton" value="Proceed" disabled="true" class="disable">
</li>
</ul>
</form>
<div id="orderInfo"></div>

CSS Code
*{margin: 0px; padding:0px;}
ul {list-style: none;}
label{padding:8px 0px 8px 0px;}
#paymentForm label
{
color: #555;
display: block;
font-size: 14px;
font-weight: 400;
}
#paymentForm input[type=text]
{
background-color: #FFFFFF;
border: 1px solid #E5E5E5;
color: #333333;
display: block;
font-size: 18px;
height: 32px;
padding: 0 5px;
width: 275px;
}
#paymentForm li {margin: 8px 0;}
#orderInfo{display:none}
.disable{opacity: 0.2}
.vertical li
{
float: left;
width: 140px;
}

JavaScript
Validating the payment form using Regular Expressions.
<script src="js/jquery.min.js"></script>
<script src="js/jquery.creditCardValidator.js"></script>
<script>
$(document).ready(function()
{
/* Form Validation */
$("#paymentForm input[type=text]").on("keyup",function()
{
var cardValid=$("#card_number").attr('rel');
var C=$("#card_name").val();
var M=$("#expiry_month").val();
var Y=$("#expiry_year").val();
var CVV=$("#cvv").val();
var expName =/^[a-z ,.'-]+$/i;
var expMonth = /^01|02|03|04|05|06|07|08|09|10|11|12$/;
var expYear = /^16|17|18|19|20|21|22|23|24|25|26|27|28|29|30|31$/;
var expCVV=/^[0-9]{3,3}$/;

if(cardValid>0 && expName.test(C) && expMonth.test(M) && expYear.test(Y)
&& expCVV.test(CVV) && parseInt(cardCheck)>0)
{
$('#paymentButton').prop('disabled', false);
$('#paymentButton').removeClass('disable');
}
else
{
$('#paymentButton').prop('disabled', true);
$('#paymentButton').addClass('disable');
}
});

/* Card Validation */
cardValidate();

/*Payment Form */
$("#paymentForm").submit(function()
{
//.......
});

});
</script> 

Card Validation
Credit Card Validation using jquery.validateCreditCard plugin.
/* Credit Card Type Check */
function cardValidate()
{
$('#card_number').validateCreditCard(function(result)
{
var N=$(this).val();
var C=$(this).attr("class");
$(this).attr("class","");
if(result && N.length>0)
{
$(this).addClass(result.card_type.name);

if(result.valid && result.length_valid && result.luhn_valid)
{
$(this).addClass('valid');
$(this).attr("rel","1");
}
else
{
$(this).attr("rel","1");
}

}
else
{
$(this).removeClass(C);
}
});
}


Ajax Payment Process
BrainTree Payment process with Jquery Ajax, here $(this).serialize() get all the form input values and posting to cardProcess.php. Once order is successful, use will get the Order status message.
/*Payment Form */
$("#paymentForm").submit(function()
{
var datastring = $(this).serialize();
$.ajax({
type: "POST",
url: "cardProcess.php",
data: datastring,
dataType: "json",
beforeSend: function(){  $("#paymentButton").val('Processing..') },
success: function(data)
{
$.each(data.OrderStatus, function(i,data)
{
var HTML;
if(data)
{
$("#paymentGrid").slideUp("slow");
$("#orderInfo").fadeIn("slow");

if(data.status == '1')
{
HTML="Order <span>"+data.orderID+"</span> has been created successfully.";
}
else if(data.status == '2')
{
HTML="Transaction has been failed, please use other card.";
}
else
{
HTML="Card number is not valid, please use other card.";
}

$("#orderInfo").html(HTML);
}
});
},
error: function(){ alert('Network Error'); }
});
return false;
});

BrainTree Integration
Create a sandbox account at sandbox.braintreegateway.com for testing process.

Payment System with BrainTree PayPal using PHP

Go to Account -> My User scroll down you will find API keys.
Payment System with BrainTree PayPal using PHP

You will find merchantId, publicKey and privateKey
Payment System with BrainTree PayPal using PHP
cardProcess.php
Here you have to modify with your BrainTree merchandID, pulicKey and privateKey. This is update Orders table, once the transaction is successful. Always maintain/store cart total price value in session. Once testing is done, you can modify environment value from sandbox to production.
<?php
include 'db.php';
include 'functions.php';
$session_price =$_SESSION['session_price']; //Cart Total Price 
if($_SERVER["REQUEST_METHOD"] == "POST" )
{
$card_number=str_replace("+","",$_POST['card_number']);
$card_name=$_POST['card_number'];
$expiry_month=$_POST['expiry_month'];
$expiry_year=$_POST['expiry_year'];
$cvv=$_POST['cvv'];
$expirationDate=$expiry_month.'/'.$expiry_year;

require_once 'braintree/Braintree.php';
Braintree_Configuration::environment('sandbox'); // Change to production
Braintree_Configuration::merchantId('Merchant_ID');
Braintree_Configuration::publicKey('Public_Key');
Braintree_Configuration::privateKey('Private_Key');
//BrainTree payment process
$result = Braintree_Transaction::sale(array(
'amount' => $price,
'creditCard' => array(
'number' => $card_number,
'cardholderName' => $card_name,
'expirationDate' => $expirationDate,
'cvv' => $cvv
)
));

if ($result->success)
{
if($result->transaction->id)
{
$braintreeCode=$result->transaction->id;
updateUserOrder($braintreeCode,$session_user_id,$session_price); //Order table update. 
}
}
else if ($result->transaction)
{
echo '{"OrderStatus": [{"status":"2"}]}';
}
else 
{
echo '{"OrderStatus": [{"status":"0"}]}';
}
}
?>

Update User Order
This will update orders table, based on the BrainTree status code. Cart table status will change 0 to 1 with order id.
<?php
function updateUserOrder($braintreeCode,$session_user_id,$session_price)
{
$db = getDB();
$sql = "INSERT INTO Orders(user_id_fk,created,braintreeCode)VALUES(:user_id,:created,:braintreeCode)";
$stmt = $db->prepare($sql);
$stmt->bindParam("user_id", $session_user_id);
$time=time();
$stmt->bindParam("created", $time);
$stmt->bindParam("braintreeCode", $braintreeCode);
$stmt->execute();

$sql1 = "SELECT order_id FROM Orders WHERE user_id_fk=:user_id ORDER BY order_id DESC LIMIT 1";
$stmt1 = $db-> prepare($sql1);
$stmt1-> bindParam("user_id", $session_user_id);
$stmt1-> execute();
$OrderDetails = $stmt1->fetchAll(PDO::FETCH_OBJ);
$order_id=$OrderDetails[0]->order_id;

$sql2 = "UPDATE Cart SET order_id_fk=:order_id,cart_status='1',price=:price WHERE cart_status='0' AND user_id_fk=:user_id";
$stmt2 = $db-> prepare($sql2);
$stmt2-> bindParam("user_id", $session_user_id);
$stmt2-> bindParam("order_id", $order_id);
$stmt2-> bindParam("price", $session_price);
$stmt2-> execute();
$db = null;
echo '{"OrderStatus": [{"status":"1", "orderID":"'.$order_id.'"}]}';
}
?>

Get User Cart Details
Getting card details based on user session id.
<?php
function getUserCartDetails($session_user_id)
{
$db = getDB();
$sql = "SELECT P.product_name,P.price FROM Users U, Cart C, Products P WHERE U.user_id=C.user_id_fk AND P.product_id = C.product_id_fk AND C.user_id_fk=:user_id AND C.cart_status='0'";
$stmt = $db->prepare($sql);
$stmt->bindParam("user_id", $session_user_id);
$stmt->execute();
$getUserCartDetails = $stmt->fetchAll(PDO::FETCH_OBJ);
$db = null;
return $getUserCartDetails;
}
?>

Live Demo


db.php
You have to modify username, password and databaseName values. Make sure enable PDO extension in PHP.ini.
<?php
function getDB() {
$dbhost="localhost";
$dbuser="username";
$dbpass="password";
$dbname="databaseName";
$dbConnection = new PDO("mysql:host=$dbhost;dbname=$dbname", $dbuser, $dbpass);
$dbConnection->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
return $dbConnection;
}

/* User Sessions */
session_start();
$session_user_id=$_SESSION['user_id'];

Note: Once your testing is done, create a BrainTree production account and modify the key details.
Was this article helpful?
Thanks! Your feedback helps us to improve 9lessons.info


31 comments:

  1. Thank Srinivas Tamada!

    Nice article, it's useful with me.

    Kevin.

    ReplyDelete
  2. You always post what developers needs in everyday development. It will be great if you cover all the payment gateways. specially paypal recurring.

    ReplyDelete
  3. Your post really help me out for the payment integration of braintree on my custom php script. Thanks a ton.

    ReplyDelete
  4. thanks very much, its most important for developer, i really need some idea about payment for e-commerce since a week, but with good luck and help all of you i find it
    thanks a lot

    ReplyDelete
  5. Thanks a lot sir. I am appreciating your approach. This is really important for developers. Your post is always inspiring me, to love our jobs. i am working as Sr. PHP Developer in a small company. This code is very helpful for me and other developer. Thanks a lot once again.

    ReplyDelete
    Replies
    1. @Praveen Kumar Thanks a lot for such a nice comment. :)

      Delete
    2. HI Srinivas Tamada


      Am searching this script on today.am so lucky..i got script from u.i didn't expect .thanks a lot

      Delete
  6. Thanks very much for your clear and comprehensive guide.

    However, I am having some issues with processing the payment:

    GET https://orderin24.es/images/macbook.png 404 (Not Found)
    jquery.min.js:4 POST https://orderin24.es/cardProcess.php 500 (Internal Server Error)n.ajaxTransport.k.cors.a.crossDomain.send @ jquery.min.js:4n.extend.ajax @ jquery.min.js:4(anonymous function) @ card.js:71n.event.dispatch @ jquery.min.js:3n.event.add.r.handle @ jquery.min.js:3

    ''error handling here''

    ReplyDelete
  7. Hi,
    I had read your article and you have described it really very well. But I have one question is there this system will be trustful to user as its creating payment processing form in own portal. As usual we are sending user to paypal site and there to feel safe to purchase. I am just confused is there the idea to use payment system on own site is good or to send user to payment getway provider page is safe ?
    Thanks for your great article.

    ReplyDelete
  8. Hello, I have downloaded your code, input the sql, however when I click the green Proceed button, it gives me a "error handling here" alert. What may be the reason for this?
    Thank you for this code and I am waiting for your answer!

    ReplyDelete
    Replies
    1. Were you able to solve this ANONYMOUS? Your question on october 17 at 8:32 is the same one that I have. I am not sure where to check the Ajax output or what I am looking for in this case?

      Delete
  9. Hope paypal doesn't limit the account again, which it has done a couple of times before to me. @Srinivas it would be very nice of you if you can guide for direct payment on a site like credit card, or other online payment processing

    ReplyDelete
  10. Is there any demo braintree with paypal express checkout?

    ReplyDelete
  11. Hi, Where have you created client token ?

    ReplyDelete
  12. its not taking session price value.. please suggest , issue with single quotes

    ReplyDelete
  13. sir when m downloding the script ...it tells CONFIDENTIAL
    This document contains sensitive information. how to resolve this.

    ReplyDelete
  14. I am downloading your code and perfect work for me (my site and also my local machine).

    Thanks,

    ReplyDelete
  15. May i know where your using client token and payment_method_nonce?

    ReplyDelete
  16. Nice tutorial :) do you have any examples using the node.js set up? Many thanks

    ReplyDelete
  17. Nice tutorial :-) I get the same error : "error handling here"
    I checked the jQuery output and it gives : jquery.min.js:4 POST http://localhost/braintree/cardProcess.php 500 (Internal Server Error)
    Any help is appreciated

    ReplyDelete
  18. there are alot of conflicts in the code you have displayed here and the code that you provide for download, please sync the code.

    ReplyDelete
  19. hi, i am also getting same error: "error handling here" ../braintree/cardProcess.php 500 (Internal Server Error).
    Any Help..

    ReplyDelete

Make in India