Paypal IPN PHP Handler Script

This is the fourth part of the PayPal IPN PHP script tutorial. This part will discuss the details of the IPN handler script. Let’s name this script “ipnhandler.php.”

Setting up your IPN URL

Before discussing this script in detail, you need to set up your IPN URL. When a customer on your website clicks the Buy Now button, they will be taken to PayPal for payment. After this successful transaction, PayPal’s server sends an IPN message which essentially contains all the information relating to the transaction (product purchased, transaction number, amount paid, etc) to your IPN URL.

If you upload the IPN PHP script to the “paypal_ipn_demo” folder, the IPN URL, for example, will be:

How are you going to inform PayPal of your IPN URL?

Note: Since you are still testing your application, you will use the PayPal Sandbox to set your IPN URL and test your scripts.

  1. Go to and log in using your PayPal Sandbox account.

  2. Click “Test Accounts” and select the radio button for your test business account in Sandbox.

  3. Click “Enter Sandbox Test Site.”

  4. Click “Profile,” and under “Selling Preferences,” click “Instant Payment Notification Preferences.”

  5. By default the IPN is off. You will need to turn it on. Click “Choose IPN settings.” Then, in the “Notification URL” section, you will need to enter your IPN URL, e.g.

  6. Under “IPN Messages,” select “Receive IPN messages,” and then click “Save.” This completes the process of setting up your IPN URL in PayPal.

{mospagebreak title=IPN Handler PHP Script: ipnhandler.php}

Below is the complete script for the IPN handler (with validation, error logging and insertion of validated information into the database). The script is a modification of the original IPN PHP script by PayPal here:


//Receive and read the post from PayPal

//After successful customer transaction in PayPal, its servers will send an IPN message to the IPN URL you provide in your PayPal business account.

$req = ‘cmd=_notify-validate’;
foreach ($_POST as $key => $value) {
$value = urlencode(stripslashes($value));
$req .= "&$key=$value";

//To ensure that the message is coming from PayPal, you are required by PayPal to post the entire IPN message back to PayPal for verification.

//This means that the same set of IPN messages are sent back to PayPal immediately after you receive them.

//It is recommended that you use port 443 for connecting to PayPal servers for security reasons because it will be an encrypted communication.

//Make sure your web host allows communication in this port number, also connecting using ssl in fsockopen requires your server to have OpenSSL installed.

//If you see errors, you need to contact and ask support to your web host.
//Since you are still testing this script in the sandbox, you will be connecting to Once everything is working well, you need to change this to

$header .= "POST /cgi-bin/webscr HTTP/1.0rn";
$header .= "Content-Type: application/x-www-form-urlencodedrn";
$header .= "Content-Length: " . strlen($req) . "rnrn";
$fp = fsockopen(‘ssl://’, 443, $errno, $errstr, 30);

//Then you need to assign posted variables from PayPal to PHP variables
//There are a lot of variables that can be passed from PayPal to your IPN URL. You can see the complete list here:

//However, for PayPal IPN implementation for digital downloads such as ebooks, mp3, etc, the following are the important variables that you need to receive, process, validate and insert to your database.

//Take note that the invoice and customer ip address variables are coming from the shopping page you set up in the second part of this tutorial, and are passed from PayPal to your script using IPN communication.

$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’];
$invoice = $_POST[‘invoice’];

//Connect to MySQL database

//This is discussed in the second part of this tutorial series

include ‘/home/www/’;
if (!$fp) {

//HTTP ERROR, this is most likely caused by the issue relating to fsockopen transaction. For example, your web host prevents access to the secure port 443, or there is a syntax error in your fsockopen.

//It is important to log the error to the MySQL database for easy troubleshooting. The ipnlogs table was c created in the third part of this tutorial series. The error numbers of the fsockopen are also logged to your database. You can see more about error numbers here:

//Remember that if there are errors relating to fsockopen, you will not be able to send back the IPN message to PayPal or get the reply from PayPal, which is an important requirement for IPN verification.

$log=’http error=’.$errno;
$log = mysql_real_escape_string($log);
mysql_query("INSERT INTO ipnlogs (eventlog) VALUES (‘$log’)");
else {
fputs ($fp, $header . $req);
while (!feof($fp)) {
$res = fgets ($fp, 1024);
if (strcmp ($res, "VERIFIED") == 0) {

//Now that the IPN transaction is "VERIFIED" according to PayPal, you can log this successful transaction to ipnlogs table for tracking purposes.

$log=’Verified IPN Transaction’;
$log = mysql_real_escape_string($log);
mysql_query("INSERT INTO ipnlogs (eventlog) VALUES (‘$log’)");

//For every verified IPN transaction, it is required by PayPal to check that the txn_id has not been previously processed. This will prevent duplicate transactions. So query the database to see if the $txn_id is or is not new.

$txn_id = mysql_real_escape_string($txn_id);
if (!($fetch = mysql_fetch_array( mysql_query("SELECT `TransactionID` FROM `customerrecords` WHERE `TransactionID`=’$txn_id’")))) {

//No records found in the customerrecords table, transaction ID is new
//Proceed with validating the rest of the IPN variables

//check that receiver_email is your Primary PayPal email. This is very important to prevent spoofing the transaction and ensures that this payment belongs to you and not to other accounts.

if ($receiver_email==’’) {
$receiver_email = mysql_real_escape_string($receiver_email);
else {
die(‘ERROR: Invalid Paypal Seller Email address.’);
//check if payment currency is USD

if ($payment_currency==’USD’) {
$payment_currency = mysql_real_escape_string($payment_currency);
else {
die(‘ERROR: Incorrect currency’);

//Check if the payment amount is correct
//This is an important validation since your PayPal Buy now button on your shopping page is not protected/encrypted, so malicious users can change the price.

//By comparing the amount paid by the customer in PayPal to the exact price stored in the products table (created in the third part of this tutorial), you can ensure that the amount paid is correct and not spoofed.

//First, retrieve the product price in the productstable for the purchased product.

$productname = mysql_real_escape_string($productname);
$result = mysql_query("SELECT `ProductPrice` FROM `productstable` WHERE `ProductName`=’$productname’")
or die(mysql_error());
$row = mysql_fetch_array($result)
or die("Invalid query: " . mysql_error());
$productprice = $row[‘ProductPrice’];

//Finally, compare the amount paid by the customer in PayPal to the original product price stored in productstable.

if ($payment_amount==$productprice) {
$payment_amount = mysql_real_escape_string($payment_amount);
else {
die(‘ERROR: Incorrect payment amount’);

//check to see if the payment_status is “Completed”
//It is highly important that you allow only customers that are fully paid in PayPal to download.

if ($payment_status==’Completed’) {
$payment_status = mysql_real_escape_string($payment_status);
else {
die(‘ERROR: Payment status not completed’);

//Validate Payer email address
//This uses the is_email.php RFC client email validator
//You can refer to this tutorial for details:
//In this case, you need to download the validator here:
//Unzip it and copy the file is_email.php to paypal_ipn_demo folder
//Once uploaded, you can now use it in this script using require_once

if (is_email($payer_email)) {
$payer_email = mysql_real_escape_string($payer_email);
else {
die(‘ERROR: Invalid payer email address’);

//Validate invoice number
//The invoice number is generated by the invoice number generator function in your shopping page as discussed in Part 2.
//The generated invoice number uses the alpha numeric format.

if (ctype_alnum($invoice)){
$invoice = mysql_real_escape_string($invoice);
else {
die(‘ERROR: The submitted invoice data is NOT alphanumeric’);

//Validate IP address
//In PHP 5, you can use filter var function to validate the IP address
//This requires that your server use PHP 5.

if(filter_var($customeripaddress, FILTER_VALIDATE_IP)){
$customeripaddress = mysql_real_escape_string($customeripaddress);
else {
die(‘ERROR: The submitted IP address data is NOT valid.’);

//Set download status to "incomplete" because the user still needs to download the purchased digital products from your website.

$downloadstatus = mysql_real_escape_string($downloadstatus);

//Now that everything has been verified and validated, you can insert all validated records into the customerrecords database.

//Bear in mind that all of these variables are sanitized with mysql_real_escape_string before insertion into the database.

mysql_query("INSERT INTO customerrecords (PaymentStatus,PaymentAmount,PaymentCurrency,PayerEmail,ReceiverEmail,TransactionID,
InvoiceNumber,ProductPurchased,IPAddress,DownloadStatus) VALUES (‘$payment_status’,’$payment_amount’,’$payment_currency’,’$payer_email’,’$receiver_email’,
‘$txn_id’,’$invoice’,’$productname’,’$customeripaddress’,’$downloadstatus’)") or die(mysql_error());

//close MySQL database connection

else {

//transaction ID already exists in the database, could not process request
//You can alternatively log this transaction into your database for investigation and monitoring purposes

die(‘Could not process request-transaction ID already exist’);
else if (strcmp ($res, "INVALID") == 0) {

//Invalid IPN transaction
//You can alternatively log this transaction into your database for troubleshooting purposes

$log=’Invalid IPN transaction’;
$log = mysql_real_escape_string($log);
mysql_query("INSERT INTO ipnlogs (eventlog) VALUES (‘$log’)");
//close the connection

fclose ($fp);

Implementing the ipnhandler.php script

Now that the script is done, you can save this script inside your paypal_ipn_demo folder. All of the required files and folders inside the paypal_ipn_demo that we’ve covered so far in this series are shown in the screen shot below:

1. ebookdownloads – This is the secure folder where you store the digital products. This is protected with .htaccess. The details of how this folder is created were discussed in the third part of the tutorial series.

2. connect.php – This is the PHP script that will be used to connect to your MySQL database for storing the IPN records and information about your products. This was discussed in the second part of this series.

3. index.php – This the shopping page where visitors can see your product as well as your PayPal Buy now buttons. This was discussed in part two.

4. invoicenumbergenerator.php – This is the script that will produce the invoice numbers. This was also discussed in part two.

5. is_email.php – This is the RFC compliant email validator script coming from this source: . This script is used in this tutorial (part four).

6. ipnhandler.php – This is the IPN script which is discussed thoroughly in this tutorial (part four). You can download the complete ipnhandler script as discussed without comments here:

All database tables were created in the third part of this tutorial. However, the project is still not complete. The customer will still need to download the ebook and use the invoice number to authenticate. In this case, you need to create a new PHP script that will execute these tasks. This will be discussed in the fifth part of this tutorial.

[gp-comments width="770" linklove="off" ]

chat sex hikayeleri Ensest hikaye