PayPal Instant Notification (IPN) is a message service that allows you to integrate your PayPal payments with your website’s back-end operations and administrative function.

Using this merchant will automatically notify events related to PayPal transactions. IPN is very useful when you need to required functionality like automatically fulfilling orders and providing customer, with order status.

In our previous blog post focused on how we use PayPal adaptive payments in PHP for making parallel payments.

In this blog post, we are going demonstrate how we configure PayPal IPN script in PHP.

 


Watch the live demo or download code from the link given below

paypal-ipn-in-PHP


Note: PayPal offers sandbox account for development and testing purpose. Here we are using Sandbox for the demo, so if you would like to test our demo you can use your PayPal sandbox credentials.

 

Concept behind the script

There are three main steps for IPN functionality

1. A web page that include a code for a call to PayPal to make a payment(index.php).
2. An IPN script on your web server that call by PayPal to notify you that payment has been made(ipn.php).
3. A webpage that show details the above have occurred and continues on to the next phase for another application(success.php).

Note: Step 1 and 3 is used by the merchant’s website and 2 will call by PayPal only.If you run that file, there is no output and IPN script will work on the web server only.

Enable IPN in your PayPal business Account

To enable IPN in your PayPal business account do steps which mention on PayPal official IPNSetup page.

 


Tutorial Scripts in detail

Below are the details of the code used in this tutorial with proper explanation.

Note: You can also refer the  PHPProjectInstall.pdf  file given in the download code folder.

 

MY-SQL Code
Create database ipn and create below table.

CREATE TABLE IF NOT EXISTS `ipn_data_tbl` (
`TID` int(11) NOT NULL AUTO_INCREMENT,
`item_name` varchar(255) NOT NULL,
`payer_email` varchar(150) NOT NULL,
`first_name` varchar(150) NOT NULL,
`last_name` varchar(150) NOT NULL,
`amount` float NOT NULL,
`currency` varchar(50) NOT NULL,
`country` varchar(50) NOT NULL,
`txn_id` varchar(100) NOT NULL,
`txn_type` varchar(100) NOT NULL,
`payment_status` varchar(100) NOT NULL,
`payment_metod` varchar(100) NOT NULL,
`create_date` datetime NOT NULL,
`payment_date` datetime NOT NULL,
PRIMARY KEY (`TID`)
)

 

Connection.php

This is the file used for database connectivity.

<?php
$server = "localhost";
$username = "root";
$password = "";
$database = "ipn";

$con = new mysqli($server,$username,$password,$database);
if (!$con){
die('Could not connect: ' . mysqli_connect_error($con));
}
?>

 

Index.php

Index.php contain code for showing Product information as long as some detail about the IPN Message.

<html>
<head>
<title>PayPal IPN Message in PHP</title>
<link rel="stylesheet" type="text/css" href="css/style.css">
</head>
<body>
<div id="main">
<center><h1>PayPal IPN Example Using PHP</h1></center>
<div id="container">
<h2>PayPal IPN Message in PHP</h2>
<hr/>
<div id="left">
<form action="process.php" method="post" >
<center>
<h3>SONY HEADPHONE</h3>
</center>
<img src="images/headphones.jpg" />
<center><input type="submit" name="submit" value=" Buy Now $80" ></center>
</form>
</div>
<div id="right">
<p style="text-align: justify;">Instant Payment Notification (IPN) is a message service that automatically notifies merchants of events related to PayPal transactions.</p>
<center>
<hr class="style-four">
</center>
<ul>
<li>Enable the IPN (Instant Payment Notification) from your PayPal account if it is not enable then IPN Message will not we POST.</li>
<li>IPN Message only generate on the server, at the local server IPN message will not generate.</li>
<li>We can send IPN message to merchant's Email Address as long as We can Store IPN message in the database.</li>
</ul>
</div>
</div>
</div><img id="paypal_logo" src="images/secure-paypal-logo.jpg">
</body>
</html>

 

Process.php

This file contains code to process product amount to PayPal.

<?php
if (isset($_POST['submit'])) {

//Here we can use PayPal URL or sandbox URL.
$paypal_url = 'https://www.sandbox.paypal.com/cgi-bin/webscr';
//Here we can used seller email id.
$merchant_email = 'Enter Your PayPal MerchantID';
//here we can put cancel URL when payment is not completed.
$cancel_return = "http://".$_SERVER['HTTP_HOST'].'/paypal-ipn-php';
//here we can put cancel URL when payment is Successful.
$success_return = "http://".$_SERVER['HTTP_HOST'].'/paypal-ipn-php/success.php';
//PayPal call this file for ipn
$notify_url = "http://".$_SERVER['HTTP_HOST'].'/paypal-ipn-php/ipn.php';
?>
<div style="margin-left: 38%"><img src="images/ajax-loader.gif"/><img src="images/processing_animation.gif"/></div>
<form name="myform" action="<?php echo $paypal_url;?>" method="post">
<input type="hidden" name="business" value="<?php echo $merchant_email;?>" />
<input type="hidden" name="notify_url" value="<?php echo $notify_url;?>" />
<input type="hidden" name="cancel_return" value="<?php echo $cancel_return;?>" />
<input type="hidden" name="return" value="<?php echo $success_return;?>" />
<input type="hidden" name="rm" value="2" />
<input type="hidden" name="lc" value="" />
<input type="hidden" name="no_shipping" value="1" />
<input type="hidden" name="no_note" value="1" />
<input type="hidden" name="currency_code" value="USD" />
<input type="hidden" name="page_style" value="paypal" />
<input type="hidden" name="charset" value="utf-8" />
<input type="hidden" name="item_name" value="HeadPhone" />
<input type="hidden" name="cbt" value="Back to FormGet" />
<input type="hidden" value="_xclick" name="cmd"/>
<input type="hidden" name="amount" value="80" />
<script type="text/javascript">
document.myform.submit();
</script>
<?php }

 

Ipn.php

This file contains code to process  IPN message and send this IPN message to Merchant’s Email address as long as save the IPN message to database.



<?php

require_once("MAILER/smtpservice.php");

class PayPal_IPN {

function ipn($ipn_data) {
define('SSL_P_URL', 'https://www.paypal.com/cgi-bin/webscr');
define('SSL_SAND_URL', 'https://www.sandbox.paypal.com/cgi-bin/webscr');
$hostname = gethostbyaddr($_SERVER['REMOTE_ADDR']);
if (!preg_match('/paypal\.com$/', $hostname)) {
$ipn_status = 'Validation post isn\'t from PayPal';
if ($ipn_data == true) {
//You can send email as well
}
return false;
}
// parse the paypal URL
$paypal_url = ($_REQUEST['test_ipn'] == 1) ? SSL_SAND_URL : SSL_P_URL;
$url_parsed = parse_url($paypal_url);

$post_string = '';
foreach ($_REQUEST as $field => $value) {
$post_string .= $field . '=' . urlencode(stripslashes($value)) . '&';
}
$post_string.="cmd=_notify-validate"; // append ipn command
// get the correct paypal url to post request to
$paypal_mode_status = $ipn_data; //get_option('im_sabdbox_mode');
if ($paypal_mode_status == true)
$fp = fsockopen('ssl://www.sandbox.paypal.com', "443", $err_num, $err_str, 60);
else
$fp = fsockopen('ssl://www.paypal.com', "443", $err_num, $err_str, 60);

$ipn_response = '';

if (!$fp) {
// could not open the connection. If loggin is on, the error message
// will be in the log.
$ipn_status = "fsockopen error no. $err_num: $err_str";
if ($ipn_data == true) {
echo 'fsockopen fail';
}
return false;
} else {
// Post the data back to paypal
fputs($fp, "POST $url_parsed[path] HTTP/1.1\r\n");
fputs($fp, "Host: $url_parsed[host]\r\n");
fputs($fp, "Content-type: application/x-www-form-urlencoded\r\n");
fputs($fp, "Content-length: " . strlen($post_string) . "\r\n");
fputs($fp, "Connection: close\r\n\r\n");
fputs($fp, $post_string . "\r\n\r\n");

// loop through the response from the server and append to variable
while (!feof($fp)) {
$ipn_response .= fgets($fp, 1024);
}
fclose($fp); // close connection
}
// Invalid IPN transaction. Check the $ipn_status and log for details.
if (!preg_match("/VERIFIED/s", $ipn_response)) {
$ipn_status = 'IPN Validation Failed';

if ($ipn_data == true) {
echo 'Validation fail';
print_r($_REQUEST);
}
return false;
} else {
$ipn_status = "IPN VERIFIED";
if ($ipn_data == true) {
echo 'SUCCESS';
}

return true;
}
}

function ipn_response($request) {
//mail("sobhagya1411@gmail.com","My subject",print_r($request,true));
$ipn_data = true;
if ($this->ipn($ipn_data)) {
// if paypal sends a response code back let's handle it
if ($ipn_data == true) {
//mail send
$sub = 'PayPal IPN Message';
$msg = print_r($request, true);
$to = "Enter Receiver MailID";
sendEmail($to, $sub, $msg);
}
// process the membership since paypal gave us a valid +
$this->insert_data($request);
}
}

function issetCheck($post, $key) {
if (isset($post[$key])) {
$return = $post[$key];
} else {
$return = '';
}
return $return;
}

function insert_data($request) {
require_once('connection.php');
$post = $request;
$item_name = $this->issetCheck($post, 'item_name');
$amount = $this->issetCheck($post, 'mc_gross');
$currency = $this->issetCheck($post, 'mc_currency');
$payer_email = $this->issetCheck($post, 'payer_email');
$first_name = $this->issetCheck($post, 'first_name');
$last_name = $this->issetCheck($post, 'last_name');
$country = $this->issetCheck($post, 'residence_country');
$txn_id = $this->issetCheck($post, 'txn_id');
$txn_type = $this->issetCheck($post, 'txn_type');
$payment_status = $this->issetCheck($post, 'payment_status');
$payment_type = $this->issetCheck($post, 'payment_type');
$payer_id = $this->issetCheck($post, 'payer_id');
$create_date = date('Y-m-d H:i:s');
$payment_date = date('Y-m-d H:i:s');
mysqli_query($con, "INSERT INTO ipn_data_tbl (item_name,payer_email,first_name,last_name,amount,currency,country,txn_id,txn_type,payer_id,payment_status,payment_type,create_date,payment_date)
VALUES ('$item_name','$payer_email','$first_name','$last_name','$amount','$currency','$country','$txn_id','$txn_type','$payer_id','$payment_status','$payment_type','$create_date','$payment_date')");
mysqli_close($con);
}

}

$obj = New PayPal_IPN();
$obj->ipn_response($_REQUEST);

 

Success.php

This file contains $_REQUEST array ,which contains IPN Message  and displayed in the front end.



<html>
<head>
<title>PayPal IPN Message in PHP</title>
<link rel="stylesheet" type="text/css" href="css/style.css">
</head>
<body>
<div id="main">
<div class="success_main_heading">
<center><h1>PayPal IPN Example Using PHP</h1></center>
</div>
<div id="return">
<h2>IPN Message Detail</h2>
<hr/>
<table id="results">
<thead>
<tr class="head">
<th>
Property
</th>
<th>
Value
</th>
</tr>
</thead>
<tbody>
<?php if (isset($_REQUEST['mc_gross'])) { ?>
<tr>
<td>
mc_gross
</td>
<td>
<?php echo $_REQUEST['mc_gross']; ?>
</td>
</tr>
<?php } if (isset($_REQUEST['protection_eligibility'])) { ?>
<tr>
<td>
protection_eligibility
</td>
<td>
<?php echo $_REQUEST['protection_eligibility']; ?>
</td>
</tr>
<?php } if (isset($_REQUEST['payer_id'])) { ?>
<tr>
<td>
payer_id
</td>
<td>
<?php echo $_REQUEST['payer_id']; ?>
</td>
</tr>
<?php } if (isset($_REQUEST['tax'])) { ?>
<tr>
<td>
tax
</td>
<td>
<?php echo $_REQUEST['tax']; ?>
</td>
</tr>
<?php } if (isset($_REQUEST['payment_date'])) { ?>
<tr>
<td>
payment_date
</td>
<td>
<?php echo $_REQUEST['payment_date']; ?>
</td>
</tr>
<?php } if (isset($_REQUEST['payment_status'])) { ?>
<tr>
<td>
payment_status
</td>
<td>
<?php echo $_REQUEST['payment_status']; ?>
</td>
</tr>
<?php } if (isset($_REQUEST['charset'])) { ?>
<tr>
<td>
charset
</td>
<td>
<?php echo $_REQUEST['charset']; ?>
</td>
</tr>
<?php } if (isset($_REQUEST['first_name'])) { ?>
<tr>
<td>
first_name
</td>
<td>
<?php echo $_REQUEST['first_name']; ?>
</td>
</tr>
<?php } if (isset($_REQUEST['mc_fee'])) { ?>
<tr>
<td>
mc_fee
</td>
<td>
<?php echo $_REQUEST['mc_fee']; ?>
</td>
</tr>
<?php } if (isset($_REQUEST['notify_version'])) { ?>
<tr>
<td>
notify_version
</td>
<td>
<?php echo $_REQUEST['notify_version']; ?>
</td>
</tr>
<?php } if (isset($_REQUEST['custom'])) { ?>
<tr>
<td>
custom
</td>
<td>
<?php echo $_REQUEST['custom']; ?>
</td>
</tr>
<?php } if (isset($_REQUEST['payer_status'])) { ?>
<tr>
<td>
payer_status
</td>
<td>
<?php echo $_REQUEST['payer_status']; ?>
</td>
</tr>
<?php } if (isset($_REQUEST['business'])) { ?>
<tr>
<td>
business
</td>
<td>
<?php echo $_REQUEST['business']; ?>
</td>
</tr>
<?php } if (isset($_REQUEST['quantity'])) { ?>
<tr>
<td>
quantity
</td>
<td>
<?php echo $_REQUEST['quantity']; ?>
</td>
</tr>
<?php } if (isset($_REQUEST['payer_email'])) { ?>
<tr>
<td>
payer_email
</td>
<td>
<?php echo $_REQUEST['payer_email']; ?>
</td>
</tr>

<?php } if (isset($_REQUEST['txn_id'])) { ?>
<tr>
<td>
txn_id
</td>
<td>
<?php echo $_REQUEST['txn_id']; ?>
</td>
</tr>
<?php } if (isset($_REQUEST['payment_type'])) { ?>
<tr>
<td>
payment_type
</td>
<td>
<?php echo $_REQUEST['payment_type']; ?>
</td>
</tr>
<?php } if (isset($_REQUEST['last_name'])) { ?>
<tr>
<td>
last_name
</td>
<td>
<?php echo $_REQUEST['last_name']; ?>
</td>
</tr>
<?php } if (isset($_REQUEST['receiver_email'])) { ?>
<tr>
<td>
receiver_email
</td>
<td>
<?php echo $_REQUEST['receiver_email']; ?>
</td>
</tr>
<?php } if (isset($_REQUEST['payment_fee'])) { ?>
<tr>
<td>
payment_fee
</td>
<td>
<?php echo $_REQUEST['payment_fee']; ?>
</td>
</tr>
<?php } if (isset($_REQUEST['receiver_id'])) { ?>
<tr>
<td>
receiver_id
</td>
<td>
<?php echo $_REQUEST['receiver_id']; ?>
</td>
</tr>
<?php } if (isset($_REQUEST['txn_type'])) { ?>
<tr>
<td>
txn_type
</td>
<td>
<?php echo $_REQUEST['txn_type']; ?>
</td>
</tr>
<?php } if (isset($_REQUEST['item_name'])) { ?><tr>
<td>
item_name
</td>
<td>
<?php echo $_REQUEST['item_name']; ?>
</td>
</tr>
<?php } if (isset($_REQUEST['mc_currency'])) { ?>
<tr>
<td>
mc_currency
</td>
<td>
<?php echo $_REQUEST['mc_currency']; ?>
</td>
</tr>
<?php } if (isset($_REQUEST['item_number'])) { ?>
<tr>
<td>
item_number
</td>
<td>
<?php echo $_REQUEST['item_number']; ?>
</td>
</tr>
<?php } if (isset($_REQUEST['residence_country'])) { ?><tr>
<td>
residence_country
</td>
<td>
<?php echo $_REQUEST['residence_country']; ?>
</td>
</tr>
<?php } if (isset($_REQUEST['test_ipn'])) { ?><tr>
<td>
test_ipn
</td>
<td>
<?php echo $_REQUEST['test_ipn']; ?>
</td>
</tr>
<?php } if (isset($_REQUEST['handling_amount'])) { ?><tr>
<td>
handling_amount
</td>
<td>
<?php echo $_REQUEST['handling_amount']; ?>
</td>
</tr>
<?php } if (isset($_REQUEST['transaction_subject'])) { ?><tr>
<td>
transaction_subject
</td>
<td>
<?php echo $_REQUEST['transaction_subject']; ?>
</td>
</tr>
<?php } if (isset($_REQUEST['payment_gross'])) { ?>
<tr>
<td>
payment_gross
</td>
<td>
<?php echo $_REQUEST['payment_gross']; ?>
</td>
</tr>
<?php } if (isset($_REQUEST['shipping'])) { ?>
<tr>
<td>
shipping
</td>
<td>
<?php echo $_REQUEST['shipping']; ?>
</td>
</tr>
<?php } if (isset($_REQUEST['merchant_return_link'])) { ?>
<tr>
<td>
merchant_return_link
</td>
<td>
<?php echo $_REQUEST['merchant_return_link']; ?>
</td>
</tr>
<?php } if (isset($_REQUEST['verify_sign'])) { ?>
<tr>
<td>
verify_sign
</td>
<td>
<div style="width: 255px; overflow: auto;">
<?php echo $_REQUEST['verify_sign']; ?>
</div>
</td>
</tr>
<?php } if (isset($_REQUEST['auth'])) { ?>

<tr>
<td>
auth
</td>
<td>
<div style="width: 255px; overflow: auto;">
<?php echo $_REQUEST['auth']; ?>
</div>
</td>
</tr>
<?php } ?>
</tbody>
</table>
<div class='back_btn'><a href='index.php' id= 'btn'><< Back to Product </a></div>;
</div>
<!-- Right side div -->
<div class="fr"id="formget">
<a href=https://www.formget.com/app><img style="margin-left: 12%;" src="images/formget.jpg" alt="Online Form Builder"/></a>
</div>
</div>
</body>
</html>

 

Style.css

Includes basic styling of HTML elements.



/*----------------------------------------------
css settings for HTML div exactCenter
------------------------------------------------*/
@import url(https://fonts.googleapis.com/css?family=Raleway);
#main{
width:960px;
margin:50px auto;
font-family:raleway;
}

span{
color:red;
}

h2{
background-color: #FEFFED;
text-align:center;
border-radius: 10px 10px 0 0;
margin: -10px -40px;
padding: 15px;
}

hr{
border:0;
border-bottom:1px solid #ccc;
margin: 10px -40px;
margin-bottom: 30px;
}

#container{
height: 500px;
width: 90%;
float: left;
border-radius: 10px;
font-family:raleway;
border: 2px solid #ccc;
padding: 10px 40px 33px;
margin-top: 23px;
}

input[type=text],input[type=password]{
width:99.5%;
padding: 10px;
margin-top: 8px;
border: 1px solid #ccc;
padding-left: 5px;
font-size: 16px;
font-family:raleway;
}

input[type=submit]{
width: 40%;
background-color:#FFBC00;
color: white;
border: 2px solid #FFCB00;
padding: 10px;
font-size:20px;
cursor:pointer;
border-radius: 5px;
}
#left{
background-color: rgb(254, 255, 237);
width: 415px;
height: 420px;
float: left;
border: 1px dashed rgb(215, 215, 215);
box-shadow: 0px 5px 17px 1px #99A3AD, 0px 0px 40px #EEEEEE;
}
#right{
width: 415px;
float: right;
height: 420px;
border: 1px dashed rgb(215, 215, 215);
box-shadow: 0px 5px 17px 1px #99A3AD, 0px 0px 40px #EEEEEE;
}

#left img{
width: 383px;
height: 289px;
border: 1px dashed rgb(215, 215, 215);
margin: 0 15px 10px 15px;
}
#left img:hover{
opacity:.80;
}

#left p{
font-size: 18px;
margin-left: 128px;
}
#right p{
padding: 20px;
}
#paypal_logo{
margin: 10px 315px;
float: right;
}

#results {
width: 100%;
margin-top: 30px;
//border: 1px solid #ccc;
table-layout: auto;
margin-bottom: 30px;
}
table {
border-collapse: collapse;
border-spacing: 0;
}
thead {
display: table-header-group;
vertical-align: middle;
border-color: inherit;
}
.head {
font-size: 15px;
font-family: "proxima_novasemibold", sans-serif;
background: #FEFFED;
color: #1d4c55;
border: 1px solid #ccc;
}
tr {
display: table-row;
vertical-align: inherit;
border-color: inherit;
}
.head th{
//border-right: 1px solid #ccc;
//border-bottom: 1px solid #ccc;
line-height: normal;
padding: 10px 0px;
text-align: left;
padding-left: 3%;
}
td {
//border-right: 1px solid #ccc;
border-bottom: 1px solid #ccc;
line-height: normal;
padding: 10px 0px;
text-align: left;
padding-left:3%;
vertical-align: top;
}

tbody {
display: table-row-group;
vertical-align: middle;
border-color: inherit;
}
tr {
display: table-row;
vertical-align: inherit;
border-color: inherit;
}

#return {
width: 492px;
height: auto;
float: left;
border-radius: 10px;
font-family: raleway;
border: 2px solid #ccc;
padding: 10px 40px 30px;
margin-bottom: 50px;
}
#return h3#success {
text-align: center;
font-size: 24px;
color: green;
margin-bottom: 10px;
}
#return P {
text-align: left;
}
#return .back_btn {
margin-top: 30px;
text-align: center;
}
#btn {
width: 100%;
background-color: #FFBC00;
color: white;
border: 2px solid #FFCB00;
padding: 10px 70px;
font-size: 20px;
cursor: pointer;
border-radius: 5px;
margin-bottom: 15px;
margin: 0 auto;
}
a{
text-decoration:none;
color: #33BADB;
}
.success_main_heading{
margin-left: -40%;

}
#return h3#fail{
text-align: center;
font-size: 24px;
margin-top: 50px;
color: red;
margin-bottom: 10px;
}
.red{
color:red;
font-weight: bold;
}
ul li{
margin-bottom: 15px;
text-align: justify;
margin-right: 20px;
}
hr.style-four {
margin-bottom: 10px;
width: 300px;
padding: 0;
border: none;
border-top: 1px solid rgba(0, 0, 0, 0.1);
color: #333;
text-align: center;
}
hr.style-four:after {
content: "Note";
display: inline-block;
position: relative;
top: -0.7em;
font-size: 1em;
padding: 0 0.25em;
background: white;
font-weight: 600;
}

 

Conclusion :

After reading the above post, I am sure you will give a try to the script provided and implement it in your own projects as well. Feel free to visit our website again in the future to get in touch with new coding tricks. You can let us know about your feedback in the space provided below :)