PayPal Instant Payment Notification with PHP

Hi there! Today we are going to combine Paypal with PHP to allow for the easy processing of payments on your website.

cdl_capture_2011-03-22-44_ 000



Finished Product: Preview
Step 1 – Creating a PayPal Account

For this tutorial you will need a Premier PayPal Account and an online website. Begin by going and click “signup” at the top of the page.

Step 1

Click Get Started under the Premier Title; you will be redirected to a signup form. Please fill in all necessary information. When your account has been created, login and move on to step 2.

Step 2 – Enable IPN

In this step we are going to enable Instant Payment Notification (IPN), so while logged in, please clickProfile and then choose Instant Payment Notification

Step 2

Now on the next screen you will see that IPN is set to “off”; click “Edit” to change that.

At the start of this tutorial, I mentioned that you would need an online website. Why? Well we are going to ask PayPal to send us data when a payment is complete. PayPal can’t reach local hosted websites unless you have all settings configured correctly. (This involves opening ports on your router). So, I’ll enter the url to my validation script for example PayPal will then post a notification to my server, at the URL I’ve specified.

Step 3 – Building a Simple HTML Page

Okay, now we need a simple and basic html page where your visitor can buy access to your download area.
I’m not going to explain all the HTML because i think you should know the basics of HTML before you start with PHP.

index.php – A simple HTML page with a stylesheet.

  1. <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN""">
  2. <html xmlns="">
  3. <head>
  4. <title> | Purchase access to download area</title>
  5. <link rel="stylesheet" type="text/css" media="All" href="css/style.css" />
  6. </head>
  7. <body>
  8. <div id="wrap">
  9. <h3>Purchase Access</h3>
  10. <p>Please click the button below to receive login details for the download area. <br />
  11.            Already have an account? <a href="login.php">Login</a> here.</p>
  12. <!– Paste your PayPal button code here (That you will get in the next step) –>
  13. </div>
  14. </body>
  15. </html>

css/style.css – A simple stylesheet for our HTML Page.


  1. body{ 
  2. background: #2D2D2D; /* Set Website Background Color */
  3. font: 11px ‘Verdana’; /* Set Website Font Size & Font Type */
  4. #wrap{ 
  5. margin: 0 auto; /* Center Our Content */
  6. width: 500px; /* Set The Width For Our Content */
  7. background: #FFF; /* Set Content Background Color */
  8. padding: 10px; /* Set Padding For Content */
  9. border: 1px solid #000; /* Add A Border Around The Content */

step 3

Step 4 – Building a PayPal Button

We need to create a purchase button, so please click Merchant Services, and then chooseWebsite Payments Standard

You may choose three types of buttons, Sell single items, Sell multiple items and, Subscription. Now in this tutorial we are going to create a single item. When someone purchases this single item, in this case access to a download area. Once the payment has been validated, an email will be sent with there details.

Step 4

Let’s enter some information for our purchase button; you may leave the rest as it is.

Step 4 Settings

When you have finished filling in each section, generate the code. Copy this code to your clipboard, and then paste it insideindex.php – where I added the comment in the html page. Please review step 3, if needed.

This should work perfectly. Users can click the button and complete their purchase.

Step 5 – Writing ipn.php

First, create ipn.php so we can start writing. We’ll use a small snippet that I made from a larger snippet that you can get from Paypal’s website.
Please note that there is no reason to learn this code out of your head! Snippets are handy and save time. I will break it down below.


  1. <?php 
  2. mysql_connect("localhost", "user", "password") or die(mysql_error()); 
  3. mysql_select_db("PayPal") or die(mysql_error()); 
  4. // read the post from PayPal system and add ‘cmd’
  5. $req = ‘cmd=_notify-validate’; 
  6. foreach ($_POST as $key => $value) { 
  7. $value = urlencode(stripslashes($value)); 
  8. $req .= "&$key=$value"; 
  9. // post back to PayPal system to validate
  10. $header = "POST /cgi-bin/webscr HTTP/1.0\r\n"; 
  11. $header .= "Content-Type: application/x-www-form-urlencoded\r\n"; 
  12. $header .= "Content-Length: " . strlen($req) . "\r\n\r\n"; 
  13. $fp = fsockopen (‘ssl://’, 443, $errno, $errstr, 30); 
  14. if (!$fp) { 
  15. // HTTP ERROR
  16. } else { 
  17. fputs ($fp, $header . $req); 
  18. while (!feof($fp)) { 
  19. $res = fgets ($fp, 1024); 
  20. if (strcmp ($res, "VERIFIED") == 0) { 
  22. else if (strcmp ($res, "INVALID") == 0) { 
  24. fclose ($fp); 
  25. ?> 

Please fill in the correct credentials for your database so we can insert data in the next step.

PayPal POSTS data to the url we specified. In this example we only need the email address from the buyer, so that we may send him his login information. This code above will read the data PayPal sends and return the info to PayPal. I’ve added two comments where the code should come if its validated. Additionally, I’ve also added a comment that specifies what should be done if it’s not validated.

Step 6 – Creating the Database

Now we are going to focus on what should happen if the payment is verified. First, we need to build a MySQL table where we store the users information. Just a simple one with an id, email and password field.

Next, we must enter our table details; we need an ID with a primary key selection and it should auto increment; next an email and password field.

For those of you don’t have the time to enter all of this information, below is a small MySQL Dump code to recreate the table.

CREATE TABLE `users` (
  `id` int(10) NOT NULL auto_increment,
  `email` varchar(50) NOT NULL,
  `password` varchar(32) NOT NULL,
  PRIMARY KEY  (`id`)
Step 7 – Account Creation

Open ipn.php again. We are going to write the following code below the “// PAYMET VALIDATED” line.

Our first step is to retrieve the email address of the buyer; PayPal sends all of this info over to ipn.php.


  2. $email = $_POST[‘payer_email’]; 

We must create one last variable – which is the password that we will generate using php.


  2. $email = $_POST[‘payer_email’]; 
  3. $password = mt_rand(1000, 9999); 

As you can see, we used mt_rand to generate a random password – in this case a numeric value between 1000 and 9999. Next, we need to insert this data into our database. To do so, we’ll use the mysql insert query.


  2. $email = $_POST[‘payer_email’]; 
  3. $password = mt_rand(1000, 9999); 
  4. mysql_query("INSERT INTO users (email, password) VALUES(‘". mysql_escape_string($email) ."’, ‘".md5($password)."’ ) ") or die(mysql_error()); 

Here we tell our script to insert the email and the password into our database. I’ve added a mysql_escape_string to ensure that mysql injection isn’t possible. I’ve also added the md5 function to our password so that it will be stored as a 32-character hash. Now the account is created; let’s move on to the next step.

Step 8 – Emailing the Login Credentials

We need to write some code that will email the login information to the buyer. To accomplish this, we will use the php mail function.


  2. $email = $_POST[‘payer_email’]; 
  3. $password = mt_rand(1000, 9999); 
  4. mysql_query("INSERT INTO users (email, password) VALUES(‘". mysql_escape_string($email) ."’, ‘".md5($password)."’ ) ") or die(mysql_error()); 
  5. $to      = $email; 
  6. $subject = ‘Download Area | Login Credentials’; 
  7. $message = ‘
  8. Thank you for your purchase
  9. Your account information
  10. ————————-
  11. Email: ‘.$email.’
  12. Password: ‘.$password.’
  13. ————————-
  14. You can now login at’; 
  15. $headers = ‘’ . "\r\n"; 
  16. mail($to, $subject, $message, $headers); 

Let’s break this email function down. We use the variable $email to get the user’s email address and assign it to the $to variable.

The variable $subject is the title/subject that you will see in your email program. After this, we have our message, which will contain a thank you note as well as the account information. The $email and $password variables in the message will change to the correct information once the email has been sent. We also have set a custom header. When the user receives the email, the “from” address will display as “”.

Step 9 – Invalid Payment Email

An invalid payment might occur because of fraud, but also because of a problem with PayPal; so we want to make sure that our customer gets what he paid for.

So we are going to send an email to our site administrator, telling him to contact the buyer for more information. Simply copy the email code we used before and then make the changes listed below.


  2. $to      = ‘’; 
  3. $subject = ‘Download Area | Invalid Payment’; 
  4. $message = ‘
  5. Dear Administrator,
  6. A payment has been made but is flagged as INVALID.
  7. Please verify the payment manualy and contact the buyer.
  8. Buyer Email: ‘.$email.’
  9. ‘; 
  10. $headers = ‘’ . "\r\n"; 
  11. mail($to, $subject, $message, $headers); 

This code is nearly the same as above, only we made some changes to the receiver, subject and message.

Step 10 – User Login

This is our final step, where we build a simple login form for our buyers. Make a new php file, and name itlogin.php. We’ll use the same HTML page as used for the index.php, only we will make some adjustments to the content of the page, and of course add a bit of styling to our login form.

login.php – This is the page where our buyers can login.


  1. <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN""">
  2. <html xmlns="">
  3. <head>
  4. <title> | Login</title>
  5. <link rel="stylesheet" type="text/css" media="All" href="css/style.css" />
  6. </head>
  7. <body>
  8. <div id="wrap">
  9. <h3>Login</h3>
  10. <p>Please enter your login credentials to get access to the download area</p>
  11. <form method="post" action="" >
  12. <fieldset>
  13. <label for="email">Email:</label><input type="text" name="email" value="" />
  14. <label for="password">Password:</label><input type="text" name="password" value="" />
  15. <input type="submit" value="Login" />
  16. </fieldset>
  17. </form>
  18. </div>
  19. </body>
  20. </html>

Add to style.css


  1. label{ 
  2. display: block; /* Make sure the label is on a single line */
  3. margin: 3px; /* Create some distance away from the input fields */
  4. input{ 
  5. padding: 3px; /* Give the text some more space */
  6. border: 1px solid gray; /* Add a border around the input fields */
  7. margin: 3px; /* Create some distance away from the labels */

Now that we’ve made our form, we need to check if the login credentials are correct. I made a few changes to login.php so we can get started:


  1. <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"""> 
  2. <html xmlns=""> 
  3. <head> 
  4. <title> | Login</title> 
  5. <link rel="stylesheet" type="text/css" media="All" href="css/style.css" /> 
  6. </head> 
  7. <body> 
  8.     <div id="wrap"> 
  9.         <?php  
  10.         mysql_connect("localhost", "paypalUser", "test123") or die(mysql_error()); 
  11.                 mysql_select_db("PayPal") or die(mysql_error()); 
  12. if(isset($_POST[’email’]) && isset($_POST[‘password’])){ 
  13. // Verify
  14.         }else{ 
  15.         ?> 
  16.         <h3>Login</h3> 
  17.         <p>Please enter your login credentials to get access to the download area</p> 
  18.         <form method="post" action="" > 
  19.             <fieldset> 
  20.                 <label for="email">Email:</label><input type="text" name="email" value="" /> 
  21.                 <label for="password">Password:</label><input type="text" name="password" value="" /> 
  22.                 <input type="submit" value="Login" /> 
  23.             </fieldset> 
  24.         </form> 
  25.         <?php 
  26.         } 
  27.         ?> 
  28.     </div> 
  29. </body> 
  30. </html> 

The code above will check if email and password are both posted. If true, we can verify the credentials. If not, we return a error. The next code we are going to write will be placed below “// Verify”. First we need to turn the post variables into local variables.


  1. $email = mysql_escape_string($_POST[’email’]); 
  2. $password = md5($_POST[‘password’]); 

I’ve added an escape function to prevent mysql injection and have transformed the posted password into a md5 hash. Because we did this in our database, we must also hash the user’s password to compare the two values correctly. Now it’s time to verify the data.


  1. $email = mysql_escape_string($_POST[’email’]); 
  2. $password = md5($_POST[‘password’]); 
  3. $gUser = mysql_query("SELECT * FROM users WHERE email=’".$email."’ AND password=’".$password."’ LIMIT 1") or die(mysql_error()); 
  4. $verify = mysql_num_rows($gUser); 
  5. if($verify > 0){ 
  6. echo ‘<h3>Login Complete</h3>
  7.           <p>Click here to download our program</p>’; 
  8. }else{ 
  9. echo ‘<h3>Login Failed</h3>
  10.           <p>Sorry your login credentials are incorrect.’; 

As you can see, we are running a mysql query, and are selecting all the data from our user table – but only the row where the user’s email address matches the one from the database.

mysql_num_rows checks if a match has been found: 1 = true; 0 = false.

Leave a comment