PayPal is an American international e-commerce business allowing payments and money transfers to be made through the Internet. PayPal is the most popular payment gateway to send and receive payment worldwide. PayPal is a widely used payment gateway to accept payment in the web application. PayPal payment gateway is the easiest option for the web developer to implement a payment system on the website.
PayPal Standard Payment Gateway is the quickest way to accept payment online. The buyer can make the payment from the website to purchase an item online. In this tutorial, we will show you how to integrate PayPal standard payment gateway in PHP and store the transaction data in the database using PayPal IPN. Our step-by-step guide on PayPal payment gateway integration in PHP helps you to easily integrate the online payment feature in your web project.
We will implement the following functionality to demonstrate the PayPal Payment Gateway integration process.
1. Fetch the products from the database and listed on the web page with the PayPal Buy button.
2. The Buy button redirects the buyer to the PayPal site to complete the payment.
3. After the payment, the buyer will redirect back to the website and the payment details will be shown.
4. The transaction data is stored in the database through the PayPal IPN.
Also Read:- PayPal Standard Payment Gateway Integration in PHP
PayPal has two environments such as Sandbox and Real Time. PayPal Sandbox allows developers to do their test transaction before the project go live. The real-time environment is used after the project is live on the production server. Once the PayPal payment process is working properly on the Sandbox environment, you can set the PayPal payment gateway for Real-Time environment.
Also Read:- How to Implement Real Time Notification Using Socket.io and Node.JS?
Create PayPal Sandbox Account
Before start accepting payment from buyers via PayPal, the payment gateway needs to be tested. To test the transaction process you need to create a PayPal sandbox account.
1. Go to the PayPal Developer page and log in to your PayPal account. If you don’t have any PayPal account, register for a PayPal account first.
2. After logging in you would be redirected to the developer homepage. Now click on the Dashboard link from the top navigation menu.
3. Click on the Accounts link under the Sandbox label from the left menu panel.
4. Create a buyer account and a merchant account from the Create Account link. For buyer account, you need to select Personal radio button under the Account type section or select Business radio button for a merchant account.
Also Read:- How to Integrate Payumoney Payment Gateway in Laravel 5
Create Database Tables
To store product and payment information two tables needs to be created in the database.
The following SQL creates a products
table in the MySQL database to store the product data.
CREATE TABLE `products` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`name` varchar(200) COLLATE utf8_unicode_ci NOT NULL,
`image` varchar(255) COLLATE utf8_unicode_ci NOT NULL,
`price` float(10,2) NOT NULL,
`status` tinyint(1) NOT NULL DEFAULT '1' COMMENT '1=Active | 0=Inactive',
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;
The following SQL creates a payments
table in the MySQL database to store the transaction data provided by PayPal.
CREATE TABLE `payments` (
`payment_id` int(11) NOT NULL AUTO_INCREMENT,
`item_number` varchar(50) COLLATE utf8_unicode_ci NOT NULL,
`txn_id` varchar(50) COLLATE utf8_unicode_ci NOT NULL,
`payment_gross` float(10,2) NOT NULL,
`currency_code` varchar(5) COLLATE utf8_unicode_ci NOT NULL,
`payment_status` varchar(20) COLLATE utf8_unicode_ci NOT NULL,
PRIMARY KEY (`payment_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;
Also Read:- How to Build a Real-time Chat App With NodeJS, Socket.IO, and MongoDB
PayPal Settings and Database Configuration (config.php)
In the config.php
file, constant variables of the PayPal and database settings are defined.
PayPal Constants:
1. PAYPAL_ID – Specify the email of the PayPal Business account.
2. PAYPAL_SANDBOX – Specify whether you use Sandbox environment (TRUE/FALSE).
3. PAYPAL_RETURN_URL – Specify the URL where the buyer will be redirected after payment.
4. PAYPAL_CANCEL_URL – Specify the URL where the buyer will be redirected after payment cancellation.
5. PAYPAL_NOTIFY_URL – Specify the URL where the transaction data will be sent for verification through PayPal IPN.
6. PAYPAL_CURRENCY – Specify the currency code.
Also Read:- How This Ex-Paypal CFO’s Payments Startup Is Helping SMEs Leverage Social Media To Grow Faster
Database Constants:
1. DB_HOST – Specify the database host.
2. DB_USERNAME – Specify the database username.
3. DB_PASSWORD – Specify the database password.
4. DB_NAME – Specify the database name.
<?php
/*
* PayPal and database configuration
*/
// PayPal configuration
define('PAYPAL_ID', 'Insert_PayPal_Business_Email');
define('PAYPAL_SANDBOX', TRUE); //TRUE or FALSE
define('PAYPAL_RETURN_URL', 'http://www.example.com/success.php');
define('PAYPAL_CANCEL_URL', 'http://www.example.com/cancel.php');
define('PAYPAL_NOTIFY_URL', 'http://www.example.com/ipn.php');
define('PAYPAL_CURRENCY', 'USD');
// 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');
// Change not required
define('PAYPAL_URL', (PAYPAL_SANDBOX == true)?"https://www.sandbox.paypal.com/cgi-bin/webscr":"https://www.paypal.com/cgi-bin/webscr");
Database Connection (dbConnect.php)
The dbConnect.php
file is used to connect the database using PHP and MySQL.
Also Read:- Get a head start with trending Nodejs developer capabilities
<?php
// Connect with the database
$db = new mysqli(DB_HOST, DB_USERNAME, DB_PASSWORD, DB_NAME);
// Display error if failed to connect
if ($db->connect_errno) {
printf("Connect failed: %s\n", $db->connect_error);
exit();
}
Products (index.php)
Initially, all the products are fetched from the database and listed on the webpage.
1. A PayPal Buy Now button is placed with each product.
2. To use PayPal standard payment gateway, you need to submit a form with some predefined PayPal HTML form field variable.
3. Follow the comment tags (<!– –>) to know about the form hidden fields.
Also Read:- Create a Simple CRUD Database App - Connecting to MySQL with PHP
<?php
// Include configuration file
include_once 'config.php';
// Include database connection file
include_once 'dbConnect.php';
?>
<div class="container">
<?php
// Fetch products from the database
$results = $db->query("SELECT * FROM products WHERE status = 1");
while($row = $results->fetch_assoc()){
?>
<div class="pro-box">
<img src="images/<?php echo $row['image']; ?>"/>
<div class="body">
<h5><?php echo $row['name']; ?></h5>
<h6>Price: <?php echo '$'.$row['price'].' '.PAYPAL_CURRENCY; ?></h6>
<!-- PayPal payment form for displaying the buy button -->
<form action="<?php echo PAYPAL_URL; ?>" method="post">
<!-- Identify your business so that you can collect the payments. -->
<input type="hidden" name="business" value="<?php echo PAYPAL_ID; ?>">
<!-- Specify a Buy Now button. -->
<input type="hidden" name="cmd" value="_xclick">
<!-- Specify details about the item that buyers will purchase. -->
<input type="hidden" name="item_name" value="<?php echo $row['name']; ?>">
<input type="hidden" name="item_number" value="<?php echo $row['id']; ?>">
<input type="hidden" name="amount" value="<?php echo $row['price']; ?>">
<input type="hidden" name="currency_code" value="<?php echo PAYPAL_CURRENCY; ?>">
<!-- Specify URLs -->
<input type="hidden" name="return" value="<?php echo PAYPAL_RETURN_URL; ?>">
<input type="hidden" name="cancel_return" value="<?php echo PAYPAL_CANCEL_URL; ?>">
<!-- Display the payment button. -->
<input type="image" name="submit" border="0" src="https://www.paypalobjects.com/en_US/i/btn/btn_buynow_LG.gif">
</form>
</div>
</div>
<?php } ?>
</div>
Payment Success (success.php)
After successful payment on PayPal, the buyer is redirected to this page.
1. The transaction data is retrieved from the URL using PHP $_GET method.
2. Insert/Update payment information in the database based on the transaction ID.
3. The payment details are displayed on the webpage.
Also Read:- What differentiates Robotics from artificial intelligence?
<?php
// Include configuration file
include_once 'config.php';
// Include database connection file
include_once 'dbConnect.php';
// If transaction data is available in the URL
if(!empty($_GET['item_number']) && !empty($_GET['tx']) && !empty($_GET['amt']) && !empty($_GET['cc']) && !empty($_GET['st'])){
// Get transaction information from URL
$item_number = $_GET['item_number'];
$txn_id = $_GET['tx'];
$payment_gross = $_GET['amt'];
$currency_code = $_GET['cc'];
$payment_status = $_GET['st'];
// Get product info from the database
$productResult = $db->query("SELECT * FROM products WHERE id = ".$item_number);
$productRow = $productResult->fetch_assoc();
// Check if transaction data exists with the same TXN ID.
$prevPaymentResult = $db->query("SELECT * FROM payments WHERE txn_id = '".$txn_id."'");
if($prevPaymentResult->num_rows > 0){
$paymentRow = $prevPaymentResult->fetch_assoc();
$payment_id = $paymentRow['payment_id'];
$payment_gross = $paymentRow['payment_gross'];
$payment_status = $paymentRow['payment_status'];
}else{
// Insert tansaction data into the database
$insert = $db->query("INSERT INTO payments(item_number,txn_id,payment_gross,currency_code,payment_status) VALUES('".$item_number."','".$txn_id."','".$payment_gross."','".$currency_code."','".$payment_status."')");
$payment_id = $db->insert_id;
}
}
?>
<div class="container">
<div class="status">
<?php if(!empty($payment_id)){ ?>
<h1 class="success">Your Payment has been Successful</h1>
<h4>Payment Information</h4>
<p><b>Reference Number:</b> <?php echo $payment_id; ?></p>
<p><b>Transaction ID:</b> <?php echo $txn_id; ?></p>
<p><b>Paid Amount:</b> <?php echo $payment_gross; ?></p>
<p><b>Payment Status:</b> <?php echo $payment_status; ?></p>
<h4>Product Information</h4>
<p><b>Name:</b> <?php echo $productRow['name']; ?></p>
<p><b>Price:</b> <?php echo $productRow['price']; ?></p>
<?php }else{ ?>
<h1 class="error">Your Payment has Failed</h1>
<?php } ?>
</div>
<a href="index.php" class="btn-link">Back to Products</a>
</div>
Payment Cancellation (cancel.php)
If the buyer wishes to cancel payment at the PayPal payment page, the buyer is redirected to this page.
Also Read:- Frontier Airlines Cancellation Policy: You need to know
<div class="container">
<div class="status">
<h1 class="error">Your PayPal Transaction has been Canceled</h1>
</div>
<a href="index.php" class="btn-link">Back to Products</a>
</div>
Configure PayPal Auto Return and Payment Data Transfer
Make sure you have configured Auto Return for Website Payments on your PayPal business account. Otherwise, you’ll not get the transaction information from PayPal in the success.php
file. See the following guide to enable Auto Return, Payment Data Transfer and set Return URL on your PayPal account.
Also Read:- What is difference between Node.JS and Express.JS?
Setup PayPal Instant Payment Notification (IPN)
To make the PayPal Standard Payment secure, validate the transaction with PayPal Instant Payment Notification (IPN). Follow the below steps to setup IPN in PayPal standard payment gateway integration.
Enable IPN:
To use this feature, IPN must be enabled in the PayPal account. We’ve already published a step-by-step guide to enable IPN in PayPal, please see the below tutorial.
Add Notify URL in PayPal Form:
Add the following input field (notify_url
) HTML along with the other PayPal HTML Variables.
<input type="hidden" name="notify_url" value="<?php echo PAYPAL_NOTIFY_URL; ?>">
Also Read:- How to convert HTML to MS Word Document using PHP
Validate Transaction:
Once IPN is enabled, PayPal will send the transaction data to the Notify URL (http://www.example.com/ipn.php
). Place the following code in the ipn.php
file to validate the transaction and insert payment information into the database.
<?php
// Include configuration file
include_once 'config.php';
// Include database connection file
include_once 'dbConnect.php';
/*
* Read POST data
* reading posted data directly from $_POST causes serialization
* issues with array data in POST.
* Reading raw POST data from input stream instead.
*/
$raw_post_data = file_get_contents('php://input');
$raw_post_array = explode('&', $raw_post_data);
$myPost = array();
foreach ($raw_post_array as $keyval) {
$keyval = explode ('=', $keyval);
if (count($keyval) == 2)
$myPost[$keyval[0]] = urldecode($keyval[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 ($myPost 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";
}
/*
* Post IPN data back to PayPal to validate the IPN data is genuine
* Without this step anyone can fake IPN data
*/
$paypalURL = PAYPAL_URL;
$ch = curl_init($paypalURL);
if ($ch == FALSE) {
return FALSE;
}
curl_setopt($ch, CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_1_1);
curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_RETURNTRANSFER,1);
curl_setopt($ch, CURLOPT_POSTFIELDS, $req);
curl_setopt($ch, CURLOPT_SSLVERSION, 6);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, 1);
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, 2);
curl_setopt($ch, CURLOPT_FORBID_REUSE, 1);
// Set TCP timeout to 30 seconds
curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 30);
curl_setopt($ch, CURLOPT_HTTPHEADER, array('Connection: Close', 'User-Agent: company-name'));
$res = curl_exec($ch);
/*
* Inspect IPN validation result and act accordingly
* Split response headers and payload, a better way for strcmp
*/
$tokens = explode("\r\n\r\n", trim($res));
$res = trim(end($tokens));
if (strcmp($res, "VERIFIED") == 0 || strcasecmp($res, "VERIFIED") == 0) {
// Retrieve transaction info from PayPal
$item_number = $_POST['item_number'];
$txn_id = $_POST['txn_id'];
$payment_gross = $_POST['mc_gross'];
$currency_code = $_POST['mc_currency'];
$payment_status = $_POST['payment_status'];
// Check if transaction data exists with the same TXN ID
$prevPayment = $db->query("SELECT payment_id FROM payments WHERE txn_id = '".$txn_id."'");
if($prevPayment->num_rows > 0){
exit();
}else{
// Insert transaction data into the database
$insert = $db->query("INSERT INTO payments(item_number,txn_id,payment_gross,currency_code,payment_status) VALUES('".$item_number."','".$txn_id."','".$payment_gross."','".$currency_code."','".$payment_status."')");
}
}
?>
Note that: Once the PayPal IPN setup is completed, the database insertion code is not required in the success.php
file.
Also Read:- Which Programming Languages Should You Learn in 2019?
Make PayPal Payment Gateway Live
When the application payment flow testing is completed, you should make the PayPal payment gateway live.
In the config.php file,
1. Specify the email of the PayPal business account in PAYPAL_ID
.
2. Set PAYPAL_SANDBOX
to FALSE.
define('PAYPAL_ID', 'Insert_PayPal_Business_Email');
define('PAYPAL_SANDBOX', FALSE);
Conclusion
PayPal standard payment gateway is the easiest way to accept payment on the web application. With our example script, you can easily integrate the PayPal payment API on the website. To make the payment process user-friendly, you can integrate PayPal Express Checkout for the online payment.