0
votes

I am trying to capture the data being posted back from PayPal to an IPN script. In my button I do have the notify_url set properly as well as the rm value of 2 (for posting data back). I am using the _xclick command (cmd=_xclick) as well in the button.

In my following code, I have written periodically, the data or flow to the error log to catch what is happening. But it seems like PayPal is pushing to the IPN but no data is being caught (or at least properly).

Here's my entire IPN script at the moment:

        // STEP 1: read POST data

            // Reading POSTed data directly from $_POST causes serialization issues with array data in the POST.
            // Instead, read raw POST data from the input stream. 

            $raw_post_data = file_get_contents('php://input');


            error_log("Got " . $raw_post_data . " when processing IPN data");
            error_log("-------------------\n");

            $raw_post_array = explode('&', $raw_post_data);
            $myPost = array();
            foreach ($raw_post_array as $keyval) {
              $keyval = explode ('=', $keyval);
              if (count($keyval) == 2)
                 $myPost[$keyval[0]] = urldecode($keyval[1]);
            }


            // read the IPN message sent from PayPal and prepend 'cmd=_notify-validate'
            $req = 'cmd=_notify-validate';
            if(function_exists('get_magic_quotes_gpc')) {
               $get_magic_quotes_exists = true;
            } 


            foreach ($myPost as $key => $value) {        
               if($get_magic_quotes_exists == true && get_magic_quotes_gpc() == 1) { 
                    $value = urlencode(stripslashes($value)); 
               } else {
                    $value = urlencode($value);
               }
               $req .= "&$key=$value";
            }


             error_log("Got response: " . $req . " when processing IPN data");
             error_log("-------------------\n");

            // STEP 2: POST IPN data back to PayPal to validate

            $ch = curl_init('https://www.paypal.com/cgi-bin/webscr');
            curl_setopt($ch, CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_1_1);
            curl_setopt($ch, CURLOPT_POST, 1);
            curl_setopt($ch, CURLOPT_RETURNTRANSFER,1);
            curl_setopt($ch, CURLOPT_POSTFIELDS, $req);
            curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, 1);
            curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, 2);
            curl_setopt($ch, CURLOPT_FORBID_REUSE, 1);
            curl_setopt($ch, CURLOPT_HTTPHEADER, array('Connection: Close'));
            $res = curl_exec($ch);

             error_log("Got response: " . $res . " when processing IPN VALIDATE");
             error_log("-------------------\n");



            if( !($res) ) {
                error_log("Got " . curl_error($ch) . " when processing IPN Validation");
                curl_close($ch);
                exit;
            }

            curl_close($ch);


             error_log("Got response: " . $res . " when processing IPN data");
             error_log("-------------------\n");

            // STEP 3: Inspect IPN validation result and act accordingly

            if (strcmp (trim($res), "VERIFIED") == 0) {
                // The IPN is verified, process it:
                // check whether 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 the notification

                // assign posted variables to local variables
                $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'];

                // IPN message values depend upon the type of notification sent.
                // To loop through the &_POST array and print the NV pairs to the screen:

                foreach($_POST as $key => $value) {
                  //echo $key." = ". $value."<br>";
                  error_log($key." = ". $value."\n");
                }
            } else if (strcmp ($res, "INVALID") == 0) {
                // IPN invalid, log for manual investigation
                $t =  "The response from IPN was: <b>" .$res ."</b>";
                 error_log($t."\n");
            }

The results to capture the data is that the IPN responds with INVALID.

I am not sure what I am missing here. It seems like the file_get_contents('php://input') isn't capturing any data at all. Is there a better way to capture the input data rather than using file_get_contents('php://input') or using the $_POST variable?

Any other insight is appreciated. Thank you.

1

1 Answers

0
votes

try to change the Step 1 by following code:

 // Prepare data that will sent to Paypal for verification
$req = "cmd=_notify-validate";
foreach ($_POST as $key => $value) {
    $value = urlencode(stripslashes($value));
    $req .= "&$key=$value";
    $content = "&$key=$value";
}

Note: you can use sandbox website for developer of paypal to test your ipn listner then you should change the line

$ch = curl_init('https://www.paypal.com/cgi-bin/webscr');

by

$ch = curl_init('https://www.sandbox.paypal.com/cgi-bin/webscr');

hope this will hepl,