Paypal Instant Payment Notification (IPN)

This is continuation of the previous post how to setup Paypal Express Checkout in your website. In my experience, you do not necessarily need to setup Paypal Instant Payment Notification (IPN), but if want to automate tasks and keep track of customer actions back in their PayPal account, you should create and setup an IPN listener script.

How IPN works

Lets say, a customer buys a product from your website and your database captures the transaction, but the fund is pending, only after few days buyer realizes this and authorizes the payment in his PayPal account, how will you update this in your database? will you wait for PayPal to send you email or have your IPN script track this user action instantly? I wouldn’t worry if it’s just 1 or 2 products, but imagine dealing with hundreds of customers.

PayPal can send $_POST variables to your script, containing various information about your customer transaction, your script should collect these values and use them to update or insert database records. Your IPN script works in background and has no direct contact with the customer, you just have to point IPN Url to this script from your Paypal IPN settings.

MySQL table

In this tutorial, we will just store information received from PayPal using IPN listener script, but you can program your own script to do lot more. Let’s say we want to create a list of history by inserting received info in the database, we need to create a table similar to below:

[cc lang=”mysql”]
‘itransaction_id’ varchar(60) NOT NULL,
‘ipayerid’ varchar(60) NOT NULL,
‘iname’ varchar(60) NOT NULL,
‘iemail’ varchar(60) NOT NULL,
‘itransaction_date’ datetime NOT NULL,
‘ipaymentstatus’ varchar(60) NOT NULL,
‘ieverything_else’ text NOT NULL,

Listener Script

PHP script ipn_paypal.php below stores any incoming message from Paypal in MySql table. Just put this file somewhere in your website and point IPN Url to this script from your Paypal IPN settings.

To test this script in Paypal sandbox mode, just create an account in Paypal Developer website, once you are logged in to the site, click ‘test tools‘ on sidebar, and click “Instant Payment Notification (IPN) Simulator” and enter this script URL in “IPN handler URL” field, choose Web Accept from “Transaction type” dropdown.

[cc lang=”php”]
$value) {
$value = urlencode(stripslashes($value));
$req .= “&$key=$value”;
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, ‘https://www’.$paypalmode.’’);
curl_setopt($ch, CURLOPT_HEADER, 0);
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_HTTPHEADER, array(‘Host: www’.$paypalmode.’’));
$res = curl_exec($ch);

if (strcmp ($res, “VERIFIED”) == 0)
$transaction_id = $_POST[‘txn_id’];
$payerid = $_POST[‘payer_id’];
$firstname = $_POST[‘first_name’];
$lastname = $_POST[‘last_name’];
$payeremail = $_POST[‘payer_email’];
$paymentdate = $_POST[‘payment_date’];
$paymentstatus = $_POST[‘payment_status’];
$mdate= date(‘Y-m-d h:i:s’,strtotime($paymentdate));
$otherstuff = json_encode($_POST);

$conn = mysql_connect($dbhost,$dbusername,$dbpassword);
if (!$conn)
die(‘Could not connect: ‘ . mysql_error());

mysql_select_db($dbname, $conn);

// insert in our IPN record table
$query = “INSERT INTO ibn_table
(itransaction_id,ipayerid,iname,iemail,itransaction_date, ipaymentstatus,ieverything_else)
(‘$transaction_id’,’$payerid’,’$firstname $lastname’,’$payeremail’,’$mdate’, ‘$paymentstatus’,’$otherstuff’)”;

//mysql error..!

That’s it! you just wait and let script store any information received in the database. Remember you can extend this script functionality to do lot more. Good luck!

29 Comments Add Comment

  • Good example but you really need to provide a working example and downloadable scripts to make this of real benefit. There are variables referred to which are not defined and sections of the script missing.

  • Stop the worked in 2016 ?…. i not know because my sistem stop
    do you can help me ?

  • Hi the code works in sandbox mode with IPN Simulator. But in real with -> $paypalmode = ”; //Sandbox for testing or empty ”. it does not work…. please help.

    with Grea Thanks

  • nice artile.I have implemented on my website .But ipn is not working

  • Hey im using your sanwebe cart. My problem is the transaction still succeeds even if the buyer has no money. In paypal, the status says it was completed. And sometimes, the transaction is not displayed in the history in paypal transaction. I dont need those token i think, all i need is the product list they bought. So i just put a header in the first if(SUCCESS). Can someone help me. I have a deadline in 2 days, and its killin me.

  • This is great!! Thanks a lot my friend, I have been struggling with this IPN stuff for days, and this is the only script that really works!
    I wish you had a Donate button so I can buy you a beer!
    Thanks again!!!

  • Thanks!!! I have tried and tested many other IPN scripts and tutorials, and this is the only one that actually works and properly writing to the MYSQL Database. Thanks! Appreciate!!!

  • Please make a complete demo of it !

  • Thank You so much for this very usefull and easy to understand example!!

  • soryy… this
    `itransaction_id` varchar(60) NOT NULL,
    `ipayerid` varchar(60) NOT NULL,
    `iname` varchar(60) NOT NULL,
    `iemail` varchar(60) NOT NULL,
    `itransaction_date` datetime NOT NULL,
    `ipaymentstatus` varchar(60) NOT NULL,
    `ieverything_else` text NOT NULL,
    PRIMARY KEY (`id`)
    ) ;

  • Perfect – thanks!

  • Hello.

    I have the script working when I send a test ‘web accept’ or ‘express checkout’ from the simulator.
    However when I set sandbox = ” and set a live account (express checkout) to point to the php file I do not get an insert. I have noticed this line:
    curl_setopt($ch, CURLOPT_HTTPHEADER, array(‘Host: www’.$paypalmode.’’));
    has a repeated ‘sanbox’ so I hard coded the line as :
    curl_setopt($ch, CURLOPT_HTTPHEADER, array(‘Host:‘));

    But it still fails.

    Any ideas ?



  • hey thnks for the great scripts, got me past a road block I had hit with the paypal api.
    is there any way to override the setting you have in your PayPal profile for IPN and point paypal express to a dynamic IPN url, I know you used to be able to use NOTIFY_URL in the older form based paypal installations, but cant get it to work with your scripts

  • Thanks for Awesome & Really Helpful Post IPN Code..

  • Above script is not functioning
    Hello, In the above code I changed my db settings. checked above script via ipn simulator. But the problem is that database in not storing any data. Please help

  • Hello,

    Please, can you tell me if this code is working? I am using a code similar and stop working. I tried to use your code in my websitem but without success.

    Thank you.


  • Hi, Thanks for the post.
    If I want to set notify_url manually, where I need to change without specifying it to paypal admin panel?

    I followed your procedure and it worked perfectly without IPN things.
    I want it to set manually in my source code..
    Please Help.

  • How can I use Localhost for IPN url?

  • Hi Saran,

    If I am storing the results of the transaction in the database using your paypal express script, why do I need to store them again using the IPN script?

    many Thanks

    • Example above just shows what you can do with received information, question is how are you going to use it. IPN notifies merchants almost instantly, your script can act based on the information it receives, for example: it can update customer record, email confirmations, trigger order fulfillment, send and enable download links etc, all these tasks can be automated with IPN script, I think it saves lots of time if you are selling many products everyday in your site, think of doing everything manually! More info here :

    • Thanks Saran,

      Thanks for the speedy response!
      I think I get what you mean, so if for example, if I get a ‘pending’ payment via PayPal Express, the IPN script is required to change that pending payment to complete when it is completed on PayPal’s servers – otherwise it wouldn’t update in my db, and always remain pending, even if the payment status has become ‘complete’?
      Is that correct?


  • Ignore my last post, I managed to get it working perfectly. Thanks

  • Hi,

    Thanks for both this tutorial and the Express checkout. Unfortunately this script isn’t returning anything to the database, any suggestion?