View Single Post
Old 11-09-2012, 02:11 PM   PM User | #2
toddbuckles
New to the CF scene

 
Join Date: Apr 2011
Posts: 6
Thanks: 0
Thanked 0 Times in 0 Posts
toddbuckles is an unknown quantity at this point
Just in case someone stumbles on this and has the same problem, I was unable to resolve it. Instead, I went the cURL route, and it worked beautifully. I am not sure why the difference, but it solved the problem. Since I had no experience with cURL, it was a learning curve for me, but I made it through.

Here is my code that worked: I connect through a glob.inc.php, search that for more info.

PHP Code:

// STEP 1: Read POST data

// reading posted data directly from $_POST causes serialization issues with array data in POST
// read raw POST data from input stream instead. 
$raw_post_data file_get_contents('php://input'); //read-only stream that allows you to read raw data from the request body.  Result is a string...
$raw_post_array explode('&'$raw_post_data);  //put the string into an array
$myPost = array();
foreach (
$raw_post_array as $keyval) {
  
$keyval explode ('='$keyval);
  if (
count($keyval) == 2)
     
$myPost[$keyval[0]] = urldecode($keyval[1]);
}
// read the post from PayPal system and add 'cmd'
$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";
}

 
// STEP 2: Post IPN data back to paypal to validate

$ch curl_init('https://www.paypal.com/cgi-bin/webscr');  //initialize the curl session, and store it in object $ch

//below are the options applied to $ch
curl_setopt($chCURLOPT_HTTP_VERSIONCURL_HTTP_VERSION_1_1); //pretty obvious, sets http version.  paypal requires 1.1

curl_setopt($chCURLOPT_POST1);  //tells curl to do a regular post (the 1 option indicates 'true'

curl_setopt($chCURLOPT_RETURNTRANSFER,1);  //maybe someone can explain, manual states 'TRUE to return the transfer as a string of the return value of curl_exec() instead of outputting it out directly.'

curl_setopt($chCURLOPT_POSTFIELDS$req); //finally, the data we are posting.  Parsed above in the foreach statements

curl_setopt($chCURLOPT_SSL_VERIFYPEER1); //set to true here to verify paypal certificate

curl_setopt($chCURLOPT_SSL_VERIFYHOST2);  //could use help here.  paypal states 1 to check the existence of a common name in the SSL peer certificate. 2 to check the existence of a common name and also verify that it matches the hostname provided. In production environments the value of this option should be kept at 2 (default value).

curl_setopt($chCURLOPT_FORBID_REUSE1); //closes the connection as soon as it is finished processing without pooling data

curl_setopt($chCURLOPT_HTTPHEADER, array('Connection: Close')); //adds connection close to header

// In wamp like environments that do not come bundled with root authority certificates,
// please download 'cacert.pem' from "http://curl.haxx.se/docs/caextract.html" and set the directory path 
// of the certificate as shown below.
// curl_setopt($ch, CURLOPT_CAINFO, dirname(__FILE__) . '/cacert.pem');

if( !($res curl_exec($ch)) ) {  //and, we execute the cURL with all options set as above and log an error if it comes back empty.  Should return 'VERIFIED'
    // error_log("Got " . curl_error($ch) . " when processing IPN data");
    
curl_close($ch);
    exit;
}
curl_close($ch);

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

if (strcmp ($res"VERIFIED") == 0) {

     
// 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'];
    
$payment_date date('Y-m-d'strtotime($_POST['payment_date']));
    
$memid mysql_real_escape_string($_POST['custom']);  //our users ID
    
    // check whether the payment_status is Completed
    
if ($payment_status=='Completed'){
        
// check that txn_id has not been previously processed
        
$txn_id_check mysql_query("SELECT 'cknum' FROM 'members' WHERE 'cknum'='".$txn_id."'"); //cknum is a field specific to my db.
        
if (mysql_num_rows($txn_id_check)!=1){  //we don't already have that txn_id stored
            // check that receiver_email is your Primary PayPal email
            
if ($receiver_email == 'yourpaypalemail@here.com'){
                
// check that payment_amount/payment_currency are correct
                
if ($payment_amount == 'your amount' && $payment_currency == 'USD') {
                    
// process payment
                    //add values to database members table
                    
$log_query mysql_query("UPDATE members SET receipt='Yes', Amount='$payment_amount', paytype='Paypal', cknum='$txn_id', paid_thru='$payment_date' WHERE memid='$memid'");    //or whatever our sql statement is, or an email string, or whatever you want to execute.                
                
}
            }
        }    
    }
} else if (
strcmp ($res"INVALID") == 0) {
    
// log for manual investigation
    
$memid mysql_real_escape_string($_POST['custom']);  //our users ID
    
$log_query mysql_query("UPDATE members SET receipt='No', cknum='INVALID' WHERE memid='$memid'");
}
?> 
I really hope this helps someone.

TB
toddbuckles is offline   Reply With Quote