PayPal Payment Integration in PHP
In this tutorial, I will explain how to do PayPal Payment Integration in PHP. As of now, it is the most popular online American payment system which makes it easy to send and receive money over the internet.
The PayPal provides various ways to send and receive money online, you can directly send money to your friend or family member and you can also make payment to several services on the internet by using PayPal.
It is also most popular online payment gateway, use to accept payments through web and mobile applications.
There are some other popular online payment gateways, if you want to offer multiple payment options to your customer then you can also allow them to make payment using Authorize.Net.
I have shared a separate and detailed tutorial about Authorize.Net payment gateway integration using PHP.
Stripe is also popular payment gateway, learn how to integrate stripe payment gateway using PHP.
PayPal offers several ways to Integrate PayPal Payment Gateway to your website, some of them are listed below:
- PayPal Payments Standard
- Checkout
- Subscriptions & Recurring Payments
- PayPal Invoicing
- Payouts
I will focus on PayPal Payments Standard, as it is the most easiest way to integrate PayPal payment using PHP. So lets start integration of PayPal payment standards in PHP.
I will use my previous tutorial PHP CRUD Operations to access database and perform all database related operations using class dbclass.php.
I will skip rewriting of the same class to avoid duplication of code. However, I will include the same class in download file, so you do not need to worry about the dbclass.php class.
Steps to Integration PayPal Payment Gateway using PHP
I will follow the below steps to integrate PayPal payment gateway on my website using PHP.
- Create a Database, Tables and Dump Sample Data
- Create a config.php File & Make Necessary Changes
- Create an index.php File & Display Some Products to Buy
- Create a notify.php File, Handle IPN & Insert Payment Record in DB
- Create a cancel.php File
- Create a return.php File
- Create a style.css File
1. Create a Database, Tables and Dump Sample Data
To create database run the following query in MySQL.
CREATE DATABASE allphptricks;
To create the tables run the following queries.
CREATE TABLE `products` (
`id` int(10) NOT NULL AUTO_INCREMENT,
`name` varchar(250) NOT NULL,
`code` varchar(100) NOT NULL,
`price` double(9,2) NOT NULL,
`image` varchar(250) NOT NULL,
PRIMARY KEY (`id`),
UNIQUE KEY `code` (`code`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1;
Note: I have already attached the SQL file of this table with dummy data, just download the complete zip file of this tutorial.
CREATE TABLE `payment_info` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`item_number` varchar(255) NOT NULL,
`item_name` varchar(255) NOT NULL,
`payment_status` varchar(255) NOT NULL,
`amount` double(10,2) NOT NULL,
`currency` varchar(255) NOT NULL,
`txn_id` varchar(255) NOT NULL,
`create_at` timestamp NOT NULL DEFAULT current_timestamp(),
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1;
Dump sample data into `products` table.
INSERT INTO `products` (`id`, `name`, `code`, `price`, `image`) VALUES
(1, 'Laptop Core i5', 'Laptop01', 100.00, 'product-images/laptop.jpg'),
(2, 'Laptop Bag', 'Bag01', 10.00, 'product-images/laptop-bag.jpg'),
(3, 'iPhone X', 'iphone01', 50.00, 'product-images/iphone.jpg');
2. Create a config.php File & Make Necessary Changes
Create a config.php file, copy paste the following code and make necessary changes like update your database credentials, database name, username, password, also update your PayPal business email, return, cancel, notify URLs etc.
<?php
// Database Configuration
define('DB_HOST', 'localhost');
define('DB_NAME', 'Your Database Name');
define('DB_USERNAME', 'Your Database Username');
define('DB_PASSWORD', 'Your Database Password');
// PayPal Configuration
define('PAYPAL_EMAIL', 'Your PayPal Business Email');
define('RETURN_URL', 'https://www.your-website.com/return.php');
define('CANCEL_URL', 'https://www.your-website.com/cancel.php');
define('NOTIFY_URL', 'https://www.your-website.com/notify.php');
define('CURRENCY', 'USD');
define('SANDBOX', TRUE); // TRUE or FALSE
define('LOCAL_CERTIFICATE', FALSE); // TRUE or FALSE
if (SANDBOX === TRUE){
$paypal_url = "https://www.sandbox.paypal.com/cgi-bin/webscr";
}else{
$paypal_url = "https://www.paypal.com/cgi-bin/webscr";
}
// PayPal IPN Data Validate URL
define('PAYPAL_URL', $paypal_url);
3. Create an index.php File & Display Some Products to Buy
Create an index.php file, copy paste the following code in it. This page will display all products from `products` table, so that user can easily buy any product.
<?php
require_once('dbclass.php');
$db = new DB;
$db->query("SELECT * FROM `products`");
$products = $db->resultSet();
$db->close();
?>
<html>
<head>
<title>PayPal Payment Integration in PHP</title>
<link rel='stylesheet' href='css/style.css' type='text/css' media='all' />
</head>
<body>
<div style="width:700px; margin:50 auto;">
<h2>PayPal Payment Integration in PHP</h2>
<?php
if( !empty($products) )
{
foreach($products as $product)
{
?>
<div class='product_wrapper'>
<div class='image'><img src='<?php echo $product['image']; ?>' />
</div>
<div class='name'><?php echo $product['name']; ?></div>
<div class='price'>$<?php echo $product['price']; ?></div>
<form method='post' action='<?php echo PAYPAL_URL; ?>'>
<!-- PayPal business email to collect payments -->
<input type='hidden' name='business'
value='<?php echo PAYPAL_EMAIL; ?>'>
<!-- Details of item that customers will purchase -->
<input type='hidden' name='item_number'
value='<?php echo $product['code']; ?>'>
<input type='hidden' name='item_name'
value='<?php echo $product['name']; ?>'>
<input type='hidden' name='amount'
value='<?php echo $product['price']; ?>'>
<input type='hidden' name='currency_code'
value='<?php echo CURRENCY; ?>'>
<input type='hidden' name='no_shipping' value='1'>
<!-- PayPal return, cancel & IPN URLs -->
<input type='hidden' name='return'
value='<?php echo RETURN_URL; ?>'>
<input type='hidden' name='cancel_return'
value='<?php echo CANCEL_URL; ?>'>
<input type='hidden' name='notify_url'
value='<?php echo NOTIFY_URL; ?>'>
<!-- Specify a Pay Now button. -->
<input type="hidden" name="cmd" value="_xclick">
<button type='submit' class='pay'>Pay Now</button>
</form>
</div>
<?php
}
}
?>
</div>
</body>
</html>
The above code will generate the following output.
4. Create a notify.php File, Handle IPN & Insert Payment Record in DB
Create a notify.php file, copy paste the following code in it. This page will handle all PayPal Instant Payment Notification (IPN), validate the data and add record into `
` table.payment_info
<?php
require_once('dbclass.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.
*/
define("IPN_LOG_FILE", "ipn.log");
$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]);
}
// Build the body of the verification post request,
// adding the _notify-validate command.
$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 using curl to
validate the IPN data is valid & genuine
Anyone can fake IPN data, if you skip it.
*/
$ch = curl_init(PAYPAL_URL);
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);
/*
This is often required if the server is missing a global cert
bundle, or is using an outdated one.
Please download the latest 'cacert.pem' from
http://curl.haxx.se/docs/caextract.html
*/
if (LOCAL_CERTIFICATE == TRUE) {
curl_setopt($ch, CURLOPT_CAINFO, __DIR__ . "/cert/cacert.pem");
}
// Set TCP timeout to 30 seconds
curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 30);
curl_setopt($ch, CURLOPT_HTTPHEADER, array(
'Connection: Close',
'User-Agent: PHP-IPN-Verification-Script'
));
$res = curl_exec($ch);
// cURL error
if (curl_errno($ch) != 0){
curl_close($ch);
exit;
} else {
curl_close($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) {
// assign posted variables to local variables
$item_number = $_POST['item_number'];
$item_name = $_POST['item_name'];
$payment_status = $_POST['payment_status'];
$amount = $_POST['mc_gross'];
$currency = $_POST['mc_currency'];
$txn_id = $_POST['txn_id'];
$receiver_email = $_POST['receiver_email'];
// $payer_email = $_POST['payer_email'];
// check that receiver_email is your PayPal business email
if (strtolower($receiver_email) != strtolower(PAYPAL_EMAIL)) {
error_log(date('[Y-m-d H:i e] ').
"Invalid Business Email: $req" . PHP_EOL, 3, IPN_LOG_FILE);
exit();
}
// check that payment currency is correct
if (strtolower($currency) != strtolower(CURRENCY)) {
error_log(date('[Y-m-d H:i e] ').
"Invalid Currency: $req" . PHP_EOL, 3, IPN_LOG_FILE);
exit();
}
//Check Unique Transcation ID
$db = new DB;
$db->query("SELECT * FROM `payment_info` WHERE txn_id=:txn_id");
$db->bind(':txn_id', $txn_id);
$db->execute();
$unique_txn_id = $db->rowCount();
if(!empty($unique_txn_id)) {
error_log(date('[Y-m-d H:i e] ').
"Invalid Transaction ID: $req" . PHP_EOL, 3, IPN_LOG_FILE);
$db->close();
exit();
}else{
$db->query("INSERT INTO `payment_info`
(`item_number`, `item_name`, `payment_status`,
`amount`, `currency`, `txn_id`)
VALUES
(:item_number, :item_name, :payment_status,
:amount, :currency, :txn_id)");
$db->bind(":item_number", $item_number);
$db->bind(":item_name", $item_name);
$db->bind(":payment_status", $payment_status);
$db->bind(":amount", $amount);
$db->bind(":currency", $currency);
$db->bind(":txn_id", $txn_id);
$db->execute();
/* error_log(date('[Y-m-d H:i e] ').
"Verified IPN: $req ". PHP_EOL, 3, IPN_LOG_FILE);
*/
}
$db->close();
} else if (strcmp($res, "INVALID") == 0) {
//Log invalid IPN messages for investigation
error_log(date('[Y-m-d H:i e] ').
"Invalid IPN: $req" . PHP_EOL, 3, IPN_LOG_FILE);
}
?>
5. Create a cancel.php File
Create a cancel.php file, copy paste the following code in it. Customer will be redirected here if he/she cancels payment from PayPal payment page.
<h1>Sorry! Your PayPal Payment has been cancelled.</h1>
6. Create a return.php File
Create a return.php file, copy paste the following code in it. Customer will be redirected here when the payment is successful.
<html>
<head>
<title>Payment Confirmed</title>
</head>
<body>
<div style="width:700px; margin:50 auto;">
<h1>Your paymeny has been received successfully.<br /> Thank you!</h1>
</div>
</body>
</html>
7. Create a style.css File
Create a style.css file, copy paste the following code in it. This is the stylesheet of your index page where all products are displayed nicely.
body {
font-family: Arial, sans-serif;
line-height: 1.6;
}
.product_wrapper {
float:left;
padding: 10px;
text-align: center;
}
.product_wrapper:hover {
box-shadow: 0 0 0 2px #e5e5e5;
cursor:pointer;
}
.product_wrapper .name {
font-weight:bold;
}
.product_wrapper .pay {
text-transform: uppercase;
background: #F68B1E;
border: 1px solid #F68B1E;
cursor: pointer;
color: #fff;
padding: 8px 40px;
margin-top: 10px;
}
.product_wrapper .pay:hover {
background: #f17e0a;
border-color: #f17e0a;
}
Conclusion
By following the above step by step guide, anyone can easily integrate PayPal payment gateway in PHP. PayPal Payments Standard is the easiest payment integration which can enable online payment on your website within a day or in a few hours.
I try to keep my code easy and simple as possible, but if anyone of you still having any trouble so feel free to comment below, I try my best to reply all comments and questions of my blog readers.
If you found this tutorial helpful, share it with your friends and developers group.
I spent several hours to create this tutorial, if you want to say thanks so like my page on Facebook, Twitter and share it.
Facebook Official Page: All PHP Tricks
Twitter Official Page: All PHP Tricks
Hello,
Thank you for your tutorial!
I have a question. In your example, the customer can only pay with Paypal. If I want a customer can pay with Paypal but with a credit card, how do that ? Does your code can be used and it’s only a parameter in Paypal interface? Or does your code cannot do that ?
Thank you for your answer !
Dear Sylvain,
Sorry for the delay in response, PayPal provides various methods to make payment. However, in this tutorial I just showed how you can make payment using your PayPal account.
To make payment via credit card, you will need to follow the PayPal integration guide.
This is a great blog post! I’m currently working on a project that will require me to integrate PayPal into my website. This post has given me a lot of helpful information.
You are welcome 🙂
I always have the following error when trying to buy something : Things don’t appear to be working at the moment. Please try again later.
Any idea ?
Make sure that you are passing all the required values.
This is a great blog post! I’m currently working on a project that will require me to integrate PayPal into my website. This post has given me a lot of helpful information.
I am glad that you found my blog helpful.
I am getting this error…
Unfortunately, a system error has occurred. Try again later.
Kindly help me
my phone number 03********
Make sure that you are passing the required data, you can check each field data by printing it on the screen.
Hi!
Thanks for sharing great tutorial. I have followed proper documentation but getting error called BAD_INPUT_ERROR, I have checked all values getting passed properly, not sure what’s wrong with it.
Thanks!
Dear Raju,
I would suggest that you download and try to test the same without making any changes in the flow, except just change your credentials.
Also make sure that certificate is also present in the relevant directory.
I have the same problem, the database connection works fine, when I click PAY NOW I see the error BAD_INPUT_ERROR. I don’t know where to enter my Paylpal account details
Javed, I would appreciate your help.
Hi Javed,
Harihar this side I couldn’t find the sql file can you provide me the sql file
Hi Harihar,
MySQL Code for table creation and dummy data both are available on my tutorial article and download. In the download, it is available in the sql folder.
Hi
congrats for the tutorial 🙂
unfortunatly, my url “notify.php” is not pinged by Paypal
Do you have any clue?
Thanks 🙂
Change notify.php to ipn.php, hope this will solve your issue.
HI , why i got error “”Sorry, we can’t complete your purchase at this time”” when try sandbox?
Thanks dear
I am glad that you find it helpful.
In this demo returning rul is not working, it’s not returning to success page, could you please help?
Sanjay, if it is not redirecting in your case, so which page are you currently on and can you var_dump() or print_r() your data and check the issue. It will be helpful if you can share your error as well.
value not saves in database?
Try to print them out on the screen.
Hello Javed!
Everything is working for me, but i have one question.
In notify.php we are trying to receive variables using $_POST[”].
My only question is , where are we retrieving these variables from? For example,
$_POST[‘mc_gross’] is giving null. In index.php there isn’t value=’mc_gross’.
Thank you for your help.
Hello Javed! This is a very beneficial tutorial !
I have a couple of questions:
1-it’s giving url not found error on return (return.php)
2-I want to insert the the amount paid into an already existing database other than product-info
Thankyou in advance!
Dear Haitham,
You need to make sure that you placed the return.php in the directly, and it does not matter which table you want to updated, you can update any table, I just give an example that you can update table. So I think, you need to make sure that you are able to connect to database.
I realized that the 3 URLs are not working (cancel,return,notify).That’s why the IPN is not working. Can I have some help in calling these files correctly? I’m sorry for the inconvenience.
Dear Haitham,
I would suggest you to kindly first try to run the application on your localhost, if you are able to run it on localhost, then you can move to the live environment.
You can also check that if these three links are working on localhost or not.
May be on your domain, you will need to give the absolute path of URLs.
I took by your advice! Return and cancel are working perfectly, however the ipn is not. Is there a way to receive the value paid ($amount) upon user click and be sent to another php page for processing? This is the last obstacle in my work.
Ok, I found the error causing INVALID and not writing to database in sandbox mode.
define(‘NOTIFY_URL’, ‘https://www.your-website.com/ipn.php’);
^
should change to
https://www.your-website.com/notify.php
Glad to know that your issue has been resolved.
Same problem here…
Everything seems to work: payment successful for personal account, and I can also see the payment was completed in the seller account.
The problem is the ‘payment_info’ table does not have any data added to it after a transaction. What could be the reasons for that?
Hi thank you for this. Everything seems to work: payment successful for personal account, and I can also see the payment was completed in the seller account.
The problem is the ‘payment_info’ table does not have any data added to it after a transaction. What could be the reasons for that?
Thanks a lot for your efforts! Have a great day
notify.php handle the data insertion, there are various ways you can debug the code, first I would suggest that you should comment all the code in it and try to insert record manually through this file, simply enter any dummy data and hit that URL, if it fails then you will need to check your database connection on this page.
If it is working fine, then you can simply print the values on the page that are received from PayPal and stop redirection.
Hope these will help you out.
PayPal Payment Integration in PHP
Is this approach good for like a “Donations” purpose?
PayPal also provide method to make donation. You will need to follow the instructions.
Sir plz make tutorial for this video
Hi Abhishek, I can’t not promise to make a video on it, but If you are facing any issue so let me know I will explain that part to you.
Plz can u make tuition in that PayPal integration in php
My this tutorial is itself a guide for beginners how wants to integrate PayPal payment on their website.