Cakephp 3 Paypal IPN not reading post data - php

I have integrated Paypal IPN into my Cakephp but no matter what I do, the file_get_contents('php://input') function is not reading the data coming back from the Paypal.
If I run the same code natively outside the Cakephp framework, it works perfectly.
In my error log, the last text I get says [2017-06-16 17:19 UTC] Invalid IPN: cmd=_notify-validate
Any ideas as to what I'm doing wrong? Thanks in advance.
public function jawaab()
{
define("DEBUG", 1);
// Set to 0 once you're ready to go live
define("USE_SANDBOX", 1);
define("LOG_FILE", "master_error.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);
$counter = 0;
$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'));
// 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 ($res == "VERIFIED"){
error_log("\r\n\r\n I AM IN -- \r\n\r\n " . PHP_EOL, 3, LOG_FILE);
// 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'];
// include("dbcontroller.php");
// $db = new DBController();
// check whether the payment_status is Completed
$isPaymentCompleted = false;
if($payment_status == "Completed") {
$isPaymentCompleted = true;
}
// check that txn_id has not been previously processed
$isUniqueTxnId = false;
$result = $this->Payments->find('all', ['conditions' => ['txn_id = ' => '$txn_id' ]]);
if(empty($result)) {
$isUniqueTxnId = true;
}
// check that receiver_email is your PayPal email
// check that payment_amount/payment_currency are correct
if($isPaymentCompleted && $isUniqueTxnId) {
$paymentsTable = TableRegistry::get('Payments');
$paymnt = $paymentsTable->newEntity();
$paymnt->booking_id = $item_number;
$paymnt->item_name = $item_name;
$paymnt->payment_status = $payment_status;
$paymnt->payment_amount = $payment_amount;
$paymnt->payment_currency = $payment_currency;
$paymnt->txn_id = $txn_id;
if ($paymentsTable->save($paymnt)) {
// The $payment entity contains the id now
$id = $paymnt->id;
}
if(($paymentsTable->save($paymnt)))
{
$bookingsTable = TableRegistry::get('Bookings');
$bookngs = $bookingsTable->get($item_number); // Return article with id 12
$bookngs->status = 1;
$bookingsTable->save($bookngs);
}
// else
//{
// $errori = $qry;
//}
}
else
{
error_log(date('[Y-m-d H:i e] '). "\r\n\r\n Something is not true - $isPaymentCompleted -- $isUniqueTxnId -- \r\n\r\n " . PHP_EOL, 3, LOG_FILE);
}
// process payment and mark item as paid.
if(DEBUG == true) {
error_log(date('[Y-m-d H:i e] '). "Verified IPN: $req $errori". PHP_EOL, 3, LOG_FILE);
}
}
else
{
error_log("\r\n\r\n $res $counter \r\n\r\n". PHP_EOL, 3, LOG_FILE);
$counter = $counter+1;
}
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 $errori" . PHP_EOL, 3, LOG_FILE);
}
}
}

Related

PayPal IPN always returning INVALID?

I know this question has been asked before and I found a few and followed every single one of them to fix this issue but I haven't been able to.
Basically, I am using this PHP IPN code. This code used to work fine but now it thorws invalid error in th elog file!
Most of the similar questions that I came across was pointing to the payment_date and everyone mentioned that the date should be set to NULL in the IPN smulator which I did that but I still get the INVALID error.
This is my IPN code:
<?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) {
$item_number = $_POST['item_number'];
//$custom = $_POST['custom'];
$payer_email = $_POST['payer_email'];
$myfile = fopen("logs.txt", "a") or die("Unable to open file!");
$txt = $payer_email ;
fwrite($myfile, "\n". $txt);
fclose($myfile);
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);
}
}
?>
Could someone please advice on this issue?
Thanks in advance.

Paypal IPN failing for some payments

I got the following code:
<?php
define('BASEPATH', true);
require('../../config.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);
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, 60);
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
$tokens = explode("\r\n\r\n", $res); // Avoid passing 2 as the last argument, so the remaining token can be picked up
$res = trim(end($tokens)); // Set $res to be the last token in the response
}
curl_close($ch);
}
// Inspect IPN validation result and act accordingly
if (strcmp ($res, "VERIFIED") == 0) {
// process payment and mark item as paid.
$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'];
$custom = $_POST['custom'];
$get_data = explode('|', $custom);
if($payment_status == 'Completed'){
//
// DO SOMETHING...
//
} else if (DEBUG == true) {
error_log(date('[Y-m-d H:i e] '). "Invalid Payment Status: $payment_status" . PHP_EOL, 3, LOG_FILE);
}
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) {
if(DEBUG == true) {
error_log(date('[Y-m-d H:i e] '). "Invalid IPN: $req" . PHP_EOL, 3, LOG_FILE);
}
} else {
if(DEBUG == true) {
error_log(date('[Y-m-d H:i e] '). "Response log: $res" . PHP_EOL, 3, LOG_FILE);
}
}
?>
This code has been working for more than 2 years without any issues but a few months ago some payments started to fail for whatever reason and Paypal started to send IPN failed warning emails and stuff...
I am trying to locate the issue without any luck. All test notifications from Paypals IPN Simulator work just fine but as soon as someone makes a legit payment it's not registered. In some rare cases the payment is registered.
Could someone point me in the right direction please?
I don't know why your code is failing but you can try using Paypal's own code here
https://github.com/paypal/ipn-code-samples/tree/master/php

Paypal IPN keeps failing in Paypal's opinion

I use the following listener based on the PHP sample provided by Paypal to process their IPN (I'm using Symfony) :
public function paypalIPNListenerAction(){
// 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("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);
}
// 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__ . "/../../../../web/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));
error_log(date('[Y-m-d H:i e] ')." verified ? : ".strcmp($res, 'VERIFIED')." $res : ".$res. PHP_EOL, 3, LOG_FILE);
if(DEBUG == true)
error_log(date('[Y-m-d H:i e] ')." verified ? : ".strcmp($res, "VERIFIED")." response : ".$res);
if (strcmp ($res, "VERIFIED") == 0) {
$em = $this->getdoctrine();
$manager = $em->getmanager();
$id = $myPost['custom'];
$payment_status = $myPost['payment_status'];
$payment_amount = $myPost['mc_gross'];
$payment_currency = $myPost['mc_currency'];
$txn_id = $myPost['txn_id'];
$receiver_email = $myPost['receiver_email'];
$processed = $em->getrepository("ArtforsmileMainBundle:Panier")->getbytxn($txn_id);
if(!$processed && $payment_status == "completed" && $payment_currency == "eur" && $receiver_email == "xxxxxxxxxxx#xxxxx.xxxxx"){
/* Interacting with the database */
}
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);
}
}
return new Response("ok", Response::HTTP_OK, array('Content-Type' => 'text/plain'));
}
The IPN are received and answered by the server and the database updated but Paypal keeps thinking they failed. What did I forget ?
Thank you by advance.

php - PayPal IPN working on sandbox but not live

I've got this PayPal IPN script, tested it in sandbox mode and it works perfectly but when I use it in live mode it doesn't work. No errors or other. What should I do to fix this issue?
<?php
define("DEBUG", 0);
define("USE_SANDBOX", 0);
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, 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);
}
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)
{
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);
}
$tokens = explode("\r\n\r\n", trim($res));
$res = trim(end($tokens));
if (strcmp ($res, "VERIFIED") == 0) {
$receiver_email = $_POST['receiver_email'];
$payer_email = $_POST['payer_email'];
$payment_status = $_POST['payment_status'];
$item_number = $_POST['item_number'];
if($payment_status == 'Completed') {
require_once("../assets/includes/core.php");
require_once("../assets/includes/settings.php");
if(USE_SANDBOX == true) {
$rec_email = "sandboxemail#email.com";
} else {
$rec_email = "mypaypalemail#email.com";
}
if($receiver_email == $rec_email) {
$con = mysql_connect($dbhost,$dbuser,$dbpass);
mysql_select_db('website');
function generateString($length)
{
$charset = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789_-";
for($i=0; $i<$length; $i++)
$key .= $charset[(mt_rand(0,(strlen($charset)-1)))];
return $key;
}
$code = generateString("30");
$insert_code = mysql_query("INSERT INTO `$dbtable_wsc` (`code`,`payer_email`,`item_number`,`used`,`gen_date`) VALUES('$code','$payer_email','$item_number','no', NOW())") or die("MYSQL INSERT CODE QUERY ERROR: " . mysql_error());
mysql_close($con);
require("phpmailer/class.phpmailer.php");
$mail = new PHPMailer();
$mail->IsSMTP();
$mail->SMTPAuth = true;
$mail->Host = "ssl://smtp.gmail.com";
$mail->Port = 465;
$mail->Username = "mydomain#email.com";
$mail->Password = "******";
$mail->FromName = "mydomain";
$mail->Subject = "mydomain | Redeem Code";
$mail->Body = "
Your redeem code is ".$code."
To use your code click here: $root_link/webshop/red.php?code=".$code."&step=step2
Thank you for have given your support with a donation to mydomain, we really appreciate it!
mydomain";
$mail->AddAddress($payer_email);
if(!$mail->Send()){
echo "Mailer Error. Contact our Support Team giving them this error: " . $mail->ErrorInfo;
}
echo "Email sent to $payer_email with the redeem code. If you didn't received your email go <a href='./red.php'>there</a> to redeem you code.";
} else {
die("You are trying to pay to the wrong 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) {
if(DEBUG == true) {
error_log(date('[Y-m-d H:i e] '). "Invalid IPN: $req" . PHP_EOL, 3, LOG_FILE);
}
}
?>
Tested this several times in sandbox mode but each time I set this live and my customers try to buy something all works exept the IPN confirmation so they don't get anything. I also would like some suggestions on how I could make better checks for ensure the payment has not been already processed or is not a fake one. Thanks!
P.S. I'm aware of the mysql extension of php being deprecated but currently that's not my main problem.
Didn't read the code, but I know for me I looked and there was two different ITNs: one for live, and one for sandbox.
Had to set them both
Hope that helps

Paypal IPN verified but not updating database

I'm using paypal IPN Sandbox to update the tables in my database when payment received. Based in my ipn log its shows OK and Verified. Here is my ipn. Also I cant receive email from my IPN.
include ('conn.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(trim($res), "VERIFIED") == 0) {
$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'];
$fee = $_POST['mc_fee'];
$citems = $_POST['num_cart_items'];
$orderID = $_POST['custom'];
$status = "Complete";
$orderstatus = "Processing";
if($payment_status == "Completed"){
$getinfo_sql = " SELECT * FROM orders a, users b
where
a.userID = b.userID
a.orderID = '$orderID'";
$getinfo = mysqli_query ($conn, $getinfo_sql);
while ($getinfo = mysqli_fetch_assoc($getinfo))
{
$custemail = $getinfo['email'];
$paymode = $getinfo['paymentmode'];
}
if($paymode == "Full Payment")
{
// date_default_timezone_set('Asia/Manila');
//
//$currentdate = date("y-m-d");
//$currentTime = date("g:i:s a");
//$audit = "INSERT INTO tbl_audittrail( username , action, `date`, `time` ) VALUES( '$sname' , '$action', '$currentdate', '$currentTime') ";
//mysql_query($audit) or die(mysql_error());
//
$checkn = mysqli_query($conn, "SELECT * FROM notifications where orderID ='$orderID'");
while($notifs= mysql_fetch_assoc($checkn))
{
$notifIDs = $notifs["notificationID"];
}
$seen = 0;
$stat= "Processing: Full Payment";
$updatenotif = mysqli_query($conn,"Update notifications set seen=0, details = '$stat' where notificationID ='$notifIDs'");
$message = " We have received the payment for your order OrderID: $orderID \n \n ";
$message .= "You can download the receipt at your Order History";
$message .= "For more info about your Order Call us at 611-1111 / 622-2222 / 633-3333";
$message .="\n \n Thanks, \n MVRAM ";
mail($custemail, 'Payment Received', $message, 'From:noreply#dbtk.megabuslines.biz');
mysql_query($conn,"UPDATE orders SET `paymentstatus` = '".$status."', `orderstatus` = '".$status."' WHERE `orderID` = '".$orderID."'") or die(mysql_error());
}
}else{
}
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 suggest you break the code into parts that can be debugged and fixed more easily.
Since you're working with PayPal IPN, you should first test that the IPN response is correctly recieved and verified.
If your logger works, then first debug that part using the log file.
If you find troubles fix the part of getting IPN data and verifying.
Once you're sure that the first part of IPN works you continue debugging the rest of the code faster by using this technique:
1) Test the IPN again and write the contents of $_POST into your log file using the returns of var_export($_POST, true)
2) Open your log file and check that you'll have there the full array of $_POST that IPN sent you
3) Copy that array and fake your original $_POST data into your script: $_POST = array(..fields from the log..);
4) Now comment out all the first part of the script that does the IPN verification, and only leave there the faked $_POST
5) Now you can manually access your script as if you were the PayPal's IPN robot by opening example.com/paypal_ipn_script.php
Now you can continue debugging the rest of your script's sql queries and see which is failing, by hitting F5 and using print_r(), var_dump(), die(), etc. All this without having to make a new paypal payment for every test and so speed up the debugging process :)
I'm using paypal IPN Sandbox to update the tables in my database when payment received.Try this code full start to end .
$data = $_POST;
$url = 'https://www.sandbox.paypal.com/cgi-bin/webscr';
$data['cmd'] = '_notify-validate';
$curl = curl_init();
curl_setopt_array(
$curl,
array(
CURLOPT_RETURNTRANSFER => 1,
CURLOPT_FOLLOWLOCATION => 1,
CURLOPT_POST => 1,
CURLOPT_SSL_VERIFYPEER => false,
CURLOPT_URL => $url,
CURLOPT_POSTFIELDS => $data
)
);
if(!($result = curl_exec($curl))){
die('Error: "' . curl_error($curl) . '" - Code: ' . curl_errno($curl));
}
curl_close($curl);
if ($result != 'VERIFIED') {
die('Fraud IPN on Varification.');
}
$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'];
$ctIdcustom = $_POST['custom'];
//your action here

Categories