How to Use Custom Variables with PayPal Instant Payment Notification (IPN)

Ever wondered how you can get a record of PayPal transactions as they happen in real-time and store them in a database? What about passing along custom variables to the PayPal form, and then catching them after the payment has been completed - such as for a referral system?

I can help you with that. I was asked to help develop a system for the '800 Miles to End Polio Now' program where we could track which groups (Rotary Clubs) generated donations to the project. We also had other tracking and reporting requirements around groups of clubs, T-Shirt sizes and so on. In addition, I wanted to be able to create a referral system where once someone had registered for the fundraiser, they could refer people to donate under them and receive credit for their referrals.

To get started, you should familiarize yourself with PayPal's Instant Payment Notification system (IPN). First thing, you're going to want to edit your PayPal button's form code to include your custom variable. You can name it whatever you like, but I just named it 'custom' for simplicities sake.


<input type="hidden" name="item_name_1" value="Registration(Large)" />
<input type="hidden" name="amount_1" value='15' />
<input type="hidden" name="quantity_1" value="1" />
<input type='hidden' name='item_number' value='' />
<input type="hidden" name="shipping_1" value='0.00' />
<input type="image" src="http://domain.com/images/paypal_checkout_EN.png"
     name="submit" class="wp_cart_checkout_button"
     alt="Make payments with PayPal - it\'s fast, free and secure!" />
<input type="hidden" name="return" value="http://domain.com" />
<input type="hidden" name="business" value="email@domain.com" />
<input type="hidden" name="currency_code" value="USD" />
<!-- Custom variable here: -->
<input type="hidden" name="custom" value="referrer=1234&size=L">
<input type="hidden" name="cmd" value="_cart" />
<input type="hidden" name="upload" value="1" />
<input type="hidden" name="rm" value="2" />
<input type="hidden" name="mrb" value="ABC2343FGBM234" />

 

Next, you want to set up your IPN listener script in the PayPal admin. This is under 'My Account', 'Profile', 'My Selling Tools'. Click on 'Update' next to 'Instant Payment Notification'. This form allows you to tell PayPal the location of the listener script on your website. Now let's crack open that listener script and see what it does:


<?php

// paypal is going to send a large post to the url we specified in the admin.
// read the post from PayPal system, turn it into a query url,
// and add the 'cmd' validate value to post it back to PayPal.
// this step ensures that the information we received from PayPal is
// legitimate.
$req = 'cmd=_notify-validate';

foreach (
$_POST as $key => $value) {
 
$value = urlencode(stripslashes($value));
  
$req .= "&$key=$value";
}

// post back to PayPal system for validation
$header .= "POST /cgi-bin/webscr HTTP/1.0\r\n";
$header .= "Content-Type: application/x-www-form-urlencoded\r\n";
$header .= "Content-Length: " . strlen($req) . "\r\n\r\n";

$fp = fsockopen('ssl://www.paypal.com', 443, $errno, $errstr, 30);

// turn the original post data into an object we can work with
$txn = (object) $_POST;

if (!
$fp) {
 
log_error('HTTP CONNECTION ERROR', $_POST);
} else {   
 
fputs($fp, $header . $req);
  while (!
feof($fp)) {
   
$res = fgets($fp, 1024);
         
   
// proceed if transaction is verified
   
if (strcmp ($res, "VERIFIED") == 0) {
     
// Do some simple error checks:
      // check if the payment_status is Completed
     
if ($txn->payment_status != 'Completed') {
       
log_error('NOT COMPLETED', $txn);
        exit;
      }
     
// check that receiver_email is your Primary PayPal email
     
if ( $txn->receiver_email != RECEIVER_EMAIL ) {
       
log_error('INVALID RECEIVER EMAIL', $txn);
        exit;
      }
     
// check that txn_id has not been previously processed
     
if ( check_existing_transaction($txn) ) {
       
log_error('ALREADY PROCESSED', $txn);
        exit;
      }
             
     
// Here's where the 'custom' magic happens. Use parse_str
      // to take the still url encoded custom str and turn it
      // into an array we can work with
     
$custom = array();
     
parse_str($txn->custom, $custom);
             
     
// Now we can do things with the $txn and $custom array
      // like add a database record for the user/transaction,
      // send a response email, etc.
   
}   
    else if (
strcmp ($res, "INVALID") == 0) {
     
log_error('TRANSACTION INVALID', $txn);
    }
  }
}

fclose ($fp);
exit;
?>

 

If you've ever worked with affiliate programs before, you know how powerful tracking custom variables on a transaction can be. For the '800 Miles' program - I created a system where people who registered to participate in the program could post a link on their Facebook, Twitter, etc - where friends could click through and the donate on behalf of the original participant. Pretty powerful stuff. Let me know what you're able to come up with on your project!

Add new comment

Filtered HTML

  • Web page addresses and e-mail addresses turn into links automatically.
  • Allowed HTML tags: <a> <em> <strong> <cite> <blockquote> <code> <ul> <ol> <li> <dl> <dt> <dd>
  • Lines and paragraphs break automatically.

Plain text

  • No HTML tags allowed.
  • Web page addresses and e-mail addresses turn into links automatically.
  • Lines and paragraphs break automatically.
CAPTCHA
This question is for testing whether or not you are a human visitor and to prevent automated spam submissions.
Image CAPTCHA
Enter the characters shown in the image.
glqxz9283 sfy39587stf02 mnesdcuix8
sfy39587stf03
sfy39587stf04