Paypal IPN: receiving instant payments in your web application.

This paypal ipn tutorial explains how to use Paypals IPN system with a simple single item purchase. Instant Payment Notification allows you to integrate your PayPal payments with your website’s back-end operations, so you get immediate notification and authentication of the PayPal payments you receive. The main use of IPN is where your website needs to know immediately that payment has been made. For example you might have sold something that you will then make available for the user to download.

There is a lot of information on the Paypal website which is worth looking at but the following paypal ipn example will show you in detail a real world example of how to use it.

There are 3 main parts to an IPN system.

1) A webpage that initiates a call to Paypal to make a payment
2) A php page on your webserver that Paypal calls to notify you that payment has been made
3) A webpage that confirms the above have occurred, and continues on to the next phase of you web application.

1 and 3 will be part of your website and accessible to users in the normal way. 2 however is only ever accessed by paypal.

I will first explain some of the issues that you need to understand if you want to know how to use IPN.

Paypal Account Setup

Your Paypal account must be setup correctly to use IPN. Check the following in your paypal account (under edit profile).

under “Selling Preferences” , “Instant Payment Notification Preferences”

  • set IPN to “On”
  • set IPN Url to the page containing the ipn code shown later in the tutorial. The name I use is “http://<yourwebsite address>/paypalipn.php” but you can use anything here.

Under “Selling Preferences”, “payment receiving preferences”

  • block payments from users who pay with echeck. (This is because these will not be instant)

Under “account information” , “email”

  • make a note of your primary email address. You will need to embed it in the code below. This email will be visible to users so make it a professional one. Users don’t get a good feeling about sending money to a hotmail address or to an address that doesnt match the website.

Sequence of Events

The way IPN works is a bit unusual so to explain…

You initiate IPN by sending a message to Paypal from the webpage that the user is on when they confirm a purchase.
What happens next is that 2 completely separate chains of events occur.

  • The first is the obvious one where the user goes to the paypal website, makes the payment and is returned to your website where they can be told their purchase is confirmed.
  • The second is initiated by Paypal and envolves Paypal calling up a predetermined webpage on your site (paypalipn.php). Paypal will send a message to this page which indicates that the payment has happened, how much was paid, who paid it, who was paid etc. On this page you need to check these details and somehow log that the payment has happened, usually by updating a database.

These two chains of events are happening at the same time (only the first is visible to the user). Although as the paypal event is more complex it will usually take longer. For this reason when you send the user to the confirmation page and it checks the database that payment has happened ok it may well find that the payment hasn’t yet been made. You will need to create some code that waits for the payment to go through and as this can take quite a few seconds you will need to inform the user with a message along the lines of “Waiting for Paypal to confirm payment…”.

So in summary

  1. Customer makes a payment through your website.
  2. Paypal sends an IPN to your specified ipn webpage specifying what has been bought etc
  3. Your webpage validates the IPN and sends Paypal an acknowledgement.
  4. Customer continues to access your website.

2 and 3 occur in parallel with what the user is doing in 4) on your website.

The purchase page

The easiest way to generate the code to use on this page is to use Paypals “Buy Now Button” function. Log in to Paypal and look under Merchant Services for “Buy It Now” button.

Fill in the information as required

You must take steps to ensure the security of the purchase.
There are various ways of doing this

  • Encrypt the button on the paypal site (there is an option for this)
  • Encrypt the button yourself (complex and beyond this tutorial)
  • Manually check all prices before shipping. I assume this isn’t appropriate for this tutorial.
  • Check all the values in the IPN processing. (Explained below in the paypalipn.php code)

If you enter an image for the button make sure it is on a secure (https) server otherwise the user will get a warning about insecure items which may scare them off continuing with the purchase.

Click to “Create Button” and copy and paste the code produced into your purchase web page.

The code will look something like this…

button code

The IPN webpage code

Paypal IPN page
Save this as paypalipn.php

Notes

There are two methods of validating the IPN sent by Paypal. Shared Secret and Postback. Paypal recommends shared secret as it is more secure but this tutorial uses Postback. Shared Secret requires that you have dedicated hosting, SSL enabled and you use Paypal Encypted website payments. Paypal recommends Postback for shared hosting applications and where you dont have SSL.
They also don’t recommend you use IPN unless you have SSL !

This is too complicated!

Hope you enjoyed the tutorial. IPN is a complicated subject. If you found it too complicated there are a few commercial products out there that will handle everything for you, such as (this is an affiliate link so I am paid for this recommendation)

Here are some useful websites to help you.

Overview

IPN Variables

Order Management Guide

Script Generator

Forum

56 Responses to “Paypal IPN: receiving instant payments in your web application.”

  • Britney says:

    do not attempt this tutorial on crack

  • Mike krol says:

    I am trying to figure out if you have to have a
    business Pay Pal account to access the IPN area.

    I was told by the instuctions on a digital delivery script I bought to just login to my reg Pay Pal account and the IPN is under edit profile but I cannot find it in my standard Pay Pal account.

    I can make Pay Pal buttons. I have the sandbox account. I just need to enable the IPN settings
    and paste a string into the box.

    I have looked eveywhere but cannot find the IPN settings area. Is that only avaiilable if you open a business account.

    I know his sounds stupid, and that I should probably already have the Business account, but I want to test this script out first and I am a way from launching my site.

    So I am trying to try this Digital Delivery out first and get it down prior to openibg my site.

    Any help would be appreciated.

    Thanks,
    Mike

  • admin says:

    Hi Mike,

    There are Personal, Premier and Business accounts.

    You need Premier or Business I think.

    Cheers

    Mike

  • admin says:

    Forgot to say,

    What you really need to do is sign up for Paypal Developer network at https://developer.paypal.com/

    This lets you create pretend accounts using pretend money! So you can try everything out first before going live. Including creating dummy Business Accounts.

    Edit: Just noticed you say you have the sandbox, so I guess you know about this. I’ll leave the comment up though as it might be useful to others.

    Mike

  • Edison Lau says:

    Hi,

    I followed your instructions but after i uploaded the file i went to it using my browser and i get an error message.

    Parse error: syntax error, unexpected ‘=’, expecting ‘)’ in /home/lionel/public_html/runescapegod/paypalipn.php on line 13

    Please Help

  • admin says:

    Hi Edison,

    There was a bug on that line which I have fixed now. You might need to refresh the page to get the fixed version. Also emailed you.

    The > sign had turned into & gt;

    Mike

  • admin says:

    Think I just deleted a real comment by mistake in the middle of the endless Spam. Please repost.

  • Jimmy P. says:

    Hey Mike, or others looking in their account for the IPN setting – I can never find it either; all i can do is search paypal for IPN, and that takes you to the page where you can turn it on or off and set the URL for the postback.

  • oriol says:

    Good job on commenting the code.

    I still have one doubt when you say:
    “a “custom” variable is available for you to pass whatever you want in it.”

    Since I need to manange online transactions, I need to pass Paypal an “OrderId” and more important, I need paypal to send it back to my php script to procees the transaction. How do you do that? Is there any other way to assure transactions on my website and payments on paypal?

    Thank’s in advance.
    Oriol

  • admin says:

    To pass an orderid using the custom variable…

    In the button code you can see the last line before the end of the form in the example is
    <input type=”hidden” name=”custom” value=”any other custom field you want to pass”>

    so you would change this to

    <input type=”hidden” name=”custom” value=”your orderid value”>

    obviously you will need to put an actual value in here.

    Paypal will pass this through and you can get it in the paypalipn.php code
    In my example I have…

    // a “custom” variable is available for you to pass whatever you want in it.

    $item_name = $_POST['item_name'];
    $item_number = $_POST['item_number'];
    $item_colour = $_POST['custom'];

    So you would change $item_colour to $orderid

    Thanks for the comment. Hope this helps.

    Mike

  • Liam says:

    Is there a simpler method? I’m still trying to grasp a lot of this, and want to be able to code some IPN into my applications, however, some are subscription based sites, and others are download based sites. Is there a simpler version of the code to learn from firsthand?

  • admin says:

    not that I know of, sorry. If you find any good resources let me know and I’ll add them to the tutorial.

    Mike

  • Victor says:

    Hi Mike,

    thank you for this tutorial. I’m trying to integrate it – with some minor modifications – into my site. I’ve tried it and I do receive the payment (from a MasterCard) into my PayPal account but my ‘paypal_ipn.php’ didn’t do anything (no database upgrade, no e-mail sending). I checked the URLs, everything seems to be OK… Can you help out somehow?
    I really appreciate your time.

  • admin says:

    Hi Victor,

    You uncommented the success debug code? And changed where I put payit@designertuts.com to your own email address of course.

    If you are getting the payment I would expect the success debug email to be sent. Strange if it isn’t. Why don’t you post your code or email it to me mike@designertuts.com

    Mike

  • Hey,

    Thanks for making such a seemingly impossible task simple.

    The documentation was very daunting and I had been putting off IPN for a while, but it was easy as hell to integrate with this tutorial.

    Thanks
    Stephen

  • admin says:

    Cheers Stephen,

    Like your Pagerank checker :)

    Mike

  • Natalie says:

    Thanks for the tutorial–very helpful. It has a bit more explanation than Paypal’s (at least the one I found).

  • Tristan Davies says:

    Very good tutorial – best one I’ve found so far. I am currently editing your code to suit my needs.
    It would be fairly useful if you gave an example that included putting completed transactions in a mysql database and checking for duplicates via said database. Just a suggestion.

  • admin says:

    Thanks for the comments and suggestion Tristan.

  • Ofer says:

    Hey there,
    Great post, i finished testing it and it works, first time ever something i downloaded is working first run.
    Thumbs-up

  • Shelly says:

    Very informative, much better than Paypal documentation…..plz suggest abt creating a DB to b linked to this page which can check the duplicate ipns….

  • Tejas Parab says:

    Hi,

    I am working on a project which involves Paypal IPN integration, I have to say your article does provide basics in a nutshell. Thank you for the same.

    -Tejas

  • ruchita says:

    hi,
    great work ,it help me alot plz suggest me can i use ipn notification with ebay listing.

  • orson aston says:

    I tried making a database call and I guess it threw things off. Everything works, but if I try making a database call if VERIFIED, to change the ‘pay’ field from ‘pending’ to ‘complete’, using the ‘custom’ field, it isn’t responding. I’m assuming this has to do with the back and forth nature of this script between paypal and the server, but am not sure.
    Sort of like this:

    $orderID = $_POST['custom'];

    if (strcmp ($res, “VERIFIED”) == 0) {
    // connect to database
    // update pay status to ‘complete’ where orderID = orderID
    }

    is this possible, or is there a workaround?

  • orson aston says:

    wow, ok nevermind – I’d checked my syntax about 15 times before I posted, but it’s 16…16 times. So what went wrong you ask? Using the ‘include’ function in php from a subdirectory, don’t forget your forward slash (/) BEFORE your file path…
    from – “path/image.php”
    to – “/path/image.php”
    this takes you back up to the root directory.

  • ray says:

    Thanks a lot!It’s really helpful for me.

  • Adam Brewer says:

    Thanks for sharing this – far simpler and easier to follow than most of the other Paypal tutorials knocking about! Adam

  • kris says:

    For some reason the confirmation part paypalipn.php is giving me some problems or seems to be skipped in the process. it even doesn’t work if i make a simple verification like:

    if ($payment_status == ‘Completed’)
    {
    $mail_To = “myemail@email.com”;
    $mail_Subject = “completed status received from paypal”;
    $mail_Body = “completed: $item_number $txn_id”;
    mail($mail_To, $mail_Subject, $mail_Body);
    }

    i also did set the notify_url with the correct path to the paypalip.php path in the form which is being sent to paypal

    anyone got the same problems? or can help out please?

    Much appreciated.

  • admin says:

    Could you post all the code. I can’t see anything wrong with what you have posted so far.

    Mike

  • Tom Arnfeld says:

    Hi
    I used the script generator to generate some IPN code that now works, sending a transaction from the sandbox website… all i dont understand is how i get a normal user to send the IPN?
    When im setting up a button.. what options to i setup?

  • admin says:

    Hi Tom,

    Just look at the button code in the tutorial. That should give you an idea. Every case is different though. You need to customise it for your own situation.
    http://designertuts.com/wp-content/uploads/2007/10/but-code

    It’s Paypal who send the IPN. Not the user of course.

  • Adamo says:

    Hi
    I used the script generator to generate some IPN code that now works, sending a transaction from the sandbox website… all i dont understand is how i get a normal user to send the IPN?
    When im setting up a button.. what options to i setup?;…

  • admin says:

    Adamo,

    Just look at the example button code here
    http://designertuts.com/wp-content/uploads/2007/10/but-code

    Mike

  • Clay says:

    Great explanation! Thanks a lot!

  • Dudley says:

    Hello

    I would like to use php, Dreamweaver CS4, mySQL, and payPal to create an online store. Is there any way to store the paypal button code in mySQL database for dynamic pages? Are there any videos, or websites that will show me how to do this?

  • Rob says:

    Good Tutorial. Explained things in a simple, straightforward way. I highly recommend it.

  • Robin says:

    Hi

    I just wanted to thank you for documenting the code that paypal themselves failed to do!

  • nphp101 says:

    nice, tuts for beginners! four thumb ups!

  • admin says:

    PP_MTS_Haak on the Paypal site suggests the following code if you need to use Curl instead of fsockopen
    https://www.x.com/docs/DOC-1551

    $url= ‘https://www.sandbox.paypal.com/cgi-bin/webscr’;
    $curl_result=$curl_err=”;
    $ch = curl_init();
    curl_setopt($ch, CURLOPT_URL,$url);
    curl_setopt($ch, CURLOPT_RETURNTRANSFER,1);
    curl_setopt($ch, CURLOPT_POST, 1);
    curl_setopt($ch, CURLOPT_POSTFIELDS, $req);
    curl_setopt($ch, CURLOPT_HTTPHEADER, array(“Content-Type: application/x-www-form-urlencoded”, “Content-Length: ” . strlen($req)));
    curl_setopt($ch, CURLOPT_HEADER , 0);
    curl_setopt($ch, CURLOPT_VERBOSE, 1);
    curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, FALSE);
    curl_setopt($ch, CURLOPT_TIMEOUT, 30);
    $res = @curl_exec($ch);
    $curl_err = curl_error($ch);
    curl_close($ch);

  • mkarron says:

    Hi,

    I have an IPN working OK, but I find its behavior quite amazing (unless there is something that I do not understand…)

    PayPal process payments even if it has returned ‘INVALID’ in the IPN! I have made some intentionl tests to force an ‘INVALID’ answer from PayPal, and:

    - There is no feedback at all in the payment pages about this fact.
    - The credit card charge goes ahead.

    …or there is something that I miss?

  • admin says:

    When Paypal sends back INVALID it is just saying that the info you sent was wrong.

    It is quite separate from the payment.

    The payment is the first thing that happens.
    Then paypal tells you about it.
    Then you tell paypal what you think it just told you.
    Then paypal says yes thats what I told you (VERIFIED) or no you misheard me (INVALID)

    I think :)

    Mike

  • mkarron says:

    Yes, yes it is like you say; I understand… and we have to live with this for the moment.

    Just, IMHO, it would be much smarter to have the possibility to block a payment directly from IPN, rather than wasting the time later in disputes, refunds, etc.

    So, what I miss (if any PayPal guy read this…) is to have the possibility to append something like “&cmd=_block_payment”, if things go wrong, in addition to the “&cmd=_&cmd=_notify-validate”, if all is OK.

    So, extend it to be also “IPPN” (Pre-Payment notification)

  • Ross says:

    Hi Mike,

    I have spent the last 2 days trying to solve this problem. I have implemented paypal ipn and tested extensively using the sandbox however when I moved this to the real paypal site everything works except where I send the confirmation email from my site not paypals confirmation email. I have an if(mail($to …) statement and in my log file this has evaluated to true as if the email has sent but the receiver never gets this email. I have the exact same code with the sandbox and this works fine. Have u ever seen anything like this? Your help here would be greatly appreciatted.

    Thanks,
    Ross

  • admin says:

    Sorry Ross I can’t think of anything.

  • Rijo says:

    sir,
    i used your code but it is not working.. after making the payment paypal is not sending back the data.. please help me…

  • admin says:

    Have you enabled IPN in your Paypal account?

  • svarga says:

    “We have had an INVALID response”.

    Is it possible I wrote uncorrect Mysql querry?

  • svarga says:

    Ok, I correct this code, mea culpa. Every thing is ok, “completed status received from paypal” thank you, my friend. But nothing to change in the database. And no error messages, like “unable connect to the database”. Maybe I miss some {} or something like this? Or replaced mysql querry in the wrong place?

Leave a Reply