Paypal ipn always return invalid
Hi everyone, i'm stuck with this problem from a week. What I'm trying to do is to pass a variable in php containing all the data of a pdf via paypal button in order to be processed on my page later. So here's my code generated by paypal where i've added notify_url and custom variable.
<form action="https://www.paypal.com/cgi-bin/webscr" method="post" target="_top">
<input type="hidden" name="cmd" value="_s-xclick">
<input type="hidden" name="hosted_button_id" value="AEJ7FLWRMAK44">
<input type="hidden" name="notify_url" value="http://mysite.it/ipn_listener.php">
<input type="hidden" name="custom" value="<?php $base; ?>">
<input type="image" src="https://www.paypalobjects.com/it_IT/IT/i/btn/btn_buynow_SM.gif" border="0" name="submit" alt="PayPal รจ il metodo rapido e sicuro per pagare e farsi pagare online.">
<img alt="" border="0" src="https://www.paypalobjects.com/it_IT/i/scr/pixel.gif" width="1" height="1">
</form>
The variable $base contains all the data of the PDF created in this page,i need to pass them through paypal form.
And here the code of the listener(Directly from paypal).
<?php
require('fpdf.php');
// CONFIG: Enable debug mode. This means we'll log requests into 'ipn.log' in the same directory.
// Especially useful if you encounter network errors or other intermittent problems with IPN (validation).
// Set this to 0 once you go live or don't require logging.
define("DEBUG", 1);
// Set to 0 once you're ready to go live
define("USE_SANDBOX", 0);
define("LOG_FILE", "./ipn.log");
// Read POST data
// reading posted data directly from $_POST causes serialization
// issues with array data in POST. Reading raw POST data from input stream instead.
$raw_post_data = file_get_contents('php://input');
$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 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";
}
// Post IPN data back to PayPal to validate the IPN data is genuine
// Without this step anyone can fake IPN data
if(USE_SANDBOX == true) {
$paypal_url = "https://www.sandbox.paypal.com/cgi-bin/webscr";
} else {
$paypal_url = "https://www.paypal.com/cgi-bin/webscr";
}
$ch = curl_init($paypal_url);
if ($ch == FALSE) {
return FALSE;
}
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);
if(DEBUG == true) {
curl_setopt($ch, CURLOPT_HEADER, 1);
curl_setopt($ch, CURLINFO_HEADER_OUT, 1);
}
// CONFIG: Optional proxy configuration
//curl_setopt($ch, CURLOPT_PROXY, $proxy);
//curl_setopt($ch, CURLOPT_HTTPPROXYTUNNEL, 1);
// Set TCP timeout to 30 seconds
curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 30);
curl_setopt($ch, CURLOPT_HTTPHEADER, array('Connection: Close'));
// CONFIG: Please download 'cacert.pem' from "http://curl.haxx.se/docs/caextract.html" and set the directory path
// of the certificate as shown below. Ensure the file is readable by the webserver.
// This is mandatory for some environments.
//$cert = __DIR__ . "./cacert.pem";
//curl_setopt($ch, CURLOPT_CAINFO, $cert);
$res = curl_exec($ch);
if (curl_errno($ch) != 0) // cURL error
{
if(DEBUG == true) {
error_log(date('[Y-m-d H:i e] '). "Can't connect to PayPal to validate IPN message: " . curl_error($ch) . PHP_EOL, 3, LOG_FILE);
}
curl_close($ch);
exit;
} else {
// Log the entire HTTP response if debug is switched on.
if(DEBUG == true) {
error_log(date('[Y-m-d H:i e] '). "HTTP request of validation request:". curl_getinfo($ch, CURLINFO_HEADER_OUT) ." for IPN payload: $req" . PHP_EOL, 3, LOG_FILE);
error_log(date('[Y-m-d H:i e] '). "HTTP response of validation request: $res" . PHP_EOL, 3, LOG_FILE);
}
curl_close($ch);
}
echo $res;
// Inspect IPN validation result and act accordingly
// Split response headers and payload, a better way for strcmp
$tokens = explode("\r\n\r\n", trim($res));
$res = trim(end($tokens));
if (strcmp ($res, "VERIFIED") == 0) {
// check whether the payment_status is Completed
// check that txn_id has not been previously processed
// check that receiver_email is your PayPal email
// check that payment_amount/payment_currency are correct
// process payment and mark item as paid.
// 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'];
$plan = $_POST ['$custom'];
$plan -> Output('filename.pdf','D');
if(DEBUG == true) {
error_log(date('[Y-m-d H:i e] '). "Verified IPN: $req ". PHP_EOL, 3, LOG_FILE);
}
} else if (strcmp ($res, "INVALID") == 0) {
// log for manual investigation
// Add business logic here which deals with invalid IPN messages
if(DEBUG == true) {
error_log(date('[Y-m-d H:i e] '). "Invalid IPN: $req" . PHP_EOL, 3, LOG_FILE);
}
}
?>
and this is the log that result after pay:
[2015-12-13 13:06 UTC] HTTP request of validation request:POST /cgi-bin/webscr HTTP/1.1
Host: www.paypal.com
Accept: */*
Connection: Close
Content-Length: 20
Content-Type: application/x-www-form-urlencoded
for IPN payload: cmd=_notify-validate
[2015-12-13 13:06 UTC] HTTP response of validation request: HTTP/1.1 200 OK
Server: Apache
X-Frame-Options: SAMEORIGIN
Paypal-Debug-Id: 3c9689e4c464d
Cache-Control: max-age=0, no-cache, no-store, must-revalidate
Pragma: no-cache
Content-Type: text/html; charset=UTF-8
DC: dcg11-origin-www-2.paypal.com
Date: Sun, 13 Dec 2015 13:06:48 GMT
Content-Length: 7
Connection: close
Set-Cookie: cwrClyrK4LoCV1fydGbAxiNL6iG=h1DUElHT0plodZm1lFPnTdqF1LiGzLoXG7dYHHRSRG9RL2cia6MdmQ6MahF1Zv2nJHPi_OHvGTI9k7icIO_xteZXVKW6_1Eanm2OzV6EUhqfCx5RaJVVZ0k6kREma-fge47I2jdAUVmGU3WkpxycLClRTtW4yxG7Upafo701Ey7HFKhzN9Q9h0FlegIaInROJAbI6it8h-Mvg-2rOIsVPBRkIJ132Jmyg0Yg0-Gi0_gQjnixauCWZ8J3yrCA_--4FroiKAAF5oRfqVPwGs9nmUOMA7nPwgSf0HHZQ6uCJ7LSUkfU3ezY77NrNaLnnEpZQ59MNutMaQeR5Blt3aAKCVQdOKicNO7ilgSho4_MygvMVCsUxcDhmlFaGE5KmkkYHdRW7MpIXivjpwSf987gDNope3f8dyq06XXnMeBMiCNhpKlh5BclrWcI7Cm; domain=.paypal.com; path=/; Secure; HttpOnly
Set-Cookie: cookie_check=yes; expires=Wed, 10-Dec-2025 13:06:48 GMT; domain=.paypal.com; path=/; Secure; HttpOnly
Set-Cookie: navcmd=_notify-validate; domain=.paypal.com; path=/; Secure; HttpOnly
Set-Cookie: navlns=0.0; expires=Tue, 12-Dec-2017 13:06:48 GMT; domain=.paypal.com; path=/; Secure; HttpOnly
Set-Cookie: X-PP-SILOVER=name%3DLIVE9.WEB.1%26silo_version%3D880%26app%3Dappdispatcher%26TIME%3D1735224662; domain=.paypal.com; path=/; Secure; HttpOnly
Set-Cookie: X-PP-SILOVER=; Expires=Thu, 01 Jan 1970 00:00:01 GMT
Set-Cookie: Apache=10.16.1.3.1450012007804246; path=/; expires=Tue, 05-Dec-45 13:06:47 GMT
Set-Cookie: AKDC=dcg11-origin-www-2.paypal.com; expires=Sun, 13-Dec-2015 13:36:48 GMT; path=/; secure
Strict-Transport-Security: max-age=63072000
INVALID
[2015-12-13 13:06 UTC] Invalid IPN: cmd=_notify-validate
I've activated IPN in my paypal account but i've always return invalid, also by deleting the piece of code that sends and receives the variable custom the result does not change. Can somebody help me? this problem is giving me a headache for a week. Thanks in advance to all for answers.
Related
I'm trying to implement PayPal IPN but always returns INVALID. I know it's a recurring question and I've looked at similar questions, but I can not fix it.
I created an account on Paypal developer and the sandbox. I set up the account on a sandbox with IPN url.
I test the IPN simulator, get the message green "IPN was sent and the handshake was verified."
My code is the same as giving Paypal example, changing the url to point to the sandbox.
<?php
define("DEBUG", 1);
define("USE_SANDBOX", 1);
define("LOG_FILE", "./ipn.log");
$raw_post_data = file_get_contents('php://input');
$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]);
}
$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";
}
if(USE_SANDBOX == true) {
$paypal_url = "https://www.sandbox.paypal.com/cgi-bin/webscr";
} else {
$paypal_url = "https://www.paypal.com/cgi-bin/webscr";
}
$ch = curl_init($paypal_url);
if ($ch == FALSE) {
return FALSE;
}
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, false); // default: 1
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false); // default: 2
curl_setopt($ch, CURLOPT_FORBID_REUSE, 1);
if(DEBUG == true) {
curl_setopt($ch, CURLOPT_HEADER, 1);
curl_setopt($ch, CURLINFO_HEADER_OUT, 1);
}
curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 30);
curl_setopt($ch, CURLOPT_HTTPHEADER, array('Connection: Close'));
//$cert = __DIR__ . "./cacert.pem";
//curl_setopt($ch, CURLOPT_CAINFO, $cert);
$res = curl_exec($ch);
if (curl_errno($ch) != 0) // cURL error
{
if(DEBUG == true) {
error_log(PHP_EOL . "-------------------------------------------------------------------------\n" . PHP_EOL, 3, LOG_FILE);
error_log(date('[Y-m-d H:i e] '). "Can't connect to PayPal to validate IPN message: " . curl_error($ch) . PHP_EOL, 3, LOG_FILE);
error_log(PHP_EOL . "-------------------------------------------------------------------------\n" . PHP_EOL, 3, LOG_FILE);
}
curl_close($ch);
exit;
} else {
// Log the entire HTTP response if debug is switched on.
if(DEBUG == true) {
error_log(PHP_EOL . "------------------------ START HTTP REQUEST OF VALIDATION REQUEST ---------------------------\n" . PHP_EOL, 3, LOG_FILE);
error_log(date('[Y-m-d H:i e] '). "HTTP request of validation request:". curl_getinfo($ch, CURLINFO_HEADER_OUT) ." for IPN payload: $req" . PHP_EOL, 3, LOG_FILE);
error_log(PHP_EOL . "------------------------ END HTTP REQUEST OF VALIDATION REQUEST ---------------------------\n" . PHP_EOL, 3, LOG_FILE);
error_log(PHP_EOL ."*". PHP_EOL, 3, LOG_FILE);
error_log(PHP_EOL . "------------------------ START RESPONSE OF VALIDATION REQUEST -------------\n" . PHP_EOL, 3, LOG_FILE);
error_log(date('[Y-m-d H:i e] '). "HTTP response of validation request: $res" . PHP_EOL, 3, LOG_FILE);
error_log(PHP_EOL . "------------------------- END RESPONSE OF VALIDATION REQUEST -------------\n" . PHP_EOL, 3, LOG_FILE);
}
curl_close($ch);
}
$tokens = explode("\r\n\r\n", trim($res));
$res = trim(end($tokens));
if (strcmp ($res, "VERIFIED") == 0) {
// check whether the payment_status is Completed
// check that txn_id has not been previously processed
// check that receiver_email is your PayPal email
// check that payment_amount/payment_currency are correct
// process payment and mark item as paid.
// 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'];
if(DEBUG == true) {
error_log(PHP_EOL . "------------------------- START VERIFIED IPN-------------------------------\n" . PHP_EOL, 3, LOG_FILE);
error_log(date('[Y-m-d H:i e] '). "Verified IPN: $req ". PHP_EOL, 3, LOG_FILE);
error_log(PHP_EOL . "------------------------- END VERIFIED IPN-------------------------------\n" . PHP_EOL, 3, LOG_FILE);
}
} else if (strcmp ($res, "INVALID") == 0) {
// log for manual investigation
// Add business logic here which deals with invalid IPN messages
if(DEBUG == true) {
error_log(PHP_EOL . "------------------------ START INVALID IPN ----------------------------\n" . PHP_EOL, 3, LOG_FILE);
error_log(date('[Y-m-d H:i e] '). "Invalid IPN: $req" . PHP_EOL, 3, LOG_FILE);
error_log(PHP_EOL . "------------------------- END INVALID IPN ----------------------------\n" . PHP_EOL, 3, LOG_FILE);
}
}
?>
And this is the debug file. The data receipt and then sending are the same. I checked this with diffchecker.
--- START HTTP REQUEST OF VALIDATION REQUEST ---
[2016-05-31 11:50 UTC] HTTP request of validation request:POST /cgi-bin/webscr HTTP/1.1
Host: www.sandbox.paypal.com
Accept: */*
Connection: Close
Content-Length: 930
Content-Type: application/x-www-form-urlencoded
for IPN payload: cmd=_notify-validate&payment_type=instant&payment_date=Tue+May+31+2016+13%3A50%3A22+GMT+0200+%28Hora+de+verano+romance%29&payment_status=Completed&address_status=confirmed&payer_status=verified&first_name=John&last_name=Smith&payer_email=buyer%40paypalsandbox.com&payer_id=TESTBUYERID01&address_name=John+Smith&address_country=United+States&address_country_code=US&address_zip=95131&address_state=CA&address_city=San+Jose&address_street=123+any+street&business=seller%40paypalsandbox.com&receiver_email=seller%40paypalsandbox.com&receiver_id=seller%40paypalsandbox.com&residence_country=US&item_name1=something&item_number1=AK-1234&tax=2.02&mc_currency=USD&mc_fee=0.44&mc_gross=12.34&mc_gross_1=12.34&mc_handling=2.06&mc_handling1=1.67&mc_shipping=3.02&mc_shipping1=1.02&txn_type=cart&txn_id=705782812¬ify_version=2.1&custom=xyz123&invoice=abc1234&test_ipn=1&verify_sign=AnTtKanWvA9fOSykMNVIDFCr8B6oAIL.gR5ZR2RjDD.y8fHCYDoudx6e
--- END HTTP REQUEST OF VALIDATION REQUEST ---
--- START RESPONSE OF VALIDATION REQUEST ---
[2016-05-31 11:50 UTC] HTTP response of validation request: HTTP/1.1 200 OK
Date: Tue, 31 May 2016 11:50:28 GMT
Server: Apache
X-Frame-Options: SAMEORIGIN
Set-Cookie: c9MWDuvPtT9GIMyPc3jwol1VSlO=tiFAjXzjRap-cueIy6IvOIuyXEDeOqGj2EOZ4kGxnAcHI6wUU6Jt_CbHdK5imoAsJCKRirDu-jdw_IrfdkaJa77vQUvlkG6tZnaedRck1D8pqjwX3yVn7iaA-95NMS4yvpv4sIhWjFbeo7qr1dJVVoIB5Pi6fKMw1r8-ipWfhL10rl4yPYXrRMozluR_GfE6axFxKGZuuQa3oJrWNHAozFy4AgqbvRdT4tQdF2xmlxbjElokDVQQbG9z2K4aNECvAoVMl8TF1ilGIebFsQGhDD_uLXhrGxCaCiBBvMrUHagnlbXmrqeKomEl5zADjdrMHuvpnb4SpsDKGo-bjbgNsKNveM6j3Y1Mdn8TQlXjv4M5S5Ei19S1ks_H3AcHWLygzcsy5i5e7YJvor_PKyrnFepc3o9ILnj6Xx0izzZgf5vrQxkiddGZESmeJUe; domain=.paypal.com; path=/; Secure; HttpOnly
Set-Cookie: cookie_check=yes; expires=Fri, 29-May-2026 11:50:29 GMT; domain=.paypal.com; path=/; Secure; HttpOnly
Set-Cookie: navcmd=_notify-validate; domain=.paypal.com; path=/; Secure; HttpOnly
Set-Cookie: navlns=0.0; expires=Thu, 31-May-2018 11:50:29 GMT; domain=.paypal.com; path=/; Secure; HttpOnly
Set-Cookie: Apache=10.72.108.11.1464695428758058; path=/; expires=Thu, 24-May-46 11:50:28 GMT
Vary: Accept-Encoding,User-Agent
Connection: close
HTTP_X_PP_AZ_LOCATOR: sandbox.slc
Paypal-Debug-Id: eaa609cbb480c
Set-Cookie: X-PP-SILOVER=name%3DSANDBOX3.WEB.1%26silo_version%3D1880%26app%3Dappdispatcher%26TIME%3D2222607703%26HTTP_X_PP_AZ_LOCATOR%3Dsandbox.slc; Expires=Tue, 31 May 2016 12:20:29 GMT; domain=.paypal.com; path=/; Secure; HttpOnly
Set-Cookie: X-PP-SILOVER=; Expires=Thu, 01 Jan 1970 00:00:01 GMT
Strict-Transport-Security: max-age=14400
Transfer-Encoding: chunked
Content-Type: text/html; charset=UTF-8
INVALID
--- END RESPONSE OF VALIDATION REQUEST ---
--- START INVALID IPN ---
[2016-05-31 11:50 UTC] Invalid IPN: cmd=_notify-validate&payment_type=instant&payment_date=Tue+May+31+2016+13%3A50%3A22+GMT+0200+%28Hora+de+verano+romance%29&payment_status=Completed&address_status=confirmed&payer_status=verified&first_name=John&last_name=Smith&payer_email=buyer%40paypalsandbox.com&payer_id=TESTBUYERID01&address_name=John+Smith&address_country=United+States&address_country_code=US&address_zip=95131&address_state=CA&address_city=San+Jose&address_street=123+any+street&business=seller%40paypalsandbox.com&receiver_email=seller%40paypalsandbox.com&receiver_id=seller%40paypalsandbox.com&residence_country=US&item_name1=something&item_number1=AK-1234&tax=2.02&mc_currency=USD&mc_fee=0.44&mc_gross=12.34&mc_gross_1=12.34&mc_handling=2.06&mc_handling1=1.67&mc_shipping=3.02&mc_shipping1=1.02&txn_type=cart&txn_id=705782812¬ify_version=2.1&custom=xyz123&invoice=abc1234&test_ipn=1&verify_sign=AnTtKanWvA9fOSykMNVIDFCr8B6oAIL.gR5ZR2RjDD.y8fHCYDoudx6e
--- END INVALID IPN ---
Where is the problem? I can't find it.
EDIT * NEW TEST CODE
$raw_post_data = file_get_contents('php://input');
$pre = "cmd=_notify-validate";
$req = $pre."&".$raw_post_data;
RECEIVED
payment_type=instant&payment_date=Wed%20Jun%2001%202016%2017%3A23%3A30%20GMT+0200%20%28Hora%20de%20verano%20romance%29&payment_status=Completed&address_status=confirmed&payer_status=verified&first_name=John&last_name=Smith&payer_email=buyer#paypalsandbox.com&payer_id=TESTBUYERID01&address_name=John%20Smith&address_country=United%20States&address_country_code=US&address_zip=95131&address_state=CA&address_city=San%20Jose&address_street=123%20any%20street&business=seller#paypalsandbox.com&receiver_email=seller#paypalsandbox.com&receiver_id=seller#paypalsandbox.com&residence_country=US&item_name1=something&item_number1=AK-1234&tax=2.02&mc_currency=USD&mc_fee=0.44&mc_gross=12.34&mc_gross_1=12.34&mc_handling=2.06&mc_handling1=1.67&mc_shipping=3.02&mc_shipping1=1.02&txn_type=cart&txn_id=218898678¬ify_version=2.1&custom=xyz123&invoice=abc1234&test_ipn=1&verify_sign=AFcWxV21C7fd0v3bYYYRCpSSRl31A2H6KSDfssM5U2ik4231sae5BneW
SENT
cmd=_notify-validate&payment_type=instant&payment_date=Wed%20Jun%2001%202016%2017%3A23%3A30%20GMT+0200%20%28Hora%20de%20verano%20romance%29&payment_status=Completed&address_status=confirmed&payer_status=verified&first_name=John&last_name=Smith&payer_email=buyer#paypalsandbox.com&payer_id=TESTBUYERID01&address_name=John%20Smith&address_country=United%20States&address_country_code=US&address_zip=95131&address_state=CA&address_city=San%20Jose&address_street=123%20any%20street&business=seller#paypalsandbox.com&receiver_email=seller#paypalsandbox.com&receiver_id=seller#paypalsandbox.com&residence_country=US&item_name1=something&item_number1=AK-1234&tax=2.02&mc_currency=USD&mc_fee=0.44&mc_gross=12.34&mc_gross_1=12.34&mc_handling=2.06&mc_handling1=1.67&mc_shipping=3.02&mc_shipping1=1.02&txn_type=cart&txn_id=218898678¬ify_version=2.1&custom=xyz123&invoice=abc1234&test_ipn=1&verify_sign=AFcWxV21C7fd0v3bYYYRCpSSRl31A2H6KSDfssM5U2ik4231sae5BneW
RESULT = INVALID
RECEIVED
payment_type=instant&payment_date=Any%20character%20except%20%28more%29%20-%20123&payment_status=Completed&address_status=confirmed&payer_status=verified&first_name=John&last_name=Smith&payer_email=buyer#paypalsandbox.com&payer_id=TESTBUYERID01&address_name=John%20Smith&address_country=United%20States&address_country_code=US&address_zip=95131&address_state=CA&address_city=San%20Jose&address_street=123%20any%20street&business=seller#paypalsandbox.com&receiver_email=seller#paypalsandbox.com&receiver_id=seller#paypalsandbox.com&residence_country=US&item_name1=something&item_number1=AK-1234&tax=2.02&mc_currency=USD&mc_fee=0.44&mc_gross=12.34&mc_gross_1=12.34&mc_handling=2.06&mc_handling1=1.67&mc_shipping=3.02&mc_shipping1=1.02&txn_type=cart&txn_id=218898678¬ify_version=2.1&custom=xyz123&invoice=abc1234&test_ipn=1&verify_sign=AFcWxV21C7fd0v3bYYYRCpSSRl31A05enR9AkCnaKLwF3GcNFhj87aOl
SENT
cmd=_notify-validate&payment_type=instant&payment_date=Any%20character%20except%20%28more%29%20-%20123&payment_status=Completed&address_status=confirmed&payer_status=verified&first_name=John&last_name=Smith&payer_email=buyer#paypalsandbox.com&payer_id=TESTBUYERID01&address_name=John%20Smith&address_country=United%20States&address_country_code=US&address_zip=95131&address_state=CA&address_city=San%20Jose&address_street=123%20any%20street&business=seller#paypalsandbox.com&receiver_email=seller#paypalsandbox.com&receiver_id=seller#paypalsandbox.com&residence_country=US&item_name1=something&item_number1=AK-1234&tax=2.02&mc_currency=USD&mc_fee=0.44&mc_gross=12.34&mc_gross_1=12.34&mc_handling=2.06&mc_handling1=1.67&mc_shipping=3.02&mc_shipping1=1.02&txn_type=cart&txn_id=218898678¬ify_version=2.1&custom=xyz123&invoice=abc1234&test_ipn=1&verify_sign=AFcWxV21C7fd0v3bYYYRCpSSRl31A05enR9AkCnaKLwF3GcNFhj87aOl
RESULT = VERIFIED
Sorry to have to ask this again - but none of the options ive tried work for me..
Below is my listener code:
Note i have done the following to the ipn file (from paypal github) - without these issues i got an SSL error in log file.
1. curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, 0);//1 - changed
2. curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, 0);//2 - changed
3. curl_setopt($ch, CURLOPT_SSLVERSION, 6); // - added
4. added the CURL headers after default CURL options
The SendBasicEmail is a email function that just sends me the POST data.
I have also worked thru the Paypal troubleshooting guide, the URL is correct and the two name/value url paragraphs in the log file (see below) are also perfectly identical..
This is on a SHared hostgator account - Im not getting any php errors, and ive set the charset of the sandbox to utf-8..
Im getting the correct values sent by the IPN simulator, but the IPN keeps just saying INVALID without any rhyme or reason..
My ipn.log file has the following:
[2016-05-27 08:13 America/Chicago] HTTP request of validation request:POST /cgi-bin/webscr HTTP/1.1
Accept: */*
Content-Type:application/x-www-form-urlencoded
Host: www.sandbox.paypal.com
Content-Length: 934
Connection: close
for IPN payload: cmd=_notify-validate&payment_type=instant&payment_date=Fri+May+27+2016+15%3A08%3A35+GMT+0200+%28South+Africa+Standard+Time%29&payment_status=Completed&address_status=confirmed&payer_status=verified&first_name=John&last_name=Smith&payer_email=buyer%40paypalsandbox.com&payer_id=TESTBUYERID01&address_name=John+Smith&address_country=United+States&address_country_code=US&address_zip=95131&address_state=CA&address_city=San+Jose&address_street=123+any+street&business=seller%40paypalsandbox.com&receiver_email=seller%40paypalsandbox.com&receiver_id=seller%40paypalsandbox.com&residence_country=US&item_name1=something&item_number1=AK-1234&tax=2.02&mc_currency=USD&mc_fee=0.44&mc_gross=12.34&mc_gross_1=12.34&mc_handling=2.06&mc_handling1=1.67&mc_shipping=3.02&mc_shipping1=1.02&txn_type=cart&txn_id=429875949¬ify_version=2.1&custom=xyz123&invoice=abc1234&test_ipn=1&verify_sign=AoVeQZD-CT8vDxSGDZcG6pciC5eEAcQRkIs5dl-N0cnLYMm89A4qOJ7B
[2016-05-27 08:13 America/Chicago] HTTP response of validation request: HTTP/1.1 200 OK
Date: Fri, 27 May 2016 13:13:01 GMT
Server: Apache
X-Frame-Options: SAMEORIGIN
Set-Cookie: c9MWDuvPtT9GIMyPc3jwol1VSlO=0g7tVdxHaY6Zg55enbaKcWevON6OjuZOp-9GlUHpUmFZPDdL2ctJ_ipwOgPQtZgsJB37HUmD6-vfYr2TmKpcq6CrX81SyThtTxD_VPiGzhTpF0velEglL5BnltyBzDVI8wzJOQgyWxio60HFFGxVd67xy6e088O7CBWNS9i64IuHjc2jAux4dD7NU1zU7kvgsDLCFjW08ibZ1gQzEU3EafhMQpg7q_q8ntofjs1SXs_a-V1GiVueQQDN5eQALgvk_T2iwg51Gv630VvftWPJSnr3N2hqsW6gshwJY3ctvkR4bs9k_kS8rWYBkTxE1zqwwmSA9MdS_izc35-mwEzD8bKp3Xlyoc1FREU4wo-fnCzun6YPRZKaCDBzvY6O9smT9-k5b4nt6pnOcCikDTbZ4r0DAJu-XaJUK9mGnG; domain=.paypal.com; path=/; Secure; HttpOnly
Set-Cookie: cookie_check=yes; expires=Mon, 25-May-2026 13:13:01 GMT; domain=.paypal.com; path=/; Secure; HttpOnly
Set-Cookie: navcmd=_notify-validate; domain=.paypal.com; path=/; Secure; HttpOnly
Set-Cookie: navlns=0.0; expires=Sun, 27-May-2018 13:13:01 GMT; domain=.paypal.com; path=/; Secure; HttpOnly
Set-Cookie: Apache=10.72.108.11.1464354781199222; path=/; expires=Sun, 20-May-46 13:13:01 GMT
Vary: Accept-Encoding,User-Agent
Connection: close
HTTP_X_PP_AZ_LOCATOR: sandbox.slc
Paypal-Debug-Id: 96473e862c576
Set-Cookie: X-PP-SILOVER=name%3DSANDBOX3.WEB.1%26silo_version%3D1880%26app%3Dappdispatcher%26TIME%3D3712436311%26HTTP_X_PP_AZ_LOCATOR%3Dsandbox.slc; Expires=Fri, 27 May 2016 13:43:01 GMT; domain=.paypal.com; path=/; Secure; HttpOnly
Set-Cookie: X-PP-SILOVER=; Expires=Thu, 01 Jan 1970 00:00:01 GMT
Strict-Transport-Security: max-age=14400
Transfer-Encoding: chunked
Content-Type: text/html; charset=UTF-8
INVALID
[2016-05-27 08:13 America/Chicago] Invalid IPN: cmd=_notify-validate&payment_type=instant&payment_date=Fri+May+27+2016+15%3A08%3A35+GMT+0200+%28South+Africa+Standard+Time%29&payment_status=Completed&address_status=confirmed&payer_status=verified&first_name=John&last_name=Smith&payer_email=buyer%40paypalsandbox.com&payer_id=TESTBUYERID01&address_name=John+Smith&address_country=United+States&address_country_code=US&address_zip=95131&address_state=CA&address_city=San+Jose&address_street=123+any+street&business=seller%40paypalsandbox.com&receiver_email=seller%40paypalsandbox.com&receiver_id=seller%40paypalsandbox.com&residence_country=US&item_name1=something&item_number1=AK-1234&tax=2.02&mc_currency=USD&mc_fee=0.44&mc_gross=12.34&mc_gross_1=12.34&mc_handling=2.06&mc_handling1=1.67&mc_shipping=3.02&mc_shipping1=1.02&txn_type=cart&txn_id=429875949¬ify_version=2.1&custom=xyz123&invoice=abc1234&test_ipn=1&verify_sign=AoVeQZD-CT8vDxSGDZcG6pciC5eEAcQRkIs5dl-N0cnLYMm89A4qOJ7B
Below is my ipn listener file:
//Begin IPN FILE
// CONFIG: Enable debug mode. This means we'll log requests into 'ipn.log' in the same directory.
// Especially useful if you encounter network errors or other intermittent problems with IPN (validation).
// Set this to 0 once you go live or don't require logging.
define("DEBUG", 1);
// Set to 0 once you're ready to go live
define("USE_SANDBOX", 1);
define("LOG_FILE", "./ipn.log");
// Read POST data
// reading posted data directly from $_POST causes serialization
// issues with array data in POST. Reading raw POST data from input stream instead.
$raw_post_data = file_get_contents('php://input');
$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 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";
}
// Post IPN data back to PayPal to validate the IPN data is genuine
// Without this step anyone can fake IPN data
if(USE_SANDBOX == true) {
$paypal_url = "https://www.sandbox.paypal.com/cgi-bin/webscr";
} else {
$paypal_url = "https://www.paypal.com/cgi-bin/webscr";
}
$ch = curl_init($paypal_url);
if ($ch == FALSE) {
return FALSE;
}
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, 0);//1
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, 0);//2
curl_setopt($ch, CURLOPT_FORBID_REUSE, 1);
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, 2);
curl_setopt($ch, CURLOPT_SSLVERSION, 6);
$headers= array('POST /cgi-bin/webscr HTTP/1.0',
'Content-Type:application/x-www-form-urlencoded',
'Host: www.sandbox.paypal.com',
"Content-Length: " . strlen($req),
'Connection: close'
);
curl_setopt($ch,CURLOPT_HTTPHEADER, $headers);
if(DEBUG == true) {
curl_setopt($ch, CURLOPT_HEADER, 1);
curl_setopt($ch, CURLINFO_HEADER_OUT, 1);
}
// CONFIG: Optional proxy configuration
//curl_setopt($ch, CURLOPT_PROXY, $proxy);
//curl_setopt($ch, CURLOPT_HTTPPROXYTUNNEL, 1);
// Set TCP timeout to 30 seconds
curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 30);
#curl_setopt($ch, CURLOPT_HTTPHEADER, array('Connection: Close'));
// CONFIG: Please download 'cacert.pem' from "http://curl.haxx.se/docs/caextract.html" and set the directory path
// of the certificate as shown below. Ensure the file is readable by the webserver.
// This is mandatory for some environments.
//$cert = __DIR__ . "./cacert.pem";
//curl_setopt($ch, CURLOPT_CAINFO, $cert);
$res = curl_exec($ch);
if (curl_errno($ch) != 0) // cURL error
{
if(DEBUG == true) {
error_log(date('[Y-m-d H:i e] '). "Can't connect to PayPal to validate IPN message: " . curl_error($ch) . PHP_EOL, 3, LOG_FILE);
}
curl_close($ch);
exit;
} else {
// Log the entire HTTP response if debug is switched on.
if(DEBUG == true) {
error_log(date('[Y-m-d H:i e] '). "HTTP request of validation request:". curl_getinfo($ch, CURLINFO_HEADER_OUT) ." for IPN payload: $req" . PHP_EOL, 3, LOG_FILE);
error_log(date('[Y-m-d H:i e] '). "HTTP response of validation request: $res" . PHP_EOL, 3, LOG_FILE);
}
curl_close($ch);
}
SendBasicEmail("fran#strike1.co.za","res",strcmp (var_dump($raw_post_array), "VERIFIED"));
// Inspect IPN validation result and act accordingly
// Split response headers and payload, a better way for strcmp
$tokens = explode("\r\n\r\n", trim($res));
$res = trim(end($tokens));
if (strcmp ($res, "VERIFIED") == 0) {
// check whether the payment_status is Completed
// check that txn_id has not been previously processed
// check that receiver_email is your PayPal email
// check that payment_amount/payment_currency are correct
// process payment and mark item as paid.
// 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'];
SendBasicEmail("fran#strike1.co.za", "IPN DATA - Pass", "$ipnrows");
if(DEBUG == true) {
error_log(date('[Y-m-d H:i e] '). "Verified IPN: $req ". PHP_EOL, 3, LOG_FILE);
}
} else if (strcmp ($res, "INVALID") == 0) {
// log for manual investigation
// Add business logic here which deals with invalid IPN messages
SendBasicEmail("fran#strike1.co.za", "IPN DATA - Fail", "$ipnrows");
if(DEBUG == true) {
error_log(date('[Y-m-d H:i e] '). "Invalid IPN: $req" . PHP_EOL, 3, LOG_FILE);
}
}
//END IPN FILE
Finally found the issue!!
After scratching around hordes of other peoples posts with the same issues for days - I found many were using a preg_replace to remove the url encoded characters (%) from the paypal post variable values..
Assuming you have double checked u dont have php syntax errors and not getting a php error.log file created when running the ipn simulator - look inside the ipn.log file (or email yourself the output of $req from the ipn listener)...
mail("*email#what.where*","Ipn Res", curl_getinfo($ch, CURLINFO_HEADER_OUT) .$res );
Look for any characters beginning with % -
look at my example above:
payment_date=Fri+May+27+2016+15**%3A**08**%3**A35+GMT+0200+
The default IPN simulator was adding a whole lot of rubbish timezone trash that was causing a variety of % (url encoded) values that were failing my ipn.
(Note I had already changed my encoding to utf-8 in the account settings)
I replaced the default IPN date field with a regular php date and all worked - FINALLY!
So - make sure you arent getting any % values in the post url and all should be good!
Also - I had to change these options to also pass:
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, 0);//1 - changed
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, 0);//2 - changed
curl_setopt($ch, CURLOPT_SSLVERSION, 6); // - added
My IPN script exactly as the PayPal sample code: http://www.example.com/cart/ipn2.php (only thing different is I added cacert.pem to cURL since my server environment lacks it)
<?php
// CONFIG: Enable debug mode. This means we'll log requests into 'ipn.log' in the same directory.
// Especially useful if you encounter network errors or other intermittent problems with IPN (validation).
// Set this to 0 once you go live or don't require logging.
define("DEBUG", 1);
// Set to 0 once you're ready to go live
define("USE_SANDBOX", 1);
define("LOG_FILE", "./ipn.log");
// Read POST data
// reading posted data directly from $_POST causes serialization
// issues with array data in POST. Reading raw POST data from input stream instead.
$raw_post_data = file_get_contents('php://input');
$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 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";
}
// Post IPN data back to PayPal to validate the IPN data is genuine
// Without this step anyone can fake IPN data
if(USE_SANDBOX == true) {
$paypal_url = "https://www.sandbox.paypal.com/cgi-bin/webscr";
} else {
$paypal_url = "https://www.paypal.com/cgi-bin/webscr";
}
$ch = curl_init($paypal_url);
if ($ch == FALSE) {
return FALSE;
}
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);
if(DEBUG == true) {
curl_setopt($ch, CURLOPT_HEADER, 1);
curl_setopt($ch, CURLINFO_HEADER_OUT, 1);
}
// CONFIG: Optional proxy configuration
//curl_setopt($ch, CURLOPT_PROXY, $proxy);
//curl_setopt($ch, CURLOPT_HTTPPROXYTUNNEL, 1);
// Set TCP timeout to 30 seconds
curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 30);
curl_setopt($ch, CURLOPT_HTTPHEADER, array('Connection: Close'));
// CONFIG: Please download 'cacert.pem' from "http://curl.haxx.se/docs/caextract.html" and set the directory path
// of the certificate as shown below. Ensure the file is readable by the webserver.
// This is mandatory for some environments.
$cert = __DIR__ . "/cacert.pem";
curl_setopt($ch, CURLOPT_CAINFO, $cert);
$res = curl_exec($ch);
if (curl_errno($ch) != 0) // cURL error
{
if(DEBUG == true) {
error_log(date('[Y-m-d H:i e] '). "Can't connect to PayPal to validate IPN message: " . curl_error($ch) . PHP_EOL, 3, LOG_FILE);
}
curl_close($ch);
exit;
} else {
// Log the entire HTTP response if debug is switched on.
if(DEBUG == true) {
error_log(date('[Y-m-d H:i e] '). "HTTP request of validation request:". curl_getinfo($ch, CURLINFO_HEADER_OUT) ." for IPN payload: $req" . PHP_EOL, 3, LOG_FILE);
error_log(date('[Y-m-d H:i e] '). "HTTP response of validation request: $res" . PHP_EOL, 3, LOG_FILE);
}
curl_close($ch);
}
// Inspect IPN validation result and act accordingly
// Split response headers and payload, a better way for strcmp
$tokens = explode("\r\n\r\n", trim($res));
$res = trim(end($tokens));
if (strcmp ($res, "VERIFIED") == 0) {
// check whether the payment_status is Completed
// check that txn_id has not been previously processed
// check that receiver_email is your PayPal email
// check that payment_amount/payment_currency are correct
// process payment and mark item as paid.
// 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'];
if(DEBUG == true) {
error_log(date('[Y-m-d H:i e] '). "Verified IPN: $req ". PHP_EOL, 3, LOG_FILE);
}
} else if (strcmp ($res, "INVALID") == 0) {
// log for manual investigation
// Add business logic here which deals with invalid IPN messages
if(DEBUG == true) {
error_log(date('[Y-m-d H:i e] '). "Invalid IPN: $req" . PHP_EOL, 3, LOG_FILE);
}
}
I then test it at here: https://developer.paypal.com/developer/ipnSimulator/
IPN handler URL: http://www.example.com/cart/ipn2.php
Transaction type: Cart checkout
Clicked "Send IPN".
IPN was sent and the handshake was verified.
Now I check ipn.log in the same directory as ipn2.php:
[2016-05-29 03:33 UTC] HTTP request of validation request:POST /cgi-bin/webscr HTTP/1.1
Host: www.sandbox.paypal.com
Accept: */*
Connection: Close
Content-Length: 956
Content-Type: application/x-www-form-urlencoded
for IPN payload: cmd=_notify-validate&payment_type=instant&payment_date=Sun+May+29+2016+09%3A47%3A44+GMT+0800+%28%25u4E2D%25u56FD%25u6807%25u51C6%25u65F6%25u95F4%29&payment_status=Completed&payer_status=verified&first_name=John&last_name=Smith&payer_email=buyer%40paypalsandbox.com&payer_id=TESTBUYERID01&address_name=John+Smith&address_country=United+States&address_country_code=US&address_zip=95131&address_state=CA&address_city=San+Jose&address_street=123+any+street&business=seller%40paypalsandbox.com&receiver_email=seller%40paypalsandbox.com&receiver_id=seller%40paypalsandbox.com&residence_country=US&item_name1=something&item_number1=AK-1234&quantity=1&shipping=3.04&tax=2.02&mc_currency=USD&mc_fee=0.44&mc_gross=12.34&mc_gross_1=12.34&mc_handling=2.06&mc_handling1=1.67&mc_shipping=3.02&mc_shipping1=1.02&txn_type=cart&txn_id=899327589¬ify_version=2.4&custom=xyz123&invoice=abc1234&test_ipn=1&verify_sign=Ax7s3TqIWw66TCwHqtv5jrDudIkqArp9Q5MbSvZN7Hmp0hVcLJIPMGtn
[2016-05-29 03:33 UTC] HTTP response of validation request: HTTP/1.1 200 OK
Date: Sun, 29 May 2016 03:33:52 GMT
Server: Apache
X-Frame-Options: SAMEORIGIN
Set-Cookie: c9MWDuvPtT9GIMyPc3jwol1VSlO=275N2N7S363a15EPCeqtgTf8h6q9dGxoqH7G2qLXSZ_CsWkTd-fn7MPTwWkNErzsHwZmTFSzM6aG-Uidv3uJDu-qATD4hP8S724yYqEFXgNSfr1n7rBUKf81IYFx1nwn3saS7puTcmRSTc1HUvXwTOY0xLie6LpPJXhg8mX92feeUkUo1_4Ndye5D67XLpfjTbHsby32vssICqRf-4XUqw9Vqz6OgWMWjYq8vyEAy4S7ojpFQxs2Bb61hY4Plum1LhSscdb_xXeKFqRjc89QU3w2S51usLzma39SM1WsFCayybOyXuYJcUyXMdCg0--tyDxO9Ru3eAjQixTZPCN9Y9TbKd0HIxBqtqxmdRGFtd0GTzFj__zc8sjO4cliOJCRI30YLCfUbMqf4G8bgDymdR7gcqIf1CNWcvMGwW; domain=.paypal.com; path=/; Secure; HttpOnly
Set-Cookie: cookie_check=yes; expires=Wed, 27-May-2026 03:33:53 GMT; domain=.paypal.com; path=/; Secure; HttpOnly
Set-Cookie: navcmd=_notify-validate; domain=.paypal.com; path=/; Secure; HttpOnly
Set-Cookie: navlns=0.0; expires=Tue, 29-May-2018 03:33:53 GMT; domain=.paypal.com; path=/; Secure; HttpOnly
Set-Cookie: Apache=10.72.108.11.1464492832868615; path=/; expires=Tue, 22-May-46 03:33:52 GMT
Vary: Accept-Encoding,User-Agent
Connection: close
HTTP_X_PP_AZ_LOCATOR: sandbox.slc
Paypal-Debug-Id: ef5f7fe7cf2cc
Set-Cookie: X-PP-SILOVER=name%3DSANDBOX3.WEB.1%26silo_version%3D1880%26app%3Dappdispatcher%26TIME%3D543378007%26HTTP_X_PP_AZ_LOCATOR%3Dsandbox.slc; Expires=Sun, 29 May 2016 04:03:53 GMT; domain=.paypal.com; path=/; Secure; HttpOnly
Set-Cookie: X-PP-SILOVER=; Expires=Thu, 01 Jan 1970 00:00:01 GMT
Strict-Transport-Security: max-age=14400
Transfer-Encoding: chunked
Content-Type: text/html; charset=UTF-8
INVALID
[2016-05-29 03:33 UTC] Invalid IPN: cmd=_notify-validate&payment_type=instant&payment_date=Sun+May+29+2016+09%3A47%3A44+GMT+0800+%28%25u4E2D%25u56FD%25u6807%25u51C6%25u65F6%25u95F4%29&payment_status=Completed&payer_status=verified&first_name=John&last_name=Smith&payer_email=buyer%40paypalsandbox.com&payer_id=TESTBUYERID01&address_name=John+Smith&address_country=United+States&address_country_code=US&address_zip=95131&address_state=CA&address_city=San+Jose&address_street=123+any+street&business=seller%40paypalsandbox.com&receiver_email=seller%40paypalsandbox.com&receiver_id=seller%40paypalsandbox.com&residence_country=US&item_name1=something&item_number1=AK-1234&quantity=1&shipping=3.04&tax=2.02&mc_currency=USD&mc_fee=0.44&mc_gross=12.34&mc_gross_1=12.34&mc_handling=2.06&mc_handling1=1.67&mc_shipping=3.02&mc_shipping1=1.02&txn_type=cart&txn_id=899327589¬ify_version=2.4&custom=xyz123&invoice=abc1234&test_ipn=1&verify_sign=Ax7s3TqIWw66TCwHqtv5jrDudIkqArp9Q5MbSvZN7Hmp0hVcLJIPMGtn
Why? I literally followed the code sample to the word. Why it's always INVALID? I've been scratching my head about this for hours and nothing relevant came up. Please help me anyone!
You may try create sandbox accounts and make test payments to check your IPN script. My script is also receiving "INVALID" response for IPN data from IPN simulator but it receives "VERIFIED" for IPN data from sandbox test payments.
You might want to check the IPN trouble shooting tips on INVALID response HERE
Charset config in the account profile is the most typical cause of the issue, and if you're testing against www.sandbox.paypal.com, you would need to update the language encoding settings in your sandbox seller account (login to www.sandbox.paypal.com with your sandbox seller credentials) rather than your LIVE account.
I'm having trouble with Paypal IPN. I'm using the IPN script from github:
Script link
This is the php code for the script:
<?php
// CONFIG: Enable debug mode. This means we'll log requests into 'ipn.log' in the same directory.
// Especially useful if you encounter network errors or other intermittent problems with IPN (validation).
// Set this to 0 once you go live or don't require logging.
define("DEBUG", 1);
// Set to 0 once you're ready to go live
define("USE_SANDBOX", 0);
define("LOG_FILE", "./ipn.log");
// Read POST data
// reading posted data directly from $_POST causes serialization
// issues with array data in POST. Reading raw POST data from input stream instead.
$raw_post_data = file_get_contents('php://input');
$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 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";
}
// Post IPN data back to PayPal to validate the IPN data is genuine
// Without this step anyone can fake IPN data
if(USE_SANDBOX == true) {
$paypal_url = "https://www.sandbox.paypal.com/cgi-bin/webscr";
} else {
$paypal_url = "https://www.paypal.com/cgi-bin/webscr";
}
$ch = curl_init($paypal_url);
if ($ch == FALSE) {
return FALSE;
}
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);
if(DEBUG == true) {
curl_setopt($ch, CURLOPT_HEADER, 1);
curl_setopt($ch, CURLINFO_HEADER_OUT, 1);
}
// CONFIG: Optional proxy configuration
//curl_setopt($ch, CURLOPT_PROXY, $proxy);
//curl_setopt($ch, CURLOPT_HTTPPROXYTUNNEL, 1);
// Set TCP timeout to 30 seconds
curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 30);
curl_setopt($ch, CURLOPT_HTTPHEADER, array('Connection: Close'));
// CONFIG: Please download 'cacert.pem' from "http://curl.haxx.se/docs/caextract.html" and set the directory path
// of the certificate as shown below. Ensure the file is readable by the webserver.
// This is mandatory for some environments.
//$cert = __DIR__ . "./cacert.pem";
//curl_setopt($ch, CURLOPT_CAINFO, $cert);
$res = curl_exec($ch);
if (curl_errno($ch) != 0) // cURL error
{
if(DEBUG == true) {
error_log(date('[Y-m-d H:i e] '). "Can't connect to PayPal to validate IPN message: " . curl_error($ch) . PHP_EOL, 3, LOG_FILE);
}
curl_close($ch);
exit;
} else {
// Log the entire HTTP response if debug is switched on.
if(DEBUG == true) {
error_log(date('[Y-m-d H:i e] '). "HTTP request of validation request:". curl_getinfo($ch, CURLINFO_HEADER_OUT) ." for IPN payload: $req" . PHP_EOL, 3, LOG_FILE);
error_log(date('[Y-m-d H:i e] '). "HTTP response of validation request: $res" . PHP_EOL, 3, LOG_FILE);
}
curl_close($ch);
}
// Inspect IPN validation result and act accordingly
// Split response headers and payload, a better way for strcmp
$tokens = explode("\r\n\r\n", trim($res));
$res = trim(end($tokens));
if (strcmp ($res, "VERIFIED") == 0) {
// check whether the payment_status is Completed
// check that txn_id has not been previously processed
// check that receiver_email is your PayPal email
// check that payment_amount/payment_currency are correct
// process payment and mark item as paid.
// 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'];
if(DEBUG == true) {
error_log(date('[Y-m-d H:i e] '). "Verified IPN: $req ". PHP_EOL, 3, LOG_FILE);
}
} else if (strcmp ($res, "INVALID") == 0) {
// log for manual investigation
// Add business logic here which deals with invalid IPN messages
if(DEBUG == true) {
error_log(date('[Y-m-d H:i e] '). "Invalid IPN: $req" . PHP_EOL, 3, LOG_FILE);
}
}
?>
...with my post-processing code being after the verifiy check
if (strcmp ($res, "VERIFIED") == 0) {
When someone pays via Paypal, everything seems to work in terms of my site receiving the IPN data and processing it. However, when I check the IPN logs in Paypal it has a status code of 500 (internal server error) and keeps resending the IPN data.
I have no idea why this is happening. This same IPN script (or close variations) are all over the net so I presume the script is fine.
Here is the log file recorded by the script:
[2015-08-15 13:31 Europe/London] HTTP request of validation request:POST /cgi-bin/webscr HTTP/1.1
Host: www.paypal.com
Accept: */*
Connection: Close
Content-Length: 1014
Content-Type: application/x-www-form-urlencoded
for IPN payload: cmd=_notify-validate&mc_gross=4.95&protection_eligibility=Eligible&address_status=unconfirmed&payer_id=--------&tax=0.00&address_street=------&payment_date=05%3A25%3A51+Aug+15%2C+2015+PDT&payment_status=Completed&charset=windows-1252&address_zip=------&first_name=-----&mc_fee=0.27&address_country_code=ES&address_name=-----¬ify_version=3.8&custom=&payer_status=verified&business=--------&address_country=Spain&address_city=-------&quantity=1&verify_sign=AEWexEu2HAXvtIxtV.FjJ4XDJIdfA8MGuWBu9unU4dGBd7qVw2YL2a0p&payer_email=--------&txn_id=-------&payment_type=instant&payer_business_name=------&last_name=W----&address_state=------&receiver_email=--------&payment_fee=&receiver_id=-------&txn_type=web_accept&item_name=---------&mc_currency=GBP&item_number=------&residence_country=GB&handling_amount=0.00&transaction_subject=&payment_gross=&shipping=0.00&ipn_track_id=--------
[2015-08-15 13:31 Europe/London] HTTP response of validation request: HTTP/1.1 200 OK
Server: Apache
X-Frame-Options: SAMEORIGIN
Paypal-Debug-Id: 85e8fa12ae5b4
Cache-Control: max-age=0, no-cache, no-store, must-revalidate
Pragma: no-cache
Content-Type: text/html; charset=UTF-8
DC: slc-origin-www.paypal.com
Date: Sat, 15 Aug 2015 12:31:22 GMT
Content-Length: 8
Connection: close
Set-Cookie: cwrClyrK4LoCV1fydGbAxiNL6iG=GsUqRUQy6PV-FIg6NZNaoWTmld6up9P1KKqndXexz_jj_zeAZ4x0Kn30L4uIpy__dU4bnuACyaC89S34gzVIGmA2RmA8EBSoiH6oFumGT1YG-PxlbiMrDzyyNIjAnfFEJ0XPZmwovk7hutZlJannbvBOGibCAawKZ3rpqkphLxNrDZR-AZa0OAwjsUNEJtcy8gxroi8dbImfynYwQxhP_tTP1422-p2gLl8hxdhVqzO1PgDbCALd3kqfM67UCXZ0TVNpr5Pi84KsVZkZ1X00PblzKmbsFJ8vS7wbmocXEJveA6o1mPllq-qKO9MOEppBM0IxMS8rbwafRFDBzkFepW_gsNCkQPAATYNkLS6PTiBYMzL5-VV4ku_b4xTAsT_q4cotE5q4d-hqH1sE4fkdbql8HGCNwIiq2RpYrsI00nmMDrkGmZbHMV02BMG; domain=.paypal.com; path=/; Secure; HttpOnly
Set-Cookie: cookie_check=yes; expires=Tue, 12-Aug-2025 12:31:22 GMT; domain=.paypal.com; path=/; Secure; HttpOnly
Set-Cookie: navcmd=_notify-validate; domain=.paypal.com; path=/; Secure; HttpOnly
Set-Cookie: navlns=0.0; expires=Mon, 14-Aug-2017 12:31:22 GMT; domain=.paypal.com; path=/; Secure; HttpOnly
Set-Cookie: Apache=10.16.0.147.1439641881720232; path=/; expires=Mon, 07-Aug-45 12:31:21 GMT
Set-Cookie: X-PP-SILOVER=name%3DLIVE9.WEB.1%26silo_version%3D880%26app%3Dappdispatcher%26TIME%3D422694741; domain=.paypal.com; path=/; Secure; HttpOnly
Set-Cookie: X-PP-SILOVER=; Expires=Thu, 01 Jan 1970 00:00:01 GMT
Set-Cookie: Apache=10.16.0.206.1439641881713999; path=/; expires=Mon, 07-Aug-45 12:31:21 GMT
Set-Cookie: AKDC=slc-origin-www.paypal.com; expires=Sat, 15-Aug-2015 13:01:22 GMT; path=/; secure
Strict-Transport-Security: max-age=63072000
VERIFIED
Does anyone know why I could be getting this 500 error?
I've searched the net for a solution but can't find out what's wrong.
Thanks
Try to put a "/" at the end of the url.
Example:
The URL http:///paypal/notify gives the error status 500 but the URL http:///paypal/notify/ works fine.
UPDATE #1: I've located the problem, when I use the simulator the $res variable has the string 'VERIFIED' as it should be, since it's being exploded from the headers, however it doesn't seem to be the case when I use the sandbox, the headers stay in that variable. What can I do?
I've used the IPN php code provided by PayPal to make a payment (which depends on the product you choose) in my website. If I use the IPN simulator it works correctly, and posts the log fine, however when using the sandbox accounts (I enabled IPN on my seller account), it doesn't log after the word VERIFIED, see here, the first is the sandbox test, the other is the simulator test
[2013-11-21 14:52 Europe/Rome] HTTP request of validation request:POST /cgi-bin/webscr HTTP/1.1
Host: www.sandbox.paypal.com
Accept: */*
Connection: Close
Content-Length: 1057
Content-Type: application/x-www-form-urlencoded
Expect: 100-continue
for IPN payload: cmd=_notify-validate&mc_gross=244.00&protection_eligibility=Eligible&address_status=unconfirmed&payer_id=SJQRWD9JWG3WQ&tax=44.00&address_street=Via+Unit%1A+d%27Italia%2C+5783296&payment_date=05%3A52%3A43+Nov+21%2C+2013+PST&payment_status=Completed&charset=windows-1252&address_zip=80127&first_name=Spazioagenti&mc_fee=8.65&address_country_code=IT&address_name=Spazioagenti+Buyer¬ify_version=3.7&custom=3%7C14%7C2%7C10%7C244%7C7&payer_status=verified&business=seller%40spazioagenti.it&address_country=Italy&address_city=Napoli&quantity=10&verify_sign=AYoLATaZgB5cTatNJOgByicud-f2AZq2KG1cXXct8eRGc2LKOUoshqub&payer_email=buyer%40spazioagenti.it&txn_id=2LL473335A169684V&payment_type=instant&last_name=Buyer&address_state=Napoli&receiver_email=seller%40spazioagenti.it&payment_fee=&receiver_id=2N8MTA3G7BX2W&txn_type=web_accept&item_name=Pacchetto+Appuntamenti+per+Sorgenia&mc_currency=EUR&item_number=&residence_country=IT&test_ipn=1&handling_amount=0.00&transaction_subject=3%7C14%7C2%7C10%7C244%7C7&payment_gross=&shipping=0.00&ipn_track_id=d05cb7a39bc8d
[2013-11-21 14:52 Europe/Rome] HTTP response of validation request: HTTP/1.1 100 Continue
HTTP/1.1 200 OK
Date: Thu, 21 Nov 2013 13:52:48 GMT
Server: Apache
X-Frame-Options: SAMEORIGIN
Set-Cookie: c9MWDuvPtT9GIMyPc3jwol1VSlO=Gsyvkagbs7ElOYK0w0MSz-85N_LQTZUfWbDB5VEBBGSXea41hUfW8kgqvr3S64gHZtDYnHKAAnxhtUudwDEoAKfy_qcwPREwYFGlKypB27oMLdN0IX5Z8kuy9guw7vyR2dJVEuDwAtCRyivAANNzi_pB_b6GCdtDpqmefesbBv1XKrJc_HR675wuSqn7ECOeREJBn-P8Q5OrTCSYlsz62eE9oFM0gsVXWRGr3rX1DR_rlk-Z9OmIGRbScwwYPY6qm6oj-3IEtyZBltdvuH3PZdeRA0BCf46x773bJOgg_D50XwRzCSDo8hCVLPZRKDjrgVYjnd69TrELucb97rYChCPHuErWVO-9_RZNJQSvIIZp7cSSeCg9ktVthqYfbrgeBLmefARnHdcR0wqjjPlyp1GWJXL2pgseS87dtyZ2DdVKJfKaa2KRBFvmSoi; domain=.paypal.com; path=/; Secure; HttpOnly
Set-Cookie: cookie_check=yes; expires=Sun, 19-Nov-2023 13:52:48 GMT; domain=.paypal.com; path=/; Secure; HttpOnly
Set-Cookie: navcmd=_notify-validate; domain=.paypal.com; path=/; Secure; HttpOnly
Set-Cookie: navlns=0.0; expires=Sat, 21-Nov-2015 13:52:48 GMT; domain=.paypal.com; path=/; Secure; HttpOnly
Set-Cookie: Apache=10.72.109.11.1385041968439630; path=/; expires=Sat, 14-Nov-43 13:52:48 GMT
Connection: close
Set-Cookie: X-PP-SILOVER=name%3DSANDBOX3.WEB.1%26silo_version%3D880%26app%3Dslingshot%26TIME%3D806391378; domain=.paypal.com; path=/; Secure; HttpOnly
Set-Cookie: X-PP-SILOVER=; Expires=Thu, 01 Jan 1970 00:00:01 GMT
Set-Cookie: Apache=10.72.128.11.1385041968427891; path=/; expires=Sat, 14-Nov-43 13:52:48 GMT
Vary: Accept-Encoding
Strict-Transport-Security: max-age=14400
Transfer-Encoding: chunked
Content-Type: text/html; charset=UTF-8
VERIFIED
-----------------------------------------------------------------------------------------------------------------------------
[2013-11-21 15:03 Europe/Rome] HTTP request of validation request:POST /cgi-bin/webscr HTTP/1.1
Host: www.sandbox.paypal.com
Accept: */*
Connection: Close
Content-Length: 852
Content-Type: application/x-www-form-urlencoded
for IPN payload: cmd=_notify-validate&residence_country=US&invoice=abc1234&address_city=San+Jose&first_name=John&payer_id=TESTBUYERID01&shipping=3.04&mc_fee=0.44&txn_id=369761703&receiver_email=seller%40paypalsandbox.com&quantity=1&custom=xyz123&payment_date=05%3A53%3A46+21+Nov+2013+PST&address_country_code=US&address_zip=95131&tax=2.02&item_name=something&address_name=John+Smith&last_name=Smith&receiver_id=seller%40paypalsandbox.com&item_number=AK-1234&verify_sign=An5ns1Kso7MWUdW4ErQKJJJ4qi4-AdDhuqhHs5YWS2Bd.yigopmmBy7J&address_country=United+States&payment_status=Completed&address_status=confirmed&business=seller%40paypalsandbox.com&payer_email=buyer%40paypalsandbox.com¬ify_version=2.1&txn_type=web_accept&test_ipn=1&payer_status=verified&mc_currency=USD&mc_gross=12.34&address_state=CA&mc_gross1=9.34&payment_type=instant&address_street=123%2C+any+street
[2013-11-21 15:03 Europe/Rome] HTTP response of validation request: HTTP/1.1 200 OK
Date: Thu, 21 Nov 2013 14:03:33 GMT
Server: Apache
X-Frame-Options: SAMEORIGIN
Set-Cookie: c9MWDuvPtT9GIMyPc3jwol1VSlO=KR7iqlBBbqQKnRabL5TJ6Dnbg5xydQBOGeaPIRc-ShkauU79QmQF20HOui5yoQz2r3lXcrzoTn22w10461k6VaYZ1j8cP-Ps-GqlxqppLmaQfclCczIrDOLku7ewLjaSnETDJ4-zd3VLXpTT6Vv_FJeaBpNZkpAFO4yq6gCL48D40CcaOPEkBB7l-ZrW_6vKsByKiV2ocW5EMS-Zl1TqmNBGAFRh5WeWspN772rwHQJdBsUM4CljSWyM2e2H0Jzr3tpNJb9OMaq7BQcefNBc5jSWqLL_-GUpZ6BgtXL2urDFNjB3BuetscxsqwwR8cSX6wuY4gZRJ4-pE0vf-x_o6Ao4Sz-A9FgVM_gl5LO0RrJoYYj4yPzHncig0cwgBRF-_GB3S6sznJVnIkQMifoGuEIOkVisXl1jKMatG7YI3H8t5cqXyyqOYVxLp-y; domain=.paypal.com; path=/; Secure; HttpOnly
Set-Cookie: cookie_check=yes; expires=Sun, 19-Nov-2023 14:03:33 GMT; domain=.paypal.com; path=/; Secure; HttpOnly
Set-Cookie: navcmd=_notify-validate; domain=.paypal.com; path=/; Secure; HttpOnly
Set-Cookie: navlns=0.0; expires=Sat, 21-Nov-2015 14:03:33 GMT; domain=.paypal.com; path=/; Secure; HttpOnly
Set-Cookie: Apache=10.72.109.11.1385042613169322; path=/; expires=Sat, 14-Nov-43 14:03:33 GMT
Connection: close
Set-Cookie: X-PP-SILOVER=name%3DSANDBOX3.WEB.1%26silo_version%3D880%26app%3Dslingshot%26TIME%3D3037892178; domain=.paypal.com; path=/; Secure; HttpOnly
Set-Cookie: X-PP-SILOVER=; Expires=Thu, 01 Jan 1970 00:00:01 GMT
Set-Cookie: Apache=10.72.128.11.1385042613160303; path=/; expires=Sat, 14-Nov-43 14:03:33 GMT
Vary: Accept-Encoding
Strict-Transport-Security: max-age=14400
Transfer-Encoding: chunked
Content-Type: text/html; charset=UTF-8
VERIFIED
[2013-11-21 15:03 Europe/Rome] POST DATA: Array
(
[residence_country] => US
[invoice] => abc1234
[address_city] => San Jose
[first_name] => John
[payer_id] => TESTBUYERID01
[shipping] => 3.04
[mc_fee] => 0.44
[txn_id] => 369761703
[receiver_email] => seller#paypalsandbox.com
[quantity] => 1
[custom] => xyz123
[payment_date] => 05:53:46 21 Nov 2013 PST
[address_country_code] => US
[address_zip] => 95131
[tax] => 2.02
[item_name] => something
[address_name] => John Smith
[last_name] => Smith
[receiver_id] => seller#paypalsandbox.com
[item_number] => AK-1234
[verify_sign] => An5ns1Kso7MWUdW4ErQKJJJ4qi4-AdDhuqhHs5YWS2Bd.yigopmmBy7J
[address_country] => United States
[payment_status] => Completed
[address_status] => confirmed
[business] => seller#paypalsandbox.com
[payer_email] => buyer#paypalsandbox.com
[notify_version] => 2.1
[txn_type] => web_accept
[test_ipn] => 1
[payer_status] => verified
[mc_currency] => USD
[mc_gross] => 12.34
[address_state] => CA
[mc_gross1] => 9.34
[payment_type] => instant
[address_street] => 123, any street
)
[2013-11-21 15:03 Europe/Rome] Verified IPN: cmd=_notify-validate&residence_country=US&invoice=abc1234&address_city=San+Jose&first_name=John&payer_id=TESTBUYERID01&shipping=3.04&mc_fee=0.44&txn_id=369761703&receiver_email=seller%40paypalsandbox.com&quantity=1&custom=xyz123&payment_date=05%3A53%3A46+21+Nov+2013+PST&address_country_code=US&address_zip=95131&tax=2.02&item_name=something&address_name=John+Smith&last_name=Smith&receiver_id=seller%40paypalsandbox.com&item_number=AK-1234&verify_sign=An5ns1Kso7MWUdW4ErQKJJJ4qi4-AdDhuqhHs5YWS2Bd.yigopmmBy7J&address_country=United+States&payment_status=Completed&address_status=confirmed&business=seller%40paypalsandbox.com&payer_email=buyer%40paypalsandbox.com¬ify_version=2.1&txn_type=web_accept&test_ipn=1&payer_status=verified&mc_currency=USD&mc_gross=12.34&address_state=CA&mc_gross1=9.34&payment_type=instant&address_street=123%2C+any+street
The code I'm using for the IPN listener is this:
// CONFIG: Enable debug mode. This means we'll log requests into 'ipn.log' in the same directory.
// Especially useful if you encounter network errors or other intermittent problems with IPN (validation).
// Set this to 0 once you go live or don't require logging.
define("DEBUG", 1);
// Set to 0 once you're ready to go live
define("USE_SANDBOX", 1);
define("LOG_FILE", "./ipn.log");
// Read POST data
// reading posted data directly from $_POST causes serialization
// issues with array data in POST. Reading raw POST data from input stream instead.
$raw_post_data = file_get_contents('php://input');
$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 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";
}
// Post IPN data back to PayPal to validate the IPN data is genuine
// Without this step anyone can fake IPN data
if(USE_SANDBOX == true) {
$paypal_url = "https://www.sandbox.paypal.com/cgi-bin/webscr";
} else {
$paypal_url = "https://www.paypal.com/cgi-bin/webscr";
}
$ch = curl_init($paypal_url);
if ($ch == FALSE) {
return FALSE;
}
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);
if(DEBUG == true) {
curl_setopt($ch, CURLOPT_HEADER, 1);
curl_setopt($ch, CURLINFO_HEADER_OUT, 1);
}
// CONFIG: Optional proxy configuration
//curl_setopt($ch, CURLOPT_PROXY, $proxy);
//curl_setopt($ch, CURLOPT_HTTPPROXYTUNNEL, 1);
// Set TCP timeout to 30 seconds
curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 30);
curl_setopt($ch, CURLOPT_HTTPHEADER, array('Connection: Close'));
// CONFIG: Please download 'cacert.pem' from "http://curl.haxx.se/docs/caextract.html" and set the directory path
// of the certificate as shown below. Ensure the file is readable by the webserver.
// This is mandatory for some environments.
//$cert = __DIR__ . "./cacert.pem";
//curl_setopt($ch, CURLOPT_CAINFO, $cert);
$res = curl_exec($ch);
if (curl_errno($ch) != 0) // cURL error
{
if(DEBUG == true) {
error_log(date('[Y-m-d H:i e] '). "Can't connect to PayPal to validate IPN message: " . curl_error($ch) . PHP_EOL, 3, LOG_FILE);
}
curl_close($ch);
exit;
} else {
// Log the entire HTTP response if debug is switched on.
if(DEBUG == true) {
error_log(date('[Y-m-d H:i e] '). "HTTP request of validation request:". curl_getinfo($ch, CURLINFO_HEADER_OUT) ." for IPN payload: $req" . PHP_EOL, 3, LOG_FILE);
error_log(date('[Y-m-d H:i e] '). "HTTP response of validation request: $res" . PHP_EOL, 3, LOG_FILE);
// Split response headers and payload
list($headers, $res) = explode("\r\n\r\n", $res, 2);
}
curl_close($ch);
}
// Inspect IPN validation result and act accordingly
if (strcmp ($res, "VERIFIED") == 0) {
error_log(date('[Y-m-d H:i e] '). "POST DATA: ". print_r($_POST, true) . PHP_EOL, 3, LOG_FILE);
// check whether the payment_status is Completed
// check that txn_id has not been previously processed
// check that receiver_email is your PayPal email
// check that payment_amount/payment_currency are correct
// process payment and mark item as paid.
// 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'];
if(DEBUG == true) {
mail('anooxy#gmail.com', 'Verified IPN', 'verified');
error_log(date('[Y-m-d H:i e] '). "Verified IPN: $req ". PHP_EOL, 3, LOG_FILE);
}
} else if (strcmp ($res, "INVALID") == 0) {
// log for manual investigation
// Add business logic here which deals with invalid IPN messages
if(DEBUG == true) {
mail('anooxy#gmail.com', 'Invalid IPN', 'not verified');
error_log(date('[Y-m-d H:i e] '). "Invalid IPN: $req" . PHP_EOL, 3, LOG_FILE);
}
}
I'm assuming there's something wrong with my form? I added everything as suggested by PayPal Javascript buttons
Here's my buy no button form HTML code:
<form method="post" action="https://www.sandbox.paypal.com/cgi-bin/webscr" class="paypal-button" target="_top">
<input type="hidden" name="button" value="buynow">
<input type="hidden" name="item_name" value="Pacchetto Appuntamenti per Sorgenia">
<input type="hidden" name="amount" value="20">
<input type="hidden" name="currency_code" value="EUR">
<input type="hidden" name="quantity" value="10">
<input type="hidden" name="tax_rate" value="22">
<input type="hidden" name="lc" value="IT">
<input type="hidden" name="env" value="www.sandbox">
<input type="hidden" name="return" value="http://test.xxxxx.it/utente/storicoordini">
<input type="hidden" name="notify_url" value="http://test.xxxxx.it/utente/ipn">
<input type="hidden" name="custom" value="3|14|2|10|244|7">
<input type="hidden" name="rm" value="2"><input type="hidden" name="cmd" value="_xclick">
<input type="hidden" name="business" value="2N8MTA3G7BX2W">
<input type="hidden" name="bn" value="JavaScriptButton_buynow">
<button type="submit" class="paypal-button large">Buy Now</button>
</form>
You're only splitting out the headers IF debug is on. Perhaps that's the problem. I'm not sure why you bother to pull out the headers as the response is going to be exactly the same plus VERIFIED (or not). I just match against the entire response.
if (preg_match("!(VERIFIED)\s*\Z!",$res))
{ /*payment verified, handle */ }
else
{ /* boo fake payment OR paypal is having problems */ }