Sunday, January 6, 2013

Disabled PayPal IPN when using Magento and eBay

The Problem

If you use the same PayPal account to collect payment for multiple stores (Magento, eBay, etc...), you may encounter an issue in which IPN is constantly being disabled on the PayPal side.  If you're struggling with this, the following may help.

Here's what's happening:  You've setup your PayPal "Notification URL" to point to Magento's IPN listener (https://{mydomain.com}/paypal/ipn (or something to that affect)).  The other storefront (like eBay) uses this same Notification URL you setup in PayPal.  So, with the Notification URL pointing to   https://{mydomain.com}/paypal/ipn specifically for Magento, when you get an order from your eBay store, PayPal tries to send an IPN message to your Magento listener.  Magento doesn't know what to do with it since the order didn't originate here so an error message is sent back to PayPal.  After a handful of these, PayPal disables IPN for your account.

The Solution

Magento sends the "Notification URL" to PayPal and that overrides whatever has been setup in your PayPal settings, so nothing to do as far as Magento goes.  What we need to do is to create another "listener" for the other store... this one will be a null/void listener, but will send a "success" message back to PayPal when called.  We'll set the "Notification URL" in PayPal to point to this null listener.  As stated before, Nofication URLs are baked into Magento requests and this null Notification URL will be ignored for all Magento IPNs and that'll hum along just fine.

  1. Over at paypaltech.com, there's a utility that will create a IPN listener script.  Go to https://www.paypaltech.com/SG2/ and copy the generated file (UPDATE: file has been removed.  See below.  Copy everything between the <-start-> and <-end-> in order to create your null_ipn.php file).  Paste this text into a file named null_ipn.php in the root of your Magento web folder.  
  2. Go to PayPal and log in.  Next, select "My Account" on the tab.  Next, navigate to profile->My Selling Tools->Instant Payment Notifications->Edit Settings.  For the "Notification URL", use the file that you just created (http://{yourdomain.com}/null_ipn.php

That's it.  IPNs received by Magento will be posted to your Magento orders and IPNs received by the null listener will send back a success message to PayPal.  No more disabled IPN every few days.

Note:  there are other ways to deal with these stray IPN notifications if you're so inclined... check them out at https://www.paypaltech.com/SG2/


I hope this helps,

webmaster, All American Hats

<--------------start null_ipn.php ------------------>

<?php

// Revision Notes
// 11/04/11 - changed post back url from https://www.paypal.com/cgi-bin/webscr to https://ipnpb.paypal.com/cgi-bin/webscr
// For more info see below:
// https://www.x.com/content/bulletin-ip-address-expansion-paypal-services
// "ACTION REQUIRED: if you are using IPN (Instant Payment Notification) for Order Management and your IPN listener script is behind a firewall that uses ACL (Access Control List) rules which restrict outbound traffic to a limited number of IP addresses, then you may need to do one of the following:
// To continue posting back to https://www.paypal.com  to perform IPN validation you will need to update your firewall ACL to allow outbound access to *any* IP address for the servers that host your IPN script
// OR Alternatively, you will need to modify  your IPN script to post back IPNs to the newly created URL https://ipnpb.paypal.com using HTTPS (port 443) and update firewall ACL rules to allow outbound access to the ipnpb.paypal.com IP ranges (see end of message)."


// read the post from PayPal system and add 'cmd'
$req = 'cmd=_notify-validate';

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

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

  //If testing on Sandbox use:
//$fp = fsockopen ('ssl://www.sandbox.paypal.com', 443, $errno, $errstr, 30);
$fp = fsockopen ('ssl://ipnpb.paypal.com', 443, $errno, $errstr, 30);


if (!$fp) {
// HTTP ERROR
} else {
fputs ($fp, $header . $req);
while (!feof($fp)) {
$res = fgets ($fp, 1024);
if (strcmp ($res, "VERIFIED") == 0) {
// check the payment_status is Completed
// check that txn_id has not been previously processed
// check that receiver_email is your Primary PayPal email
// check that payment_amount/payment_currency are correct
// process payment


// echo the response
echo "The response from IPN was: <b>" .$res ."</b><br><br>";

//loop through the $_POST array and print all vars to the screen.

foreach($_POST as $key => $value){

        echo $key." = ". $value."<br>";



}


}
else if (strcmp ($res, "INVALID") == 0) {
// log for manual investigation

// echo the response
echo "The response from IPN was: <b>" .$res ."</b>";

  }

}
fclose ($fp);
}
?>

<----------------end null_ipn.php ----------------->

Using a Wishlist to Build Your Magento Newsletter Template

Building a Magento Newsletter using a Wishlist

With Magento you can build newsletters using straight up HTML.  It's a very nice feature but building out a nice newsletter with enticing product images and "buy now" links can be tedious to do by hand. Here's an easy way to get a good template that has a grid of products with customer convenience hyperlinks.

The Wishlist

Any customer can create a list of all of their favorite products using the wishlist functionality built into Magento. The wishlist "send to" functionality sends a copy of a very nicely-formatted product ad of the wishlist to an your e-mail account... full HTML.

  1. Login to the Magento store frontend and add the products you'd like in your newsletter to your wishlist.
  2. Click the "Share Wishlist" in order to send to your email address.
  3. If you use something like sendgrid or mailchimp as your outgoing SMTP service, you're going to get a lot of injected redirects into your HTML.  You'll need an alternate way of getting the email to yourself. I temporarily disabled the awesome plugin from aschroder.com that sends out SMTP/gmail. After disabling, the email was sent from my web server instead and was clean. 

Getting the HTML from the Wishlist email to your newsletter


  1. In your email client, locate the wishlist email and view source (In gmail that's called "show original" and is available from the drop-down menu).  Select all of the HTML in the email and copy to the clipboard.
  2. Some e-mail clients such as gmail insert funny characters into the HTML.  If you notice a lot of "=0A" or "=3D" in the HTML you copied, go to http://www.convertstring.com/EncodeDecode/QuotedPrintableDecode in order to "decode".  Once decoded, you'll want to copy the converted text to the clipboard.

Creating the Newlsetter


  1. Just paste the HTML into your Magento newsletter template.  Adjust and beautify as needed.

I hope this helps!
Webmaster, All American Hats