A payment gateway helps to collect payment online on the web application. If you want to allows the users to make payment through your website, online payment gateway needs to be integrated. PayPal is a widely used payment gateway that allows you to accept payment online in the web application. PayPal provides various options to integrate payment gateway, like PayPal Standard, PayPal Pro, PayPal Checkout, etc.
PayPal Checkout is the easiest way to integrate payment gateway in your web application. PayPal Express Checkout payment gateway is very useful when you want to provide a user-friendly UI to the user for the online payment. The PayPal Express Checkout executes payments directly from the browser and the user does not need to leave your website for payment
There are two ways to integrate PayPal Checkout payment gateway, client-side and server-side integration. In server integration, PayPal API is called to create, execute, and validate the payment. Also, it helps you to integrate PayPal payment gateway with express checkout experience. In this tutorial, we will show you how to integrate PayPal express checkout with PayPal API using PHP.
The example code demonstrates PayPal express checkout integration in PHP. Also, the transaction information will be stored in the MySQL database. The following steps will be implemented to integrate PayPal express checkout payment gateway in PHP.
Before getting started, look at the file structure of PayPal express checkout integration.
paypal_express_checkout_integration_php/ ├── config.php ├── index.php ├── checkout.php ├── payment-status.php ├── process.php ├── DB.class.php ├── PaypalExpress.class.php ├── css/ │ └── style.css └── images/
Before enabling payment gateway on your live site, it needs to be tested. PayPal Sandbox environment allows developers to test the transaction before making the payment gateway live. Follow the below steps to create PayPal sandbox account for PayPal express checkout.
To store products and transactions information two tables need to be created in the database. The following SQL creates products
and payments
tables in the MySQL database.
CREATE TABLE `products` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`name` varchar(255) COLLATE utf8_unicode_ci NOT NULL,
`image` varchar(255) COLLATE utf8_unicode_ci NOT NULL,
`price` float(10,2) NOT NULL,
`currency` varchar(10) COLLATE utf8_unicode_ci NOT NULL DEFAULT 'USD',
`status` tinyint(1) NOT NULL DEFAULT 1 COMMENT '1=Active, 0=Inactive',
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;
CREATE TABLE `payments` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`product_id` int(10) NOT NULL,
`txn_id` varchar(200) COLLATE utf8_unicode_ci NOT NULL,
`payment_gross` float(10,2) NOT NULL,
`currency_code` varchar(5) COLLATE utf8_unicode_ci NOT NULL,
`payer_id` varchar(20) COLLATE utf8_unicode_ci NOT NULL,
`payer_name` varchar(50) COLLATE utf8_unicode_ci NOT NULL,
`payer_email` varchar(50) COLLATE utf8_unicode_ci NOT NULL,
`payer_country` varchar(5) COLLATE utf8_unicode_ci NOT NULL,
`payment_status` varchar(10) COLLATE utf8_unicode_ci NOT NULL,
`created` datetime NOT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;
The DB class handles all the database related operations (fetch, insert, and update).
<?php
/*
* DB Class
* This class is used to handle the database related (connect, select, insert, and update) operations
* @author CodexWorld.com
* @url http://www.codexworld.com
* @license http://www.codexworld.com/license
*/
// Include configuration file
require_once 'config.php';
class DB{
private $dbHost = DB_HOST;
private $dbUsername = DB_USERNAME;
private $dbPassword = DB_PASSWORD;
private $dbName = DB_NAME;
public function __construct(){
if(!isset($this->db)){
// Connect to the database
$conn = new mysqli($this->dbHost, $this->dbUsername, $this->dbPassword, $this->dbName);
if($conn->connect_error){
die("Failed to connect with MySQL: " . $conn->connect_error);
}else{
$this->db = $conn;
}
}
}
/*
* Returns rows from the database based on the conditions
* @param string name of the table
* @param array select, where, order_by, limit and return_type conditions
*/
public function getRows($table,$conditions = array()){
$sql = 'SELECT ';
$sql .= array_key_exists("select",$conditions)?$conditions['select']:'*';
$sql .= ' FROM '.$table;
if(array_key_exists("where",$conditions)){
$sql .= ' WHERE ';
$i = 0;
foreach($conditions['where'] as $key => $value){
$pre = ($i > 0)?' AND ':'';
$sql .= $pre.$key." = '".$value."'";
$i++;
}
}
if(array_key_exists("order_by",$conditions)){
$sql .= ' ORDER BY '.$conditions['order_by'];
}
if(array_key_exists("start",$conditions) && array_key_exists("limit",$conditions)){
$sql .= ' LIMIT '.$conditions['start'].','.$conditions['limit'];
}elseif(!array_key_exists("start",$conditions) && array_key_exists("limit",$conditions)){
$sql .= ' LIMIT '.$conditions['limit'];
}
$result = $this->db->query($sql);
if(array_key_exists("return_type",$conditions) && $conditions['return_type'] != 'all'){
switch($conditions['return_type']){
case 'count':
$data = $result->num_rows;
break;
case 'single':
$data = $result->fetch_assoc();
break;
default:
$data = '';
}
}else{
if($result->num_rows > 0){
while($row = $result->fetch_assoc()){
$data[] = $row;
}
}
}
return !empty($data)?$data:false;
}
/*
* Insert data into the database
* @param string name of the table
* @param array the data for inserting into the table
*/
public function insert($table,$data){
if(!empty($data) && is_array($data)){
$columns = '';
$values = '';
$i = 0;
if(!array_key_exists('created', $data)){
$data['created'] = date("Y-m-d H:i:s");
}
foreach($data as $key=>$val){
$pre = ($i > 0)?', ':'';
$columns .= $pre.$key;
$values .= $pre."'".$val."'";
$i++;
}
$query = "INSERT INTO ".$table." (".$columns.") VALUES (".$values.")";
$insert = $this->db->query($query);
return $insert?$this->db->insert_id:false;
}else{
return false;
}
}
/*
* Update data into the database
* @param string name of the table
* @param array the data for updating into the table
* @param array where condition on updating data
*/
public function update($table,$data,$conditions){
if(!empty($data) && is_array($data)){
$colvalSet = '';
$whereSql = '';
$i = 0;
foreach($data as $key=>$val){
$pre = ($i > 0)?', ':'';
$colvalSet .= $pre.$key."='".$val."'";
$i++;
}
if(!empty($conditions)&& is_array($conditions)){
$whereSql .= ' WHERE ';
$i = 0;
foreach($conditions as $key => $value){
$pre = ($i > 0)?' AND ':'';
$whereSql .= $pre.$key." = '".$value."'";
$i++;
}
}
$query = "UPDATE ".$table." SET ".$colvalSet.$whereSql;
$update = $this->db->query($query);
return $update?$this->db->affected_rows:false;
}else{
return false;
}
}
}
The PaypalExpress class handles the PayPal API related operations.
validate() –
<?php
/*
* PaypalExpress Class
* This class is used to handle PayPal API related operations
* @author CodexWorld.com
* @url http://www.codexworld.com
* @license http://www.codexworld.com/license
*/
// Include configuration file
require_once 'config.php';
class PaypalExpress{
public $paypalEnv = PAYPAL_SANDBOX?'sandbox':'production';
public $paypalURL = PAYPAL_SANDBOX?'https://api.sandbox.paypal.com/v1/':'https://api.paypal.com/v1/';
public $paypalClientID = PAYPAL_API_CLIENT_ID;
private $paypalSecret = PAYPAL_API_SECRET;
public function validate($paymentID, $paymentToken, $payerID, $productID){
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $this->paypalURL.'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, $this->paypalClientID.":".$this->paypalSecret);
curl_setopt($ch, CURLOPT_POSTFIELDS, "grant_type=client_credentials");
$response = curl_exec($ch);
curl_close($ch);
if(empty($response)){
return false;
}else{
$jsonData = json_decode($response);
$curl = curl_init($this->paypalURL.'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 ' . $jsonData->access_token,
'Accept: application/json',
'Content-Type: application/xml'
));
$response = curl_exec($curl);
curl_close($curl);
// Transaction data
$result = json_decode($response);
return $result;
}
}
}
In the config.php
file, constant variables of the PayPal REST API and database settings are defined.
PayPal API Constants:
true
for sandbox environment and false
for production.Database Constants:
<?php
/*
* PayPal API configuration
* Remember to switch to your live API keys in production!
* See your keys here: https://developer.paypal.com/
*/
define('PAYPAL_API_CLIENT_ID', 'Your_REST_API_Client_ID');
define('PAYPAL_API_SECRET', 'Your_REST_API_Secret');
define('PAYPAL_SANDBOX', true); //set false for production
// Database configuration
define('DB_HOST', 'MySQL_Database_Host');
define('DB_USERNAME', 'MySQL_Database_Username');
define('DB_PASSWORD', 'MySQL_Database_Password');
define('DB_NAME', 'MySQL_Database_Name');
In this page, all the products are listed with the Buy button.
getRows()
function of DB class.<?php
// Include and initialize database class
include_once 'DB.class.php';
$db = new DB;
// Get all products from database
$products = $db->getRows('products');
?> <!-- List products --> <?php
if(!empty($products)){
foreach($products as $row){
?> <div class="item"> <img src="images/<?php echo $row['image']; ?>"/> <p>Name: <?php echo $row['name']; ?></p> <p>Price: <?php echo $row['price']; ?></p> <a href="checkout.php?id=<?php echo $row['id']; ?>">BUY</a> </div> <?php
}
}else{
echo '<p>Product(s) not found...</p>';
}
?>
In this page, selected product details are displayed with a checkout button.
getRows()
function of DB class.<?php
// Redirect to the home page if id parameter not found in URL
if(empty($_GET['id'])){
header("Location: index.php");
}
// Include and initialize database class
include_once 'DB.class.php';
$db = new DB;
// Include and initialize paypal class
include_once 'PaypalExpress.class.php';
$paypal = new PaypalExpress;
// Get product ID from URL
$productID = $_GET['id'];
// Get product details
$conditions = array(
'where' => array('id' => $productID),
'return_type' => 'single'
);
$productData = $db->getRows('products', $conditions);
// Redirect to the home page if product not found
if(empty($productData)){
header("Location: index.php");
}
?> <div class="item"> <!-- Product details --> <img src="images/<?php echo $productData['image']; ?>"/> <p>Name: <?php echo $productData['name']; ?></p> <p>Price: <?php echo $productData['price']; ?></p> <!-- Checkout button --> <div id="paypal-button"></div> </div>
PayPal Checkout Button:
The following code needed to add the PayPal express checkout button.
Include the PayPal checkout JS library.
<script src="https://www.paypalobjects.com/api/checkout.js"></script>
Define an HTML element to render the checkout button.
<div id="paypal-button"></div>
Add JavaScript code to enable express checkout.
<!--
JavaScript code to render PayPal checkout button and execute payment
-->
<script>
paypal.Button.render({
// Configure environment
env: '<?php echo $paypal->paypalEnv; ?>',
client: {
sandbox: '<?php echo $paypal->paypalClientID; ?>',
production: '<?php echo $paypal->paypalClientID; ?>'
},
// Customize button (optional)
locale: 'en_US',
style: {
size: 'small',
color: 'gold',
shape: 'pill',
},
// Set up a payment
payment: function (data, actions) {
return actions.payment.create({
transactions: [{
amount: {
total: '<?php echo $productData['price']; ?>',
currency: '<?php echo $productData['currency']; ?>'
}
}]
});
},
// Execute the payment
onAuthorize: function (data, actions) {
return actions.payment.execute()
.then(function () {
// Show a confirmation message to the buyer
//window.alert('Thank you for your purchase!');
// Redirect to the payment process page
window.location = "process.php?paymentID="+data.paymentID+"&token="+data.paymentToken+"&payerID="+data.payerID+"&pid=<?php echo $productData['id']; ?>";
});
}
}, '#paypal-button');
</script>
In this page, the transaction is validated via PayPal API and payment information is stored in the database.
validate()
function of PaypalExpress class.<?php
$redirectStr = '';
if(!empty($_GET['paymentID']) && !empty($_GET['token']) && !empty($_GET['payerID']) && !empty($_GET['pid']) ){
// Include and initialize database class
include_once 'DB.class.php';
$db = new DB;
// Include and initialize paypal class
include_once 'PaypalExpress.class.php';
$paypal = new PaypalExpress;
// Get payment info from URL
$paymentID = $_GET['paymentID'];
$token = $_GET['token'];
$payerID = $_GET['payerID'];
$productID = $_GET['pid'];
// Validate transaction via PayPal API
$paymentCheck = $paypal->validate($paymentID, $token, $payerID, $productID);
// If the payment is valid and approved
if($paymentCheck && $paymentCheck->state == 'approved'){
// Get the transaction data
$id = $paymentCheck->id;
$state = $paymentCheck->state;
$payerFirstName = $paymentCheck->payer->payer_info->first_name;
$payerLastName = $paymentCheck->payer->payer_info->last_name;
$payerName = $payerFirstName.' '.$payerLastName;
$payerEmail = $paymentCheck->payer->payer_info->email;
$payerID = $paymentCheck->payer->payer_info->payer_id;
$payerCountryCode = $paymentCheck->payer->payer_info->country_code;
$paidAmount = $paymentCheck->transactions[0]->amount->details->subtotal;
$currency = $paymentCheck->transactions[0]->amount->currency;
// Get product details
$conditions = array(
'where' => array('id' => $productID),
'return_type' => 'single'
);
$productData = $db->getRows('products', $conditions);
// If payment price is valid
if($productData['price'] >= $paidAmount){
// Insert transaction data in the database
$data = array(
'product_id' => $productID,
'txn_id' => $id,
'payment_gross' => $paidAmount,
'currency_code' => $currency,
'payer_id' => $payerID,
'payer_name' => $payerName,
'payer_email' => $payerEmail,
'payer_country' => $payerCountryCode,
'payment_status' => $state
);
$insert = $db->insert('payments', $data);
// Add insert id to the URL
$redirectStr = '?id='.$insert;
}
}
// Redirect to payment status page
header("Location:payment-status.php".$redirectStr);
}else{
// Redirect to the home page
header("Location:index.php");
}
?>
In this page, the payment data is retrieved from the database based on the ID specified in the URL and the transaction details is shown to the user.
<?php
if(!empty($_GET['id'])){
// Include and initialize database class
include_once 'DB.class.php';
$db = new DB;
// Get payment details
$conditions = array(
'where' => array('id' => $_GET['id']),
'return_type' => 'single'
);
$paymentData = $db->getRows('payments', $conditions);
// Get product details
$conditions = array(
'where' => array('id' => $paymentData['product_id']),
'return_type' => 'single'
);
$productData = $db->getRows('products', $conditions);
}else{
header("Location: index.php");
}
?>
<div class="status">
<?php if(!empty($paymentData)){ ?>
<h1 class="success">Your Payment has been Successful!</h1>
<h4>Payment Information</h4>
<p><b>TXN ID:</b> <?php echo $paymentData['txn_id']; ?></p>
<p><b>Paid Amount:</b> <?php echo $paymentData['payment_gross'].' '.$paymentData['currency_code']; ?></p>
<p><b>Payment Status:</b> <?php echo $paymentData['payment_status']; ?></p>
<p><b>Payment Date:</b> <?php echo $paymentData['created']; ?></p>
<p><b>Payer Name:</b> <?php echo $paymentData['payer_name']; ?></p>
<p><b>Payer Email:</b> <?php echo $paymentData['payer_email']; ?></p>
<h4>Product Information</h4>
<p><b>Name:</b> <?php echo $productData['name']; ?></p>
<p><b>Price:</b> <?php echo $productData['price'].' '.$productData['currency']; ?></p>
<?php }else{ ?>
<h1 class="error">Your Payment has Failed</h1>
<?php } ?>
</div>
PayPal Standard Payment Gateway Integration in PHP
When your test is completed on the Sandbox environment and you’re satisfied with it, you can make the payment gateway live. Follow the below steps to configure PayPal Express Checkout payment gateway live for production.
Get Live REST API credentials:
Go to the PayPal Developer Portal, log in to the Dashboard with your PayPal business account.
Specify Live API Credentials:
In config.php
file, do the following changes.
false
.define('PAYPAL_API_CLIENT_ID', 'REST_API_LIVE_Client_ID');
define('PAYPAL_API_SECRET', 'REST_API_LIVE_Secret');
define('PAYPAL_SANDBOX', false);
PayPal Pro Payment Gateway Integration in PHP
PayPal Express Checkout makes the online payment process simple and user-friendly. The buyer stays on your website throughout the checkout flow and completes the payment process without leaving your website. Using the example code you can easily implement the PayPal express checkout process in your web application.
Do you want to get implementation help, or enhance the functionality of this script? Click here to Submit Service Request
Hello, first of all thanks for the script.
What can I do so that the item name is then on the Paypal invoice?
I would also like to specify shipping fees and then calculate the purchase price from the price and the shipping fees. How can I pass this on to PayPal?
Hi There,
I liked the video and instructions to set this up using V1 setup a test ALL good:
“public $paypalURL = PAYPAL_SANDBOX?’https://api.sandbox.paypal.com/v1/’:’https://api.paypal.com/v1/’; )”
I would like to implement the solution but using the V2, do you have a working sample of how to do that?
This would be very useful.
Thanks in advance
Ramsy
Love this product. Glad I purchased the membership. I have it fully working but would like to send/receive my invoice number to/from PayPal. Do you know how I would be able to add this element?
payment: function (data, actions) {
return actions.payment.create({
transactions: [{
amount: {
total: $(“#amount”).val(),
currency: ‘AUD’
},
description: $(“#email”).val(),
custom: $(“#booking_id”).val()
}]
});
},
Can we send custom values and print in order details of paypal
Thanks Codexworld. I’ve tried it and it is working fine. This is what I wanted for a project I am working on. But how can I change it to send multiple items for checkout?
See this tutorial – https://www.codexworld.com/paypal-standard-add-to-cart-multiple-items-php/
how to implement this for subscription
Hi, this content help me, in my work job, thanks!
Thanks Bro! It was really helpful for me.
I was developing and wp plugin. It was helpful for me.
where is style.css
Download the source code.
Thanks Codexworld,
this article really helpful for me.
How would I add something like a custom transaction fee? The one thing that is confusing me. Thanks