Recent PayPal IPN Issues: Postmortem

  • Jacob@DPD
  • December 8, 2010
  • 1 Comment

Instant Payment Notifications (IPNs) are key to how DPD processes and validates PayPal orders. We receive an IPN for each successful purchase that triggers an email and activates the buyer’s purchase. To make sure we are receiving an actual IPN from PayPal to prevent unauthorized download, DPD contacts and verifies each IPN with PayPal. We either get a VALID or INVALID response.

In the past week or so we noticed a spike in failed IPN verifications from PayPal due to the continued rollout of PayPal’s new site. These sort of breakages aren’t uncommon with PayPal and they’re reasonably quick to address these types of issues. We normally don’t have to make any changes on our end before PayPal rolls out a fix. This time was different- There was no fix or even mention of the issue on PayPal’s site and failed IPN verifications were piling up.

So we dug into the logs and figured out what changed. Yesterday we rolled out changes to address the problem. We’re happy to report that we are now seeing a 100% success rate in validating IPNs.

If you are seeing new purchases with the “Error” status, this is most likely caused by an incompatable character encoding in your PayPal account profile having trouble with names and addresses with special characters in them. Please take a moment to enable UTF-8 (item #5) in your PayPal account. This fixes 99% of the remaining IPN validation errors.

What follows is a technical analysis of what happened and how we fixed it. We are posting this in hopes of helping other PayPal developers.

Geeky Programmer Stuff Below…

(Code samples are in PHP.)

The first problem is with generating the validation params. In every IPN validation sample out there, including on PayPal’s own site, you will see the following code to build the validation request:

$req = 'cmd=_notify-validate';

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

There are two things wrong with this snippet. First, PayPal sometimes sends three extra parameters. The most important of those is the cmd parameter. This causes the validation command to switch from _notify-validate to whatever PayPal includes in their IPN and PayPal responds with a 400 Bad Request error. The CONTEXT, myAllTextSubmitID, and form_charset parameters do not have any effect on validation. Adding a unset($params['cmd']); before the foreach fixes the problem.

Secondly, the call to stripslashes is not needed. PayPal likes for you to send back the string exactly as they sent it to you, and they send strings with slashes included. Go figure.

The fixed validation request builder looks like:

$req = 'cmd=_notify-validate';

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

Responses (1) / Trackbacks (0)

    by Mike Mooney
    Aug 21st, 2011


    Holy mackeral, thank you. The “cmd” parameter was indeed my problem, and that would have taken forever for my to resolve.

Leave a Response

This site uses Akismet to reduce spam. Learn how your comment data is processed.