During my upgrade I had to upgrade my file downloader as well. I had to go through the atrocious task of testing paypals ipn functions and make sure they're working correctly. This turned out to be a huge headache. Apparently paypal sandbox doesn't send back a VERIFIED string anymore even if you're IPN listener is correctly configured and responding correctly. I spent hours last night stepping through the IPN procedure trying to figure out why the IPN was always failing.
After several hours of googling and coming across several official paypal instruction pages that contradict one another. Here's one that even contradicts itself. You'll notice that in the instructions of the page they say to post back the ipn data to www.paypal.com or www.sandbox.paypal.com, depending on whether you are going live or testing your listener in the Sandbox. But then lower on the page they provide a sample script and in that script they're posting to ssl://www.paypal.com WTF!!!
Something else that may trip you up in sandbox ipn testing is, if you choose web accept in the ipn simulator it defaults to payment_status=Completed. Now here is a quote from paypal's instructions.
Lets look at web_accept it's the most common used and easiest to work with...
web_accept performs 5 data checks before it processes anything. These checks are the minimum recommended by PayPal that should be performed in your as follows:
So that basically says if you don't change the web accept payment_status variable from completed to something else, the ipn will not send back a "VERIFIED" string, not that it matters anyway because paypal's sandbox doesn't send a VERIFIED string anyway!!!
So what DOES paypal sandbox send back? Well the answer is literally nothing. Here, I'll show you.
HTTP/1.0 302 Found Location: https://www.sandbox.paypal.com Server: BigIP Connection: close Content-Length: 0That's it. That's all they sand back in the sandbox. Screw BigIP. Should have named it BigTimeWaster.
So in closing here is a paypal ipn script that is adapted to the fact that the paypal sandbox ipn sucks donkey balls. In live mode of course paypal DOES send back the VERIFIED string that we want.
function validate_ipn() { //live mode $url = "www.paypal.com"; //if test mode $url = "www.sandbox.paypal.com"; $path = "cgi-bin/webscr"; // 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 = ''; foreach ($_POST as $field=>$value) { $this->ipn_data["$field"] = $value; $post_string .= $field.'='.urlencode(stripslashes($value)).'&'; } $post_string.="cmd=_notify-validate"; // append ipn command // open the connection to paypal $fp = fsockopen($url,"80",$err_num,$err_str,30); if(!$fp) { // could not open the connection. If loggin is on, the error message // will be in the log. $this->last_error = "fsockopen error no. $errnum: $errstr"; $this->log_ipn_results(false); return false; } else { // Post the data back to paypal fputs($fp, "POST " . $path . " HTTP/1.1\r\n"); fputs($fp, "Host: " . $url . "\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)) { $this->ipn_response .= fgets($fp, 1024); } fclose($fp); // close connection } if (eregi("VERIFIED",$this->ipn_response) || $url == 'www.sandbox.paypal.com') { //if(true){ // Valid IPN transaction. $this->logThis('SUCCESS!!'); //$this->log_ipn_results(true); return true; } else { // Invalid IPN transaction. Check the log for details. $this->logThis('IPN Validation Failed.'); //$this->log_ipn_results(false); return false; } } function logThis($string) { ob_start(); print_r($string); $message = ob_get_clean(); //put the file in the root for testing purposes. $f = fopen(JPATH_ROOT . DS . 'test.txt','a'); fwrite($f,$message); fclose($f); }