PayPal Standard Payment Gateway Integration in PHP


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 payment system on the website.

paypal-payment-process-php-codexworld

This tutorial will explain how to integrate PayPal standard payment gateway in PHP and store the transaction data using PayPal IPN. Our step-by-step guide on PayPal payment gateway integration in PHP helps you to easily integrate the payment option in your web project.

In our example script, we’ll display some products with buy now option. Once the user clicks on the Buy Now button, they will be redirected to the PayPal where the payment will complete. After payment completion, the user will be redirected back to the website and the transaction details to be shown to the user. Also, the transaction information would be stored in the MySQL database.

PayPal has two environments such as Sandbox and Real Time. PayPal Sandbox allows developers to do their test transaction before the project go live. Real Time environment is used after project live. Once PayPal payment process is working fine on Sandbox environment, you can set PayPal to Real-Time environment.

Creating a PayPal Sandbox Account

Before start accepting payment from buyers via PayPal, payment gateway needs to be tested. To test transaction process you need to create PayPal sandbox account.

  • Go to the PayPal Developer page and log in to your PayPal account. If you don’t have any PayPal account, sign up for a PayPal account first.
  • After logged in you would be redirected to the developer homepage. Now click on the Dashboard link from the top navigation menu.
  • Click on the Accounts link under the Sandbox label from the left menu panel.
  • Create buyer account and 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.

You may follow the detailed guide on creating a PayPal Sandbox account from the below link.

Database Tables Creation

To store products details and payment transaction information two tables need to be created in MySQL database. The products data is stored into the products table and payments table is used for storing the transaction information provided by PayPal.

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,
 `status` tinyint(1) NOT NULL DEFAULT '1',
 PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;

CREATE TABLE `payments` ( `payment_id` int(11) NOT NULL AUTO_INCREMENT, `item_number` varchar(255) COLLATE utf8_unicode_ci NOT NULL, `txn_id` varchar(255) 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(255) COLLATE utf8_unicode_ci NOT NULL, PRIMARY KEY (`payment_id`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;

Database Configuration (dbConfig.php)

This file is used to connect and select database using PHP and MySQL. Change $dbHost, $dbUsername, $dbPassword, and $dbName variable’s value with your database credentials.

<?php
//Database credentials
$dbHost 'localhost';
$dbUsername 'root';
$dbPassword '';
$dbName 'codexworld';

//Connect with the database
$db = new mysqli($dbHost$dbUsername$dbPassword$dbName);

//Display error if failed to connect
if ($db->connect_errno) {
    
printf("Connect failed: %s\n"$db->connect_error);
    exit();
}
?>

Products (products.php)

All the products will be fetched from the products table and listed with PayPal Buy Now button. To use PayPal standard payment gateway, you need to submit a form with some predefined PayPal HTML form field variable. Follow the comment tags (<!– –>) to know about the form hidden fields.

<?php
//Include DB configuration file
include 'dbConfig.php';

//Set useful variables for paypal form
$paypalURL 'https://www.sandbox.paypal.com/cgi-bin/webscr'//Test PayPal API URL
$paypalID 'Insert_PayPal_Email'//Business Email

?>
<?php
    
//Fetch products from the database
    
$results $db->query("SELECT * FROM products");
    while(
$row $results->fetch_assoc()){
?> <img src="images/<?php echo $row['image']; ?>"/> Name: <?php echo $row['name']; ?> Price: <?php echo $row['price']; ?> <form action="<?php echo $paypalURL?>" method="post"> <!-- Identify your business so that you can collect the payments. --> <input type="hidden" name="business" value="<?php echo $paypalID?>"> <!-- 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="USD"> <!-- Specify URLs --> <input type='hidden' name='cancel_return' value='http://localhost/paypal_integration_php/cancel.php'> <input type='hidden' name='return' value='http://localhost/paypal_integration_php/success.php'> <!-- Display the payment button. --> <input type="image" name="submit" border="0" src="https://www.paypalobjects.com/en_US/i/btn/btn_buynow_LG.gif" alt="PayPal - The safer, easier way to pay online"> <img alt="" border="0" width="1" height="1" src="https://www.paypalobjects.com/en_US/i/scr/pixel.gif" > </form> <?php ?>

Payment Success (success.php)

Once the PayPal payment is successful, the buyer is redirected to this page. The transaction information is received using $_GET method and inserts payment data into the database.

<?php
include 'dbConfig.php';

//Get payment information from PayPal
$item_number $_GET['item_number']; 
$txn_id $_GET['tx'];
$payment_gross $_GET['amt'];
$currency_code $_GET['cc'];
$payment_status $_GET['st'];

//Get product price from database
$productResult $db->query("SELECT price FROM products WHERE id = ".$item_number);
$productRow $productResult->fetch_assoc();
$productPrice $productRow['price'];

if(!empty(
$txn_id) && $payment_gross == $productPrice){
    
//Check if payment data exists with the same TXN ID.
    
$prevPaymentResult $db->query("SELECT payment_id FROM payments WHERE txn_id = '".$txn_id."'");

    if(
$prevPaymentResult->num_rows 0){
        
$paymentRow $prevPaymentResult->fetch_assoc();
        
$last_insert_id $paymentRow['payment_id'];
    }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."')");
        
$last_insert_id $db->insert_id;
    }
?> <h1>Your payment has been successful.</h1> <h1>Your Payment ID - <?php echo $last_insert_id?></h1> <?php }else{ ?> <h1>Your payment has failed.</h1> <?php ?>

Payment Cancel (cancel.php)

If the buyer wishes to cancel payment at the PayPal payment page, the buyer is redirected to this page.

<h1>Your PayPal transaction has been canceled.</h1>

Configure PayPal Auto Return and Payment Data Transfer

Make sure you had configured Auto Return for Website Payments on your PayPal business account. Otherwise, you’ll not get the transaction information from PayPal in success.php file. Read the following guide to enable Auto Return, Payment Data Transfer and set Return URL on your PayPal account.

Setup PayPal Instant Payment Notification (IPN)

To make the PayPal Standard Payment more secure, Instant Payment Notification (IPN) should be used to validate the transaction. Follow the below steps to setup IPN in PayPal payment gateway integration.

Enable IPN
To Use this feature, IPN must be enabled in PayPal account. We’ve already published a step-by-step guide to enable IPN in PayPal, please go to the below link.

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='http://www.codexworld.com/ipn.php'>

Validate Transaction
Once IPN is enabled PayPal will send the transaction data to the Notify URL (http://www.codexworld.com/ipn.php). Place the following code in ipn.php file to validate and insert payment information into the database.

<?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 "https://www.sandbox.paypal.com/cgi-bin/webscr";
$ch curl_init($paypalURL);
if (
$ch == FALSE) {
    return 
FALSE;
}
curl_setopt($chCURLOPT_HTTP_VERSIONCURL_HTTP_VERSION_1_1);
curl_setopt($chCURLOPT_POST1);
curl_setopt($chCURLOPT_RETURNTRANSFER,1);
curl_setopt($chCURLOPT_POSTFIELDS$req);
curl_setopt($chCURLOPT_SSLVERSION6);
curl_setopt($chCURLOPT_SSL_VERIFYPEER1);
curl_setopt($chCURLOPT_SSL_VERIFYHOST2);
curl_setopt($chCURLOPT_FORBID_REUSE1);

// Set TCP timeout to 30 seconds
curl_setopt($chCURLOPT_CONNECTTIMEOUT30);
curl_setopt($chCURLOPT_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") == || strcasecmp($res"VERIFIED") == 0) {
    
    
//Payment data
    
$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 payment data exists with the same TXN ID.
    
$prevPayment $db->query("SELECT payment_id FROM payments WHERE txn_id = '".$txn_id."'");
    if(
$prevPaymentResult->num_rows 0){
        exit();
    }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."')");
    }

}

Note that: Once PayPal IPN setup is completed, database insertion code is not required in success.php file.

Make PayPal Payment Gateway Live

When your application payment flow testing is completed, you need to modify two files to make PayPal payment gateway live.

Open the products.php file, change the $paypalURL and $paypalID value with live PayPal URL and business email.

$paypalURL 'https://www.paypal.com/cgi-bin/webscr';
$paypalID 'InsertPayPalBusinessEmail';

Open the ipn.php file, change the $paypalURL value with live PayPal URL.

$paypalURL "https://www.paypal.com/cgi-bin/webscr";

55 Comments

  1. Shail Said...
    • CodexWorld Said...
  2. Timothy Martin Said...
  3. Camille Said...
    • CodexWorld Said...
  4. Thomas Said...
    • CodexWorld Said...
  5. Shamali Said...
  6. Ram Said...
    • CodexWorld Said...
  7. Apeksha Said...
  8. Nelson Said...
    • CodexWorld Said...
  9. Mandeep Said...
  10. Arun Said...
  11. Abhinav Said...
    • CodexWorld Said...

Leave a reply

Connect With CodexWorld