PayPal IPN Listener works inside sandbox but not outside

355 views Asked by At

I am running this PayPal IPN listener written by tutsplus, it's modified a bit to suit my needs. Everything worked fine until I have moved from sandbox to live mode. I have went over the code, and don't quite understand if I need to switch anything or it is checking for sandbox/live itself.

<?php
class PayPal_IPN{
function infotuts_ipn($im_debut_ipn) {

        define('SSL_P_URL', 'https://www.paypal.com/cgi-bin/webscr');
        define('SSL_SAND_URL', 'https://www.sandbox.paypal.com/cgi-bin/webscr');
        $hostname = gethostbyaddr($_SERVER['REMOTE_ADDR']);
        if (!preg_match('/paypal\.com$/', $hostname)) {
            $ipn_status = 'Validation post isn\'t from PayPal';
            if ($im_debut_ipn == true) {
                // mail test
            }

            return false;
        }

      // parse the paypal URL
        $paypal_url = ($_REQUEST['test_ipn'] == 1) ? SSL_SAND_URL : SSL_P_URL;
        $url_parsed = parse_url($paypal_url);

        $post_string = '';
        foreach ($_REQUEST as $field => $value) {
            $post_string .= $field . '=' . urlencode(stripslashes($value)) . '&';
        }
        $post_string.="cmd=_notify-validate"; // append ipn command
        // get the correct paypal url to post request to
        $paypal_mode_status = $im_debut_ipn; //get_option('im_sabdbox_mode');
        if ($paypal_mode_status == true)
            $fp = fsockopen('ssl://www.sandbox.paypal.com', "443", $err_num, $err_str, 60);
        else
            $fp = fsockopen('ssl://www.paypal.com', "443", $err_num, $err_str, 60);

        $ipn_response = '';

        if (!$fp) {
// could not open the connection.  If loggin is on, the error message
// will be in the log.
            $ipn_status = "fsockopen error no. $err_num: $err_str";
            if ($im_debut_ipn == true) {
                echo 'fsockopen fail';
            }
            return false;
        } else {
// Post the data back to paypal
            fputs($fp, "POST $url_parsed[path] HTTP/1.1\r\n");
            fputs($fp, "Host: $url_parsed[host]\r\n");
            fputs($fp, "Content-type: application/x-www-form-urlencoded\r\n");
            fputs($fp, "Content-length: " . strlen($post_string) . "\r\n");
            fputs($fp, "Connection: close\r\n\r\n");
            fputs($fp, $post_string . "\r\n\r\n");

// loop through the response from the server and append to variable
            while (!feof($fp)) {
                $ipn_response .= fgets($fp, 1024);
            }
            fclose($fp); // close connection
        }

// Invalid IPN transaction.  Check the $ipn_status and log for details.
        if (!preg_match("/VERIFIED/s", $ipn_response)) {
            $ipn_status = 'IPN Validation Failed';

            if ($im_debut_ipn == true) {
                echo 'Validation fail';
                print_r($_REQUEST);
            }
            return false;
        } else {
            $ipn_status = "IPN VERIFIED";
            if ($im_debut_ipn == true) {
                echo 'SUCCESS';

                }

            return true;
        }
    }


    function ipn_response($request){
    mail("[email protected]","My subject",print_r($request,true));
    $im_debut_ipn=true;
        if ($this->infotuts_ipn($im_debut_ipn)) {

            // if paypal sends a response code back let's handle it        
                   if ($im_debut_ipn == true) {
                    $sub = 'PayPal IPN Debug Email Main';
                    $msg = print_r($request, true);
                    $aname = 'infotuts';
                  //mail send
                }

                // process the membership since paypal gave us a valid +
                $this->insert_data($request);
            }
    }
function issetCheck($post,$key){
if(isset($post[$key])){
$return=$post[$key];
}
else{
$return='';
}
return $return;
}   
    function insert_data($request){
    require_once('dbconnect.php');


$post=$request;
$item_name=$this->issetCheck($post,'item_name');
$amount=$this->issetCheck($post,'mc_gross');
$currency=$this->issetCheck($post,'mc_currency');
$payer_email=$this->issetCheck($post,'payer_email');
$first_name=$this->issetCheck($post,'first_name');
$last_name=$this->issetCheck($post,'last_name');
$country=$this->issetCheck($post,'residence_country');
$txn_id=$this->issetCheck($post,'txn_id');
$txn_type=$this->issetCheck($post,'txn_type');
$payment_status=$this->issetCheck($post,'payment_status');
$payment_type=$this->issetCheck($post,'payment_type');
$payer_id=$this->issetCheck($post,'payer_id');
$date=$this->issetCheck($post,'custom');
$create_date=date('Y-m-d H:i:s');
$payment_date=date('Y-m-d H:i:s');

$firstLast = $first_name . $last_name;

$explode = explode('|', $item_name);

foreach($explode as $slot) {

    if(strlen($slot) > 0) {

        $query = "INSERT INTO bookings (date, start, name, email, phone, order_id) VALUES ('$date', '$slot', '$firstLast', '$payer_email', '$phone', '$orderid')"; 
        $result = mysqli_query($con, $query) or die(mysqli_error($link)); 

    } // Close if

} // Close foreach


mysqli_query($con,"INSERT INTO trans_tbl (item_name,ride_day,payer_email,first_name,last_name,amount,currency,country,txn_id,txn_type,payer_id,payment_status,payment_type,create_date,payment_date) 
VALUES ('$item_name','$date','$payer_email','$first_name','$last_name','$amount','$currency','$country','$txn_id','$txn_type','$payer_id','$payment_status','$payment_type','$create_date','$payment_date')");
mysqli_close($con);



    }
    }
    $obj = New PayPal_IPN();
    $obj->ipn_response($_REQUEST);

    ?>

On the IPN History of the paypal website it is stuck at sent - resending.

I have setup IPN settings and notify URL in profile settings, and have a business account. My email is verified on the account as well. Another thing to note, I have been doing simple $0.01 to test this outside sandbox mode, and the return page is working fine just not the ipn listener.

Any help is much appreciated, thanks.

1

There are 1 answers

0
Ben Cann On
$paypal_mode_status = $im_debut_ipn; //get_option('im_sabdbox_mode');
if ($paypal_mode_status == true)
    $fp = fsockopen('ssl://www.sandbox.paypal.com', "443", $err_num, $err_str, 60);
else
    $fp = fsockopen('ssl://www.paypal.com', "443", $err_num, $err_str, 60);

Could be incorrect, you should test to confirm, but I think it's because your $im_debut_ipn variable, when set to TRUE, is not only "debugging" but for some reason is also being used to determine the paypal url. It then sets the url to be paypals sandbox url (see above).

i.e, When

$im_debut_ipn = true

then,

$fp = fsockopen('ssl://www.sandbox.paypal.com', "443", $err_num, $err_str, 60);

is also true.

Note that I think $im_debut_ipn is actually a typo and should be ..debug.., meaning a debug mode that lets error messages be shown.