robmcvey/cakephp-paypal — pull request #20 by riteshkhadka (2014-08-06 06:27:34+00:00)
Title: Working with IPN and doDirectPayment credit card.

Changes in code to track IPN response. Can you check with following codes if the response is verified. I got payment status completed but could not get the last response send as "Verified" from paypal.

Login to your paypal sandbox account and enable IPN Notification
1) Add following parameters before executing function
$this->Paypal->doDirectPayment($payment)
///code to add
$payment = array(
'notifyurl' => 'Your notify url',
'custom' => 'custom parameters like last inserted id'
);

2) Plugin/Paypal/Lib/Paypal.php
Pass below variable to paypal from the function formatDoDirectPaymentNvps()
//set variable to pass to paypal
$nvps = array(
'NOTIFYURL' => $payment['notifyurl'],
'CUSTOM' => $payment['custom']
);

3) Track IPN Response which is silently passed by the paypal. Create a function in your controller to handle the IPN reponse.The link is provided in the paypal documentation (https://gist.github.com/xcommerce-gists/3440401)

//function to track paypal IPN Response
public function notify_url(){

// STEP 1: read POST data

// Reading POSTed data directly from $_POST causes serialization issues with array data in the POST.
// Instead, read raw POST data from the input stream.
$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 IPN message sent from PayPal and prepend 'cmd=_notify-validate'
$req = 'cmd=_notify-validate';
if(function_exists('get_magic_quotes_gpc')) {
$get_magic_quotes_exists = true;
}
foreach ($myPost as $key => $value) {
if($get_magic_quotes_exists == true && get_magic_quotes_gpc() == 1) {
$value = urlencode(stripslashes($value));
} else {
$value = urlencode($value);
}
$req .= "&$key=$value";
}

// STEP 2: POST IPN data back to PayPal to validate

$ch = curl_init('https://www.paypal.com/cgi-bin/webscr');
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);
curl_setopt($ch, CURLOPT_HTTPHEADER, array('Connection: Close'));

// In wamp-like environments that do not come bundled with root authority certificates,
// please download 'cacert.pem' from "http://curl.haxx.se/docs/caextract.html" and set
// the directory path of the certificate as shown below:
// curl_setopt($ch, CURLOPT_CAINFO, dirname(__FILE__) . '/cacert.pem');
if( !($res = curl_exec($ch)) ) {
// error_log("Got " . curl_error($ch) . " when processing IPN data");
curl_close($ch);
exit;
}
curl_close($ch);

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

if (strcmp ($res, "VERIFIED") == 0) {
// The IPN is verified, process it:
// check whether the payment_status is Completed
// check that txn_id has not been previously processed
// check that receiver_email is your Primary PayPal email
// check that payment_amount/payment_currency are correct
// process the notification

// 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'];
$custom = $_POST['custom'];//added by Ritesh
// IPN message values depend upon the type of notification sent.
// To loop through the &_POST array and print the NV pairs to the screen:
foreach($_POST as $key => $value) {
echo $key." = ". $value."
";
}
//update your table

} else if (strcmp ($res, "INVALID") == 0) {
// IPN invalid, log for manual investigation

}

}

Response format from Paypal IPN
mc_gross=1.00&protection_eligibility=Ineligible&payer_id=********&tax=0.00&payment_date=04%3A53%3A14+Jul+25%2C+2014+PDT&payment_status=Completed&charset=windows-1252&first_name=&mc_fee=0.33¬ify_version=3.8&custom=76&payer_status=unverified&business=**********&quantity=1&verify_sign=****************&txn_id=26674131GT652710L&payment_type=instant&last_name=&receiver_email=************&payment_fee=0.33&receiver_id=*********&txn_type=web_accept&item_name=&mc_currency=USD&item_number=&residence_country=US&test_ipn=1&receipt_id=1598-3406-0475-9379&handling_amount=0.00&transaction_subject=&payment_gross=1.00&shipping=0.00&ipn_track_id=491aa84bbe078