Integrating PayPal IPN listener – server side – the easy way!
In this tutorial we will talk about PayPal. Everybody is using it these days and it would be a great advantage if you have it on your own website.
Imagine how easy it could be, if you can accept orders/payments via paypal and process everything on your server. You will be able to keep a tracking of the existing orders and you will always be informed( almost instantly ) if the item is paid correctly.
Do you need the described above functionality?
If the answer is “yes” then PayPal IPN is here to help! There is just a small thing to note – in order to use IPN you need to own a paypal Premier, or Business account.
Ok, let’s assume that you already have an account. The first thing you need to do is to create a listener on your server – this is the link that PayPal will inform when the payment status is changed.
Ok, but how hard is to start Integrating PayPal IPN listener – server side?
My answer that it’s easy as 1+1!
Here is an example of the listener that you are going to need:
[code language=”php”]
//Integrating PayPal IPN listener – server side
<?php
// CONFIG: Enable debug mode. This means we’ll log requests into ‘ipn.log’ in the same directory.
// Especially useful if you encounter network errors or other intermittent problems with IPN (validation).
// Set this to 0 once you go live or don’t require logging.
define("DEBUG", 1);
// Set to 0 once you’re ready to go live
define("USE_SANDBOX", 1);
define("LOG_FILE", "./ipn.log");
// 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
if(USE_SANDBOX == true) {
$paypal_url = "https://www.sandbox.paypal.com/cgi-bin/webscr";
} else {
$paypal_url = "https://www.paypal.com/cgi-bin/webscr";
}
$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_SSL_VERIFYPEER, 1);
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, 2);
curl_setopt($ch, CURLOPT_FORBID_REUSE, 1);
if(DEBUG == true) {
curl_setopt($ch, CURLOPT_HEADER, 1);
curl_setopt($ch, CURLINFO_HEADER_OUT, 1);
}
// CONFIG: Optional proxy configuration
//curl_setopt($ch, CURLOPT_PROXY, $proxy);
//curl_setopt($ch, CURLOPT_HTTPPROXYTUNNEL, 1);
// Set TCP timeout to 30 seconds
curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 30);
curl_setopt($ch, CURLOPT_HTTPHEADER, array(‘Connection: Close’));
// CONFIG: Please download ‘cacert.pem’ from "http://curl.haxx.se/docs/caextract.html" and set the directory path
// of the certificate as shown below. Ensure the file is readable by the webserver.
// This is mandatory for some environments.
//$cert = __DIR__ . "./cacert.pem";
//curl_setopt($ch, CURLOPT_CAINFO, $cert);
$res = curl_exec($ch);
if (curl_errno($ch) != 0) // cURL error
{
if(DEBUG == true) {
error_log(date(‘[Y-m-d H:i e] ‘). "Can’t connect to PayPal to validate IPN message: " . curl_error($ch) . PHP_EOL, 3, LOG_FILE);
}
curl_close($ch);
exit;
} else {
// Log the entire HTTP response if debug is switched on.
if(DEBUG == true) {
error_log(date(‘[Y-m-d H:i e] ‘). "HTTP request of validation request:". curl_getinfo($ch, CURLINFO_HEADER_OUT) ." for IPN payload: $req" . PHP_EOL, 3, LOG_FILE);
error_log(date(‘[Y-m-d H:i e] ‘). "HTTP response of validation request: $res" . PHP_EOL, 3, LOG_FILE);
}
curl_close($ch);
}
// Inspect IPN validation result and act accordingly
// Split response headers and payload, a better way for strcmp
$tokens = explode("rnrn", trim($res));
$res = trim(end($tokens));
if (strcmp ($res, "VERIFIED") == 0) {
// check whether the payment_status is Completed
// check that txn_id has not been previously processed
// check that receiver_email is your PayPal email
// check that payment_amount/payment_currency are correct
// process payment and mark item as paid.
// assign posted variables to local variables
//$item_name = $_POST[‘item_name’];
//$item_number = $_POST[‘item_number’];
//$payment_status = $_POST[‘payment_status’];
//$payment_amount = $_POST[‘mc_gross’];
//$payment_currency = $_POST[‘mc_currency’];
//$txn_id = $_POST[‘txn_id’];
//$receiver_email = $_POST[‘receiver_email’];
//$payer_email = $_POST[‘payer_email’];
if(DEBUG == true) {
error_log(date(‘[Y-m-d H:i e] ‘). "Verified IPN: $req ". PHP_EOL, 3, LOG_FILE);
}
} else if (strcmp ($res, "INVALID") == 0) {
// log for manual investigation
// Add business logic here which deals with invalid IPN messages
if(DEBUG == true) {
error_log(date(‘[Y-m-d H:i e] ‘). "Invalid IPN: $req" . PHP_EOL, 3, LOG_FILE);
}
}
?>
Integrating PayPal IPN listener – server side
[/code]
In the code above you can find almost everything that you might need in order to proceed your orders – mind that you need to change the DEBUG option when you are done with the tests
Ok, looks good, but how can we check if this integrating PayPal IPN listener – server side tutorial is working?
Really easy!
Login to the PayPal developers console and under the “DASHBOARD” option you will find an “IPN Simulator” link. Don’t be afraid and click on it.
There are few boxes, but the most important is the first one – you will need to point the URL of your listener.
For example: http://yourwebsiteLink.com/paypal/listener.php
In the second box you need to choose the type of simulation.
Clicking on the “Send IPN” button at the bottom of the page PayPal will send a request to your server and write it in a .log file inside of the listener’s directory
Now if everything is ok you can start integrating PayPal to your website.
Integrating PayPal IPN listener – server side was never easier