我的Paypal IPN出了什么问题?它适用于Sandbox但不适用

时间:2014-12-06 21:38:51

标签: paypal

所以我一直在尝试设置Paypal IPN,并尝试了大量不同的解决方案来让我的IPN验证。出于某种原因,当我使用Sanbox paypal时它工作正常,但是一旦我尝试使用实时版本,就没有任何反应。没有错误日志,没有IPN日志,没有。我迷失了。

我想知道是否有新眼睛会发现问题。这是我的paypal.php课程:

    <?php

session_start();
$base = "/var/www/html/";
include("db.php");
require_once('paypal.class.php');  // include the class file
$p = new paypal_class;             // initiate an instance of the class
//$p->paypal_url = 'https://www.sandbox.paypal.com/cgi-bin/webscr';   // testing paypal url
$p->paypal_url = 'https://www.paypal.com/cgi-bin/webscr';     // paypal url

// setup a variable for this script (ie: 'http://www.micahcarrick.com/paypal.php')
$this_script = 'http://'.$_SERVER['HTTP_HOST'].$_SERVER['PHP_SELF'];

// if there is not action variable, set the default action of 'process'
if (empty($_GET['action'])) $_GET['action'] = 'process';  

if (empty($_GET['amm'])) $_GET['amm'] = '1';

$EMAIL = 'emailaddresshere';


switch ($_GET['action']) {

   case 'process':      // Process and order...

if (empty($_GET['prod'])){
header("Location: confirm-product.php");        //Was donate.php (but no file for that, so might be confirm-product)
 exit;
}

if (empty($_GET['username'])){
if($_GET['action'] = 'process'){
header("Location: confirm-product.php");            // was donate.php as well
 exit;
}
} 
      //if(!isset($_SESSION["username"])) {
      //    header("Location: login.php");
      //    exit;
      //}

      //include("include.php");
//die("donation is temporarily disabled!");

      // There should be no output at this point.  To process the POST data,
      // the submit_paypal_post() function will output all the HTML tags which
      // contains a FORM which is submited instantaneously using the BODY onload
      // attribute.  In other words, don't echo or printf anything when you're
      // going to be calling the submit_paypal_post() function.

      // This is where you would have your form validation  and all that jazz.
      // You would take your POST vars and load them into the class like below,
      // only using the POST values instead of constant string expressions.

      // For example, after ensureing all the POST variables from your custom
      // order form are valid, you might have:
      //
      // $p->add_field('first_name', $_POST['first_name']);
      // $p->add_field('last_name', $_POST['last_name']);

    $price = '10.00';
        if($_GET['prod'] == 1)
            $price = '10.00';
        if($_GET['prod'] == 2)
            $price = '45.00';
        if($_GET['prod'] == 3)
            $price = '80.00';
        if($_GET['prod'] == 4)
            $price = '300.00';
        if($_GET['prod'] == 5)          //remove/change prod 5 after testing
            $price = '0.01';

    $name = '1K Donator Points';
        if ($_GET['prod'] == 1)
            $name = '1K Donator Points';
        if ($_GET['prod'] == 2)
            $name = '5K Donator Points';
        if ($_GET['prod'] == 3)
            $name = '10K Donator Points';
        if ($_GET['prod'] == 4)
            $name = '50K Donator Points';
        if ($_GET['prod'] == 5)
            $name = 'Testing Payment';
      $p->add_field('custom', $_GET['username']);
      $p->add_field('business', $EMAIL);
      $p->add_field('return', $this_script.'?action=success');
      $p->add_field('cancel_return', $this_script.'?action=cancel');
      $p->add_field('notify_url', $this_script.'?action=ipn');
      $p->add_field('item_name', ''.$name);
      $p->add_field('item_number', $_GET['prod']);
      $p->add_field('currency_code', 'USD');
      $p->add_field('amount', $price);
      //$p->add_field('quantity', $_GET['amm']);
      $p->add_field('lc', 'GB');
      $p->submit_paypal_post(); // submit the fields to paypal
 //     $p->dump_fields();      // for debugging, output a table of all the fields
      break;

   case 'success':      // Order was successful...

      // This is where you would probably want to thank the user for their order
      // or what have you.  The order information at this point is in POST
      // variables.  However, you don't want to "process" the order until you
      // get validation from the IPN.  That's where you would have the code to
      // email an admin, update the database with payment status, activate a
      // membership, etc.  

      //include("include.php");
      echo "<h2>Donation Successful</h2><p>Your payment has been completed.</p>";
      // You could also simply re-direct them to another page, or your own
      // order status page which presents the user with the status of their
      // order based on a database (which can be modified with the IPN code
      // below).
      break;

   case 'cancel':       // Order was canceled...

      // The order was canceled before being completed.
      //include("include.php");
      echo "<h2>Payment Cancelled</h2><p>Your payment was cancelled.</p>";

      break;

   case 'ipn':          // Paypal is calling page for IPN validation...

      // It's important to remember that paypal calling this script.  There
      // is no output here.  This is where you validate the IPN data and if it's
      // valid, update your database to signify that the user has payed.  If
      // you try and use an echo or printf function here it's not going to do you
      // a bit of good.  This is on the "backend".  That is why, by default, the
      // class logs all IPN data to a text file.
      if ($p->validate_ipn()) {
        error_log("Made it to validating IPN", 3, "myerrors.log");

         // Payment has been recieved and IPN is verified.  This is where you
         // update your database to activate or process the order, or setup
         // the database with the user's order details, email an administrator,
         // etc.  You can access a slew of information via the ipn_data() array.

         // Check the paypal documentation for specifics on what information
         // is available in the IPN POST variables.  Basically, all the POST vars
         // which paypal sends, which we send back for validation, are now stored
         // in the ipn_data() array.

         if($p->ipn_data["payment_status"] != "Completed") die();

         error_log("Payment Status = Completed, if this message shows - ", 3, "myerrors.log");

         if($p->ipn_data["mc_gross"] > 0 && strcmp ($p->ipn_data["business"],$EMAIL) == 0) {
            error_log("Blah blah blah 33", 3, "myerrors.log");
             $user = $p->ipn_data["custom"];
             $date = $p->ipn_data["payment_date"];
             $prodid = $p->ipn_data["item_number"];
             $amount = $p->ipn_data["mc_gross"];
             $amountTickets = 1;

             $user = str_replace("-", "_", $user);
             $user = str_replace(" ", "_", $user);
             $user = mysqli_real_escape_string($mysqli, $user);
             $prodid = mysqli_real_escape_string($mysqli, $prodid);
             $amount = mysqli_real_escape_string($mysqli, $amount);
             $mysqli = new mysqli("host", "name", "pass", "db");
             if ($mysqli->connect_error) {
        //      error_log("Connection Failed to Database", 3, "myerrors.log");
            } 
                $query = "INSERT INTO donation (username, time, productid, price, tickets) VALUES ('".$user."', '".$date."', '".$prodid."', '".$amount."', '".$amountTickets."');";
                $mysqli->query($query);
                //
             error_log("Passed through MySql Table insertion lines.", 3, "myerrors.log");
         }
         error_log("  -   Finished validating IPN process.", 3, "myerrors.log");
      }
      break;
 }    

?>

这是我的paypal.class.php课程

    <?php
/*******************************************************************************
 *                      PHP Paypal IPN Integration Class
 *******************************************************************************
 *      Author:     Micah Carrick
 *      Email:      email@micahcarrick.com
 *      Website:    http://www.micahcarrick.com
 *
 *      File:       paypal.class.php
 *      Version:    1.3.0
 *      Copyright:  (c) 2005 - Micah Carrick
 *                  You are free to use, distribute, and modify this software
 *                  under the terms of the GNU General Public License.  See the
 *                  included license.txt file.
 * 
 *******************************************************************************
*/

class paypal_class {

   var $last_error;                 // holds the last error encountered

   var $ipn_log;                    // bool: log IPN results to text file?

   var $ipn_log_file;               // filename of the IPN log
   var $ipn_response;               // holds the IPN response from paypal  
   var $ipn_data = array();         // array contains the POST values for IPN

   var $fields = array();           // array holds the fields to submit to paypal

    public $timeout = 30;       

    private $post_data = array();
    private $post_uri = '';     
    private $response_status = '';
    private $response = '';

    const PAYPAL_HOST = 'www.paypal.com';


   function paypal_class() {

      // initialization constructor.  Called when class is created.

      $this->paypal_url = 'https://www.paypal.com/cgi-bin/webscr';          //real one
   //   $this->paypal_url = 'https://www.sandbox.paypal.com/cgi-bin/webscr';        //testing one

      $this->last_error = '';

      $this->ipn_log_file = '.ipn_results.log';
      $this->ipn_log = true;
      $this->ipn_response = '';

      // populate $fields array with a few default values.  See the paypal
      // documentation for a list of fields and their data types. These defaul
      // values can be overwritten by the calling script.

      $this->add_field('rm','2');           // Return method = POST
      $this->add_field('cmd','_xclick');

   }

   public function getPostUri() {
        return $this->post_uri;
    }

   function add_field($field, $value) {

      // adds a key=>value pair to the fields array, which is what will be
      // sent to paypal as POST variables.  If the value is already in the
      // array, it will be overwritten.

      $this->fields["$field"] = $value;
   }

   function submit_paypal_post() {

      // this function actually generates an entire HTML page consisting of
      // a form with hidden elements which is submitted to paypal via the
      // BODY element's onLoad attribute.  We do this so that you can validate
      // any POST vars from you custom form before submitting to paypal.  So
      // basically, you'll have your own form which is submitted to your script
      // to validate the data, which in turn calls this function to create
      // another hidden form and submit to paypal.

      // The user will briefly see a message on the screen that reads:
      // "Please wait, your order is being processed..." and then immediately
      // is redirected to paypal.

      echo "<html>\n";
      echo "<head><title>Processing Payment...</title></head>\n";
      echo "<body onLoad=\"document.forms['paypal_form'].submit();\">\n";
      echo "<center><h2>Please wait, your order is being processed and you";
      echo " will be redirected to the paypal website.</h2></center>\n";
      echo "<form method=\"post\" name=\"paypal_form\" ";
      echo "action=\"".$this->paypal_url."\">\n";

      foreach ($this->fields as $name => $value) {
         echo "<input type=\"hidden\" name=\"$name\" value=\"$value\"/>\n";
      }
      echo "<center><br/><br/>If you are not automatically redirected to ";
      echo "paypal within 5 seconds...<br/><br/>\n";
      echo "<input type=\"submit\" value=\"Click Here\"></center>\n";

      echo "</form>\n";
      echo "</body></html>\n";

   }

   function validate_ipn() {

      // parse the paypal URL
 //     $url_parsed=parse_url($this->paypal_url);  
        error_log("  - Parsed URL.", 3, "myerrors.log");    //remove after

      // generate the post string from the _POST vars aswell as load the
      // _POST vars into an arry so we can play with them from the calling
      // script.
      $post_string = '';   //old
    //  $post_string="cmd=_notify-validate";        //new
      foreach ($_POST as $field=>$value) {
         $this->ipn_data["$field"] = $value;
         $post_string .= $field.'='.urlencode(stripslashes($value)).'&';        //old
    //  $post_string .= '&' . $field.'='.urlencode(stripslashes($value)); //new
      }
      $post_string.="cmd=_notify-validate"; // append ipn command

      error_log("  - Into ValidatingIPN, Line 187.", 3, "myerrors.log");    //remove after

      // open the connection to paypal
    //  $fp = fsockopen($url_parsed['host'], 443, $errnum, $errstr, 30);    //old real one
 //     $fp = fsockopen('ssl://www.paypal.com', 443, $errnum, $errstr, 30); //try this
 //     $fp = fsockopen('ssl://www.paypal.com', 443, $errno, $errstr, 30);  //try this
    //  $fp = fsockopen('https://www.paypal.com', 443, $errnum, $errstr, 30);
 //     $fp = fsockopen('ssl://www.sandbox.paypal.com', 443, $errno, $errstr, 30);      //testing one

    /*  if ($url_parsed['scheme'] == 'https') {
            $url_parsed['port'] = 443;
            $ssl = 'ssl://';
        } else {
            $url_parsed['port'] = 80;
            $ssl = '';
        }

        $fp = fsockopen($ssl.$url_parsed['host'], $url_parsed['port'], $errnum, $errstr, 30); */

                    //Real One v2
            $uri = 'ssl://www.paypal.com';
            $port = '443';
            $this->post_uri = $uri.'/cgi-bin/webscr';

        $fp = fsockopen($uri, $port, $errno, $errstr, $this->timeout);

      if(!$fp) {
          throw new Exception("fsockopen error: [$errno] $errstr");
      }

         // Post the data back to paypal
    //     fputs($fp, "POST $url_parsed[path] HTTP/1.1\r\n");       //old
    /*     fputs($fp, "POST /cgi-bin/webscr HTTP/1.1\r\n");
         fputs($fp, "Host: www.sandbox.paypal.com\r\n");            //sandbox  - www.sandbox.paypal.com
         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"); */

        $header = "POST /cgi-bin/webscr HTTP/1.1\r\n";
        $header .= "Host: www.paypal.com\r\n";          //real - www.paypal.com
        $header .= "Content-Type: application/x-www-form-urlencoded\r\n";
        $header .= "Content-Length: ".strlen($post_string)."\r\n";
        $header .= "Connection: Close\r\n\r\n";

        fputs($fp, $header.$post_string."\r\n\r\n");

         error_log("  - Connected to paypal connection. Posted Data to paypal.", 3, "myerrors.log");    //remove after

         // loop through the response from the server and append to variable
         while(!feof($fp)) {
            $this->ipn_response .= fgets($fp, 1024);        //old
         }

         fclose($fp); // close connection


    //  if (eregi("VERIFIED",$this->ipn_response)) {    //old
      if (preg_match("VERIFIED", $this->ipn_response)) {    //new       ~VERIFIED~i for sandbox

         // Valid IPN transaction.
         error_log("  - Valid IPN Transaction.", 3, "myerrors.log");    //remove after
         $this->log_ipn_results(true);
         return true;      

      } else {

         // Invalid IPN transaction.  Check the log for details.
         $this->last_error = 'IPN Validation Failed.';
         error_log("  - IPN Validation Failed", 3, "myerrors.log"); //remove after
         $this->log_ipn_results(true);      //Default: false  
         return false;

      }

   }

   function log_ipn_results($success) {

      if (!$this->ipn_log) return;  // is logging turned off?

      // Timestamp
      $text = '['.date('m/d/Y g:i A').'] - ';

      // Success or failure being logged?
      if ($success) $text .= "SUCCESS!\n";
      else $text .= 'FAIL: '.$this->last_error."\n";

      // Log the POST variables
      $text .= "IPN POST Vars from Paypal:\n";
      foreach ($this->ipn_data as $key=>$value) {
         $text .= "$key=$value, ";
      }

      // Log the response from the paypal server
      $text .= "\nIPN Response from Paypal Server:\n ".$this->ipn_response;

      // Write to log
      $fp=fopen($this->ipn_log_file,'a');
      fwrite($fp, $text . "\n\n");

      fclose($fp);  // close file
   }

   function dump_fields() {

      // Used for debugging, this function will output all the field/value pairs
      // that are currently defined in the instance of the class using the
      // add_field() function.

      echo "<h3>paypal_class->dump_fields() Output:</h3>";
      echo "<table width=\"95%\" border=\"1\" cellpadding=\"2\" cellspacing=\"0\">
           <tr>
              <td bgcolor=\"black\"><b><font color=\"white\">Field Name</font></b></td>
              <td bgcolor=\"black\"><b><font color=\"white\">Value</font></b></td>
           </tr>";

      ksort($this->fields);
      foreach ($this->fields as $key => $value) {
         echo "<tr><td>$key</td><td>".urldecode($value)."&nbsp;</td></tr>";
      }

      echo "</table><br>";
   }
}

0 个答案:

没有答案