Search code examples
phppaypal-ipn

Paypal IPN failure


I have set up Paypal account notification url to go to this script:

    // Read the notification from PayPal which comes in the form of a POST array and create the acknowledgement response
    $req = 'cmd=_notify-validate';               // add 'cmd' to beginning of the acknowledgement you send back to PayPal

    foreach ($_POST as $key => $value) 
    { // Loop through the notification NV pairs
    $value = urlencode(stripslashes($value));  // Encode the values
    $req .= "&$key=$value";                    // Add the NV pairs to the acknowledgement
    }


    // Assign the paypal payment notification values to local variables
    if($_POST){
    $item_name = $_POST['item_name'];
    $item_number = $_POST['item_number'];
    $payment_status = $_POST['payment_status'];
    $payment_amount = $_POST['mc_gross'];
    $payment_currency = $_POST['mc_currency'];
    $txn_id = $_POST['txn_id'];
    $receiver_email = $_POST['receiver_email'];
    $payer_email = $_POST['payer_email'];}

    //Set up the acknowledgement request headers (this is the updated version for http 1.1)
    $header .= "POST /cgi-bin/webscr HTTP/1.1\r\n";
    $header .= "Content-Type: application/x-www-form-urlencoded\r\n";
    $header .= "Host: www.paypal.com\r\n";
    $header .= "Connection: close\r\n";
    $header .= "Content-Length: " . strlen($req) . "\r\n\r\n";
    //Open a socket for the acknowledgement request
    $fp = fsockopen ('www.paypal.com', 80, $errno, $errstr, 30);

    if(!$fp){
        echo "HTTP ERROR";
    }
    else
    {//start 1

    // Post request back to PayPal for validation
    fputs ($fp, $header . $req);

    //once paypal receives the acknowledgement response, another message will be send containing the single word VERIFIED or INVALID

    while (!feof($fp)) 
        { //start 2, while not EndOfFile
    $res = fgets ($fp, 1024); // Get the acknowledgement response
    $res = trim($res);
        if (strcmp ($res, "VERIFIED") == 0) 
            {// start 3, Response is OK

            if ($payment_status == "Completed")
                {//start 4

                //send email announcing success

                $from = "Rupert Heath Literary Agency";
                $to = $payer_email;
                $subject = "Ebook";
                $body = "It works";
                mail($to, $subject, $body, $from);

                }//end 4
            }//end 3
            else if(strcmp ($res, "INVALID") == 0)
                {//start 5

                //send email announcing failure
                //$error_log .= 'Line 57'

                $from = "Guide Test Page";
                $to = $payer_email;
                $subject = "INVALID IPN";
                $body = "Doesn't work";
                mail($to, $subject, $body, $from);
                }//end 5


    } //end 2
fclose ($fp);  //close file pointer
} //end 1

Which is based on a number of web-hosted examples and caters for the upgrade to HTTP 1.1

The script, as a test, sends either a success or a failure email depending on either a VERIFIED or INVALID response from Paypal. Problem is I always get an INVALID email and can't understand why. I have looked at the Paypal IPN History and the HTTP response code is 200 which seems to indicate that the IPN exchange worked correctly so maybe Paypal is responding VERIFIED but my script has an error.

The IPN history details are:

Instant Payment Notification (IPN) details

Message ID69025489S2598613V

Date/time created18/07/2013 23:22 PDT

Original/Resent Original

Latest delivery attempt date/time 18/07/2013 23:22 PDT

Notification URL http://www.rupertheath.com/ipn/ipn_script

HTTP response code 200

Delivery status Sent

No. of retries 0

Transaction ID4D0877596N038120Y

IPN typeTransaction made

IPN Message mc_gross=0.01&protection_eligibility=Eligible&address_status=confirmed&payer_id=C3USV8A4Q2QDW&tax=0.00&address_street=Ramsey House 34 Fowlers Road&payment_date=23:22:44 Jul 18, 2013 PDT&payment_status=Completed&charset=windows-1252&address_zip=SP1 2QU&first_name=Michael&mc_fee=0.01&address_country_code=GB&address_name=Michael Heath&notify_version=3.7&custom=&payer_status=verified&[email protected]&address_country=United Kingdom&address_city=Salisbury&quantity=1&verify_sign=AhKyCHsfiy2frgZNNoQmGHQ3LhKMAboweJqZzYCdqp30Hb7b99tF.04a&[email protected]&txn_id=4D0877596N038120Y&payment_type=instant&last_name=Heath&address_state=Wiltshire&[email protected]&payment_fee=&receiver_id=BRM2TYMP4ACZ8&txn_type=web_accept&item_name=Ebook&mc_currency=GBP&item_number=&residence_country=GB&handling_amount=0.00&transaction_subject=Ebook&payment_gross=&shipping=0.00&ipn_track_id=b0a3b4ae3c51c

Can anyone help me debug this problem?


Solution

  • It could very well be an issue with this line:

    $value = urlencode(stripslashes($value));
    

    Specifically, using stripslashes there. You only need to include stripslashes if your PHP configuration has (god help you) Magic Quotes on. Thankfully, Magic Quotes has been removed as of PHP 5.4, so you can probably safely remove stripslashes from that line, making it:

    $value = urlencode($value);
    

    Believe it or not, Paypal allows user data to contain backslashes. So if the IPN has any backslashes, and you remove them with stripslashes, when you post IPN data back to PayPal for validation Paypal will give you the INVALID response, since the data will not match.