Using PHP with PayPal’s IPN (Instant PayPal Notification) to automate your digital delivery

When you want to sell something through the internet, PayPal is your best choice. Almost every website selling stuff or subscriptions use PayPal to manage its transactions.

While PayPal back-end allows users to fully manage their accounts, there are some features it still lacks.

Real world example: let’s say you are selling a digital good, such as the source code of your latest Flash game, or an ebook.

Since there is no shipment as the buyer will download it or receive it by email, he expects to get the book/game a few minutes after the payment.

That’s ok if you check your PayPal account every 10 minutes, manually sending emails to buyers, but once in a while you need to sleep… or have a shower… who will send your book then?

That’s why services like PayLoadz come into play, managing transactions and digital delivery for a monthly subscription and a per transition fee.

If you don’t want to use third part services, PayPal offers the Instant Payment Notification to automate your digital deliveries.

Instant Payment Notification (IPN) is PayPal’s message service that sends a notification when a transaction is affected. Once IPN is integrated, sellers can automate their back office so they don’t have to wait for payments to come in to trigger order fulfillment.

The process is simple: once you have a PayPal account, in your profile page click “Instant Payment Notification Preferences” under “Selling Preferences”, and you will be asked for an URL.

This is the URL of a page on your server which will act as a listener for PayPal payments.

Then, all you have to do is write your own listener based on the information you will find in the official docs. Wait, I forgot to tell you three things:

1) The script is wrong, it will give an error because there are missing curly brackets

2) The given address where to test the script is wrong, it’s not www.sandbox.paypal.com anymore

3) The script (once corrected) won’t work on every server since relies on fsockopen. In my opinion it would have been better to use cURL

So, this is the script I suggest to use:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
<?php
 
$request = "cmd=_notify-validate"; 
foreach ($_POST as $varname => $varvalue){
	$email .= "$varname: $varvalue\n";  
	if(function_exists('get_magic_quotes_gpc') and get_magic_quotes_gpc()){  
		$varvalue = urlencode(stripslashes($varvalue)); 
	}
	else { 
		$value = urlencode($value); 
	} 
	$request .= "&$varname=$varvalue"; 
} 
$ch = curl_init();
curl_setopt($ch,CURLOPT_URL,"https://www.sandbox.paypal.com/cgi-bin/webscr");
//curl_setopt($ch,CURLOPT_URL,"https://www.paypal.com");
curl_setopt($ch,CURLOPT_POST,true);
curl_setopt($ch,CURLOPT_POSTFIELDS,$request);
curl_setopt($ch,CURLOPT_FOLLOWLOCATION,false);
curl_setopt($ch,CURLOPT_RETURNTRANSFER,true);
$result = curl_exec($ch);
curl_close($ch);
switch($result){
	case "VERIFIED":
		// verified payment
		break;
	case "INVALID":
		// invalid/fake payment
		break;
	default:
		// any other case (such as no response, connection timeout...)
}
 
?>

Simply comment/uncomment lines 15-16 if you want to use it in sandbox or real mode.

Once the payment is VERIFIED, you can send the email with the game/book/activation code to the email address you will find in POST[payer_email] variable. You can find the complete list of passed variables at this page.

To test it, once you activated your IPN and installed the script on your web server, register as a PayPal developer, then test your IPN in the sandbox page.

In a few days, a fully working example on this site, with some deals at an extraordinary price.

Rate this post: 1 Star2 Stars3 Stars4 Stars5 Stars (6 votes, average: 4.67 out of 5)
Loading ... Loading ...
Be my fan on Facebook and follow me on Twitter! Exclusive content for my Facebook fans and Twitter followers

This post has 13 comments

  1. Ronny

    on September 29, 2011 at 4:46 pm

    Oh thats great thanks emanuel
    i learnt something new today :)
    keep up the great stuff:D

  2. ViolentAJ

    on September 30, 2011 at 2:33 pm

    I’ll have to bone up on my PHP. I don’t have a website right now, but I’m interested in getting the source to a game sold. I think that this will be very helpful. If I figure out a way to implement this in Flash, it might be helpful as well.

  3. Televisores Led

    on October 2, 2011 at 11:13 am

    Great. Very useful. I have to put me up to date with php

  4. Cierrovachi

    on October 7, 2011 at 3:02 am

    Hi, very nice and informative. Thanks.

    Can I ask you a question regarding (sandbox and) IPN.

    I’ve used the PHP script for IPN from their official site and then created Buy now button, connected them (ok, set ipn (enabled it before)) and tested the whole procedure.

    Tests have shown me some weird things;

    when i “buy” (in sandbox) the item it says that my payment is completed (only on the buyer side), then I log in to my sandbox merchant account and the money is not there.

    Then I check my IPN log (file on my server that checks all POSTs and writes them to a file for reference) and I see 13 exactly same messages from paypal, all including payment_status=Completed.

    But the sandbox money is still not on merchant’s account.

    I have figured it out how to make it work:
    when I buy (click on button pay now, login, click pay (then I am as a buyer redirected back to seller’s site), I have to login to my buyers account, go to last transaction (it has status completed, which is not really true) click on details and scroll to the bottom of details page and click confirm.

    Only then test payment is really made to merchant.

    I suppose this is only needed in Sandbox account?
    Do / did you have the same scenario or am I doing something wrong?

    I can of course go live with my script and ask a friend to pay with real money (and pay him back) but that would be the last option.

    My second concern is the following:

    1.) somebody registers on my site, buys my digital product (software or just access to the site) with paypal
    2.) uses / saves the access/sw
    3.) open an dispute with paypal and reclaim his money

    How to prevent this?
    How to prove paypal that you have provided the customer with what you’ ve promised?

  5. Emanuele Feronato

    on October 7, 2011 at 3:43 pm

    First, the confirm button is only active in the sandbox mode.

    Second, you can’t prevent people for downloading and then reclaiming their money.

    Anyway, this never happened to me, as of today.

  6. yoji

    on October 10, 2011 at 6:29 pm

    I’m implementing Paypal Express Checkout solution for digital goods.
    I started some tests : when a buyer clicks on the “Pay” button, I confirm the transaction, calling Paypal API and I get a response, Success or Failure. Then why would I need IPN ?
    The transaction success response is not enough to send the digital good ?

  7. Emanuele Feronato

    on October 10, 2011 at 6:57 pm

    Sure, it’s enough, but you might want to automate digital good delivery, and store buyers data somewhere to have some kind of statistics.

  8. yoji

    on October 11, 2011 at 11:10 am

    The php script which processes the payment can automatically deliver digital good and store data when the success response is received. Tell me if I’m wrong, but as this success response seems reliable, then we don’t need IPN.

    I only see IPN would be usefull for recurrent payment : I get a success response only when I process one payment but if it is a recurrent payment, I would use IPN to automatically deliver the digital good every time the payment is completed.

  9. Steve

    on October 13, 2011 at 10:50 pm

    For the wishlist:
    It would be great to have a detailed tutorial on paypal subscriptions!

  10. Iggy

    on October 25, 2011 at 10:52 am

    Hey Emanuele,

    thanks for the code!

    I still have a challenge while putting this to work, and maybe you could help me out. How would I impelement a personal link with an expiration date for each buyer? For me, that’s the whole point in implemeting IPN (otherwise, I would just let the buyer download from the link after the sucessful payment included the “buy now” button set up).

    Thx!

    Iggy

  11. Emanuele Feronato

    on October 25, 2011 at 6:19 pm

    Sure you can Iggy, you will need a mysql database to store payer information as well as payment timestamp.

    You will mail the payer a link with an ID, and before letting him download anything, just check the timestamp.

  12. disco duro externo barato

    on November 24, 2011 at 7:12 pm

    Oh! thats great, thanks emanuel. Its Very useful!

  13. gtraxx

    on February 15, 2012 at 1:36 am

    Hello, you would not have a sample form to use your example?
    I try to create a form that sends data to paypal, then inserted into the database on the status of payment.
    Sorry for my english, i speak french :)