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.

See my Paypal Tips Section at the end of the Tutorial for the following

  • Using CURL instead of fsockopen
  • Paypal’s IPN Script and Docs

Jump to the Tips Section at the end of the Tutorial or continue on this page with the IPN tutorial itself.

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)

Have a look at my new Video Tutorials about Paypal IPN.

Here are some useful websites to help you.

Top 12 Paypal IPN pages

Overview

IPN Variables

Order Management Guide

Script Generator

Forum


END OF TUTORIAL | END OF TUTORIAL | END OF TUTORIAL | END OF TUTORIAL | END OF TUTORIAL |


IPN Tips Section

  • Using CURL
  • $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);

  • Paypal’s IPN Script and Docs

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

  • I checked this IPN Code and that works fine
    Just a question I received IPN and log them and got two values

    One for current paid and other is for subscription or what any idea ?

  • Stan says:

    Hi, if anyone is facing response 500 internal server error from paypal on live service it may not be your problem, Paypal confirmed an issue with IPN on their side. check this out http://www.lampwebdevelopers.com/152/web-developement/bugs-issues/paypal-express-checkout-ipn-notification-bug/

  • admin says:

    Thanks Stan. Seems like a big problem. Post again if you have any more news. I believe urlencoding helps as well?

    Mike

  • Thanks for sharing valuable information.

  • Elton says:

    Hi, that;s a great tutorial …
    I just wonder if is possible to do it using chained payment ( two receivers )

  • vienlhanz says:

    Hello, when I tested the ipn with sandbox, the ipn is not called.
    Thanks.

  • sandeep says:

    Hi Team,

    I tried implementing the way u had given, it is not getting redirected to my site after the payment is done. I am sure that there is no problem with the notify_url , what else need to be checked ?

    Thanks and Regards
    Sandeep

  • Admin says:

    Hi Sandeep,

    You know Paypal doesn’t redirect user to the notify_url. It just sends data there once the payment is approved. The user doesn’t see this, its just for your server.

    Can you post some more information about the problem?

    Cheers

    Mike

  • free paypal says:

    Great guide, Thank you very much, I have been using Paypal for my site for many years now and this tutorial has helped people I know in achieving their Paypal needs!
    Thank you very much

  • engineerahmad says:

    i used ur script as it is and its sending me mail with error username=empty
    and txn_id=empty whats wrong plz help.

  • admin says:

    Is the email address confirmed on the Paypal Account

  • James says:

    Hi there – love this guide and my script is working. But what I do not understand is:

    You save the customer and order information via paypalipn.php – then you say on your thank you page you have like a timer whilst it checks the information got saved properly to your database….

    Well where is the link between the 2 processes? How do I know which customer record to pull back once on the thank you page? There has to be some sort of ID link, like a pay pal transaction id or similar?

  • admin says:

    You could use php sessions to let different php pages keep in touch with each other?

  • James says:

    Thank so much for your reply. The problem is we are using ASP. I found an ASP version of your page, so I’m purely just using your logic rather than code (hope you don’t mind!)

    Surely there has to be a variable, either query string or post that you can send to your order confirmation to identify which customer or transaction it is?

  • Hi,
    I created payapal library as well:
    https://github.com/pete911/paypal
    it requires php 5.3
    have a look if you like oop

  • Justin says:

    I was wondering how using an encrypted Paypal button makes it secure. If you go this route, are there any other measured you need to take in paypalipn.php to make it secure?

  • admin says:

    Encrypted buttons stop people making their own buttons and putting in their own prices for example

    The integration guide for Website Payments Standard has lots of info
    http://images.paypal.com/en_US/ebook/PP_WebsitePaymentsStandard_IntegrationGuide/toc.html

    On this page http://images.paypal.com/en_US/ebook/PP_WebsitePaymentsStandard_IntegrationGuide/encryptedwebpayments.html
    it gives good advice about security

    I would still do these checks in paypalipn.php even if you have encrypted buttons

    // you must check at the least the following…

    if (($payment_status == ‘Completed’) && //payment_status = Completed
    ($receiver_email == “”) && // receiver_email is same as your account email
    ($payment_amount == $amount_they_should_have_paid ) && //check they payed what they should have
    ($payment_currency == “GBP”) && // and its the correct currency
    (!txn_id_used_before($txn_id))) { //txn_id isn’t same as previous to stop duplicate payments. You will need to write a function to do this check.

    Cheers

  • kevin says:

    never thought of using CURL for this, though its a great idea as i’m sure the speedboost helps.

  • Michael says:

    I have this working fine on the sandbox, as expected it returns POST vars and everything works OK. As soon as I put it live though the listener doesn’t receive anything via POST so nothing works. Any ideas why this may be? It’s driving me mad!

  • Bryan says:

    Thanks for the great tutorial. I had one question: You mentioned that we should give customers a message such as “waiting for Paypal to confirm payment.” How would one create that page to display that message to the customer, and then update the page once Paypal confirms payment, considering that the IPN process is taking place asynchronously and not on the return page?

    Thanks!

  • Scot says:

    Thanks for the tutorial.

    After a ton of debugging and google searching, it sounds like sandbox doesn’t accept non-SSL connections anymore.

    Using SSL in my script fixed my problem, at least.

  • admin says:

    Thanks Scot,

    I have added a warning about this to my script.

    Mike

  • Josh says:

    I appreciate this tutorial, but I got stuck on the step that says:

    <>

    First, I found a “Profile” link, which I clicked. But I do not see a “Selling Preferences” section. I do see a “My Selling Tools” link, but there’s no “Instant Payment Notification Preferences” link there. So, now I’m back to guessing.

  • Josh says:

    The step referred to above is “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””

  • Josh says:

    Okay, I followed the tutorial and tested the results by purchasing one of my own products. But I don’t see a “A webpage that confirms the above have occurred, and continues on to the next phase of you web application”. What step have I missed? How do I test/view the results?

  • Josh says:

    I’m thankful for the tutorial. There’s no mention here (that I saw) that one needs a server that supports CURL. This was something that took me a while to figure out (since I’m a newbie, and why would I need a tutorial if I weren’t?)

    Also, your Paypal instructions are out of date–or don’t correspond to Paypal.

  • superrider says:

    I found a great article while googling, i recommend it.
    http://www.discusswire.com/paypal-ipn-php/

  • admin says:

    Hi Josh,

    I think you must be using a Paypal Personal account. I think it has different menus.
    I assumed people would have a Paypal Business acount.

    The “webpage that confirms etc” is talking about the page you you tell paypal to go to after they pay.
    You can set this up in paypal settings or using something like this…

    You don’t need CURL on all servers. But sounds like yours does. Some don’t allow fsockopen.

    This tutorial is pretty old now but people to still find it useful.
    To be honest I haven’t checked the details for a while.
    I’ll have a look when I get the time :)

    Mike

Leave a Reply

New Discussion Forum

We have teamed up with CrypticGFX.com who are providing a place to discuss our tutorials.

You can still post blog comments as before but if you want a more in-depth discussion have a look at Cryptic GFX.