Running a script when I receive PayPal payment [closed] - php

This question is unlikely to help any future visitors; it is only relevant to a small geographic area, a specific moment in time, or an extraordinarily narrow situation that is not generally applicable to the worldwide audience of the internet. For help making this question more broadly applicable, visit the help center.
Closed 10 years ago.
I want to set things up so that when a user pays me through PayPal, a PHP script will be run. How can I set up this kind of notification?

It's called an IPN.
You just need to go into your settings, enable the IPN, tell it what file will be handling the call back and then write your php file.

Here's how I handle paypal ipns with php
<?php
if($_POST){
// read the post from PayPal system and add 'cmd'
$req = 'cmd=_notify-validate';
foreach ($_POST as $key => $value) {
$value = urlencode(stripslashes($value));
$req .= "&$key=$value";
}
// post back to PayPal system to validate
$header .= "POST /cgi-bin/webscr HTTP/1.0\r\n";
$header .= "Content-Type: application/x-www-form-urlencoded\r\n";
$header .= "Content-Length: " . strlen($req) . "\r\n\r\n";
$fp = fsockopen ('ssl://www.paypal.com', 443, $errno, $errstr, 30);
if (!$fp) {
// HTTP ERROR
} else {
fputs ($fp, $header . $req);
while (!feof($fp)) {
$res = fgets ($fp, 1024);
if (strcmp ($res, "VERIFIED") == 0) {
// check the payment_status is Completed
// assign posted variables to local variables - NOT NECESSARY..
$receiver_email = mysql_real_escape_string($_POST['receiver_email']);
$payer_email = mysql_real_escape_string($_POST['payer_email']);
$business_id = mysql_real_escape_string($_POST['item_number']);
$payment_gross = mysql_real_escape_string($_POST['mc_gross']);
$item_name = mysql_real_escape_string($_POST['item_name']);
$currency = mysql_real_escape_string($_POST['mc_currency']);
$payment_date = mysql_real_escape_string($_POST['payment_date']);
$payment_status = mysql_real_escape_string($_POST['payment_status']);
$address_street = mysql_real_escape_string($_POST['address_street']);
$first_name = mysql_real_escape_string($_POST['first_name']);
$last_name = mysql_real_escape_string($_POST['last_name']);
$address_street = mysql_real_escape_string($_POST['address_street']);
$address_city = mysql_real_escape_string($_POST['address_city']);
$address_state = mysql_real_escape_string($_POST['address_state']);
$address_country_code = mysql_real_escape_string($_POST['address_country_code']);
$address_zip = mysql_real_escape_string($_POST['address_zip']);
$quantity = mysql_real_escape_string($_POST['quantity']);
$payment_fee = mysql_real_escape_string($_POST['mc_fee']);
$address_name = mysql_real_escape_string($_POST['address_name']);
$payment_type = mysql_real_escape_string($_POST['payment_type']);
$payer_business_name = mysql_real_escape_string($_POST['payer_business_name']);
$item_number = mysql_real_escape_string($_POST['item_number']);
$transaction_subject = mysql_real_escape_string($_POST['transaction_subject']);
$parent_txn_id = mysql_real_escape_string($_POST['parent_txn_id']);
$txn_id = mysql_real_escape_string($_POST['txn_id']);
$custom = mysql_real_escape_string($_POST['custom']);
//insert into payments table
$result = mysql_query("INSERT INTO payments (payment_date, payment_type, receiver_email, payer_email, gross_amt, quantity, currency, payment_status, paypal_fee, transaction_subject, item_name, item_number, first_name, last_name, payer_business_name, address_name, address_street,address_city,address_state,address_zip,address_country_code,parent_txn_id, txn_id, custom) VALUES ('$payment_date','$payment_type', '$receiver_email', '$payer_email', '$payment_gross','$quantity','$currency','$payment_status','$payment_fee','$transaction_subject','$item_name','$item_number','$first_name','$last_name','$payer_business_name','$address_name','$address_street','$address_city','$address_state','$address_zip','$address_country_code','$parent_txn_id','$txn_id','$custom')") or die(mysql_error());
//end of if invalid
}
else if (strcmp ($res, "INVALID") == 0) {
// log for manual investigation
}
}
fclose ($fp);
}
//end of post
}
?>

PayPal offers the Instant Payment Notification system which you have to set up through your account.
Here is the link to their guide to get you started.
https://cms.paypal.com/cms_content/US/en_US/files/developer/IPNGuide.pdf
Also they offer a template for your IPN listener. Here is the one in PHP:
<?php
// read the post from PayPal system and add 'cmd'
$req = 'cmd=' . urlencode('_notify-validate');
foreach ($_POST as $key => $value) {
$value = urlencode(stripslashes($value));
$req .= "&$key=$value";
}
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, 'https://www.paypal.com/cgi-bin/webscr');
curl_setopt($ch, CURLOPT_HEADER, 0);
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_HTTPHEADER, array('Host: www.paypal.com'));
$res = curl_exec($ch);
curl_close($ch);
// 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 (strcmp ($res, "VERIFIED") == 0) {
// check 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 payment
}
else if (strcmp ($res, "INVALID") == 0) {
// log for manual investigation
}
?>

Related

Paypal IPN Sandbox - IPN Listener - no verified or invalid

I have set up test accounts Business and Personal in developer for trying out sandbox mode.
I have made a payment button on my site. I click the button and go to paypal.
Test user personal account is used for paying.
Payment goes through and is Completed when i look in the Paypal business account.
Redirect to my site works good.
So in my eyes i should have a "working" system.
My IPN Listener though does not return either verified or invalid.
This is my listener:
<?php
require("../widgets/init.inc.php");
//Test the script is launced
$log_query = mysql_query("INSERT INTO `log` VALUES (' ','zz','ff','rr', 'rr')");
// Link to PayPal Codes //
// https://cms.paypal.com/us/cgi-bin/?cmd=_render-content&content_ID=developer/e_howto_html_IPNandPDTVariables //
// read the post from PayPal system and add 'cmd' //
$req = 'cmd=_notify-validate';
foreach ($_POST as $key => $value) {
$value = urlencode(stripslashes($value));
$req .= "&$key=$value";
}
// post back to PayPal system to validate //
$header .= "POST /cgi-bin/webscr HTTP/1.0\r\n";
$header .= "Content-Type: application/x-www-form-urlencoded\r\n";
$header .= "Content-Length: " . strlen($req) . "\r\n\r\n";
//For the below line i have tried "www.sandbox.paypal" as well as "www.paypal"
$fp = fsockopen ('ssl://www.paypal.com', 443, $errno, $errstr, 30);
// 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'];
$txnId = $_POST['txn_id'];
$receiverEmail = $_POST['receiver_email'];
$payerEmail = $_POST['payer_email'];
//$id = ($_POST['custom']);
if (!$fp) {
} else {
fputs ($fp, $header . $req);
while (!feof($fp)) {
$res = fgets ($fp, 1024);
if (strcmp ($res, "VERIFIED") == 0) {
if ($payment_status=='Completed') {
//$txnIdCheck = mysql_query("SELECT `txnId` FROM `log` WHERE `txnId`='".$txnId."'");
//if (mysql_num_rows($txnIdCheck) !=1) {
// enter your email address associated with your paypal account here //
if ($receiverEmail=='biztester1#mydomain.dk') {
/* when a new premium member makes payment paypal will update our database. The txn_id from paypal, members email address, date of payment and members id we gave them when they joined our site will be inserted into the log table. At the same time the memberAdmin table for the member will be updated by adding a '1' to premium and the date of payment so the new premium member will have access to premium areas of your site. */
//Check if verified is launced
$log_query_2 = mysql_query("INSERT INTO `log` VALUES (' ','yes','yes','yes', 'yes')");
//$log_query = mysql_query("INSERT INTO `log` VALUES (' ','".intval($id)."','".$txnId."','".$payerEmail."', now())");
//$update_premium = mysql_query("UPDATE `memberAdmin` SET `premium`=1, `premiumDate`=now() WHERE `id`=".intval($id)."");
}
//}
}
}
else if (strcmp ($res, "INVALID") == 0) {
//Check if invalid is launced
$log_query_2 = mysql_query("INSERT INTO `log` VALUES (' ','no','no','no', 'no'");
}
}
fclose ($fp);
}
?>
I have activated the IPN at the paypal business account site.
I have made a txt file of the returned information from paypal, and it looks like this:
==== Thu, 18 Jul 2013 01:34:21 +0200 ====
POST: mc_gross = 0.01
POST: protection_eligibility = Ineligible
POST: payer_id = 73WPPK8HKSW7C
POST: tax = 0.00
POST: payment_date = 15:15:20 Jul 17, 2013 PDT
POST: payment_status = Completed
POST: charset = windows-1252
POST: first_name = Niels
POST: mc_fee = 0.01
POST: notify_version = 3.7
POST: payer_status = verified
POST: business = biztester1#mydomain.dk
POST: quantity = 1
POST: verify_sign = A-ddKAwtxju4TpHGJOGq6c3ewj26AyiHsD.XO90coZ.4rVzOT7VyooKO
POST: payer_email = tester1#mydomain.dk
POST: txn_id = 6WH41489RE087103M
POST: payment_type = instant
POST: last_name = Tester
POST: receiver_email = biztester1#mydomain.dk
POST: payment_fee = 0.01
POST: receiver_id = PCX638B2M7WPA
POST: txn_type = web_accept
POST: item_name = 500Credits
POST: mc_currency = USD
POST: item_number = 1
POST: residence_country = DE
POST: test_ipn = 1
POST: handling_amount = 0.00
POST: transaction_subject = 500Credits
POST: payment_gross = 0.01
POST: shipping = 0.00
POST: ipn_track_id = 2dffcbf8767d3
InvoiceID:
Custom1:
Custom2:
Custom3:
It seems like it is a lot harder to get this to work than what I think it should be.
I found the problem.. AND THE ANNOYING THING IS THAT PAYPAL DOCUMENTATION IS WRONG AGAIN.. I don't understand that the documentation can state press this button and press this button.. WHEN there are no buttons like this in the site...
For this problem - The documentation does state a wrong method / does not include full code needed.
THE PROBLEM:
The $res returned this:
HTTP/1.0 400 Bad Request
Server: BigIP
Connection: close
Content-Length: 19
Invalid Host header
what needs to be added is :
$header .= "Host: www.sandbox.paypal.com\r\n";
AND then the above code looks like this:
// post back to PayPal system to validate //
$header .= "POST /cgi-bin/webscr HTTP/1.0\r\n";
$header .= "Host: www.sandbox.paypal.com\r\n";
$header .= "Content-Type: application/x-www-form-urlencoded\r\n";
$header .= "Content-Length: " . strlen($req) . "\r\n\r\n";
$fp = fsockopen ('ssl://www.sandbox.paypal.com', 443, $errno, $errstr, 30);
This was the full code i ended up using:
<?php
require("../widgets/init.inc.php");
// Link to PayPal Codes //
// https://cms.paypal.com/us/cgi-bin/?cmd=_render-content&content_ID=developer/e_howto_html_IPNandPDTVariables //
// read the post from PayPal system and add 'cmd' //
$req = 'cmd=_notify-validate';
foreach ($_POST as $key => $value) {
$value = urlencode(stripslashes($value));
$req .= "&$key=$value";
}
// post back to PayPal system to validate //
$header .= "POST /cgi-bin/webscr HTTP/1.0\r\n";
$header .= "Host: www.sandbox.paypal.com\r\n";
$header .= "Content-Type: application/x-www-form-urlencoded\r\n";
$header .= "Content-Length: " . strlen($req) . "\r\n\r\n";
$fp = fsockopen ('ssl://www.sandbox.paypal.com', 443, $errno, $errstr, 30);
// 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'];
$txnId = $_POST['txn_id'];
$receiverEmail = $_POST['receiver_email'];
$payerEmail = $_POST['payer_email'];
//$id = ($_POST['custom']);
if (!$fp) {
} else {
fputs ($fp, $header . $req);
while (!feof($fp)) {
$res = fgets ($fp, 1024);
$log_query_pre = mysql_query("INSERT INTO `log` VALUES (' ','$receiverEmail','$payment_status','$res', 'yes')");
if (strcmp ($res, "VERIFIED") == 0) {
if ($payment_status=='Completed') {
//$txnIdCheck = mysql_query("SELECT `txnId` FROM `log` WHERE `txnId`='".$txnId."'");
//if (mysql_num_rows($txnIdCheck) !=1) {
// enter your email address associated with your paypal account here //
if ($receiverEmail=='biztester1#mydomain.dk') {
/* when a new premium member makes payment paypal will update our database. The txn_id from paypal, members email address, date of payment and members id we gave them when they joined our site will be inserted into the log table. At the same time the memberAdmin table for the member will be updated by adding a '1' to premium and the date of payment so the new premium member will have access to premium areas of your site. */
//Check if verified is launced
$log_query_2 = mysql_query("INSERT INTO `log` VALUES (' ','yes','yes','yes', 'yes')");
//$log_query = mysql_query("INSERT INTO `log` VALUES (' ','".intval($id)."','".$txnId."','".$payerEmail."', now())");
//$update_premium = mysql_query("UPDATE `memberAdmin` SET `premium`=1, `premiumDate`=now() WHERE `id`=".intval($id)."");
}
//}
}
}
else if (strcmp ($res, "INVALID") == 0) {
//Check if invalid is launced
$log_query_2 = mysql_query("INSERT INTO `log` VALUES (' ','no','no','no', 'no')");
}
}
fclose ($fp);
}
?>

Paypal IPN Callback not working with sandbox

I am working with Drupal 7 & have implemented paypal by coding at one place where my user is suppose to register by paying at paypal & when he returns back I have to register him in callback function if payment is verified.
My callback function is simply not working & all the variables values which I am suppose to get in callback is also returning me false...
Here is my code --
This one I am using to send user to paypal with values--
function user_type_register_form_submit($form, &$form_state){
global $base_url;
$username = $form_state['values']['name'];
$user_email = $form_state['values']['mail'];
$user_type = $form_state['values']['user_type'];
$user_first_name = $form_state['values']['field_first_name']['und'][0]['value'];
$user_last_name = $form_state['values']['field_last_name']['und'][0]['value'];
$user_company_name = $form_state['values']['field_company_name']['und'][0]['value'];
$user_address_line_1 = $form_state['values']['field_address_line_1']['und'][0]['value'];
$user_address_line_2 = $form_state['values']['field_address_line_2']['und'][0]['value'];
$user_city = $form_state['values']['field_user_city']['und'][0]['value'];
$user_state = $form_state['values']['field_user_state']['und'][0]['value'];
$user_zip = $form_state['values']['field_user_zip']['und'][0]['value'];
$user_phone_number = $form_state['values']['field_phone_number_']['und'][0]['value'];
$user_mobile_number = $form_state['values']['field_mobile_number_']['und'][0]['value'];
$user_fax_number = $form_state['values']['field_fax_number_']['und'][0]['value'];
$paypal = array();
$paypal['cmd'] = '_xclick';
$paypal['business'] = 'rajeev_1359782736_biz#gmail.com';
$paypal['page_style'] = 'Primary';
$paypal['bn'] = 'PP-DonationsBF';
$paypal['item_name'] = 'Membership';
$paypal['currency_code'] = 'USD';
$paypal['no_shipping'] = '1';
$paypal['tax'] = '0';
$paypal['lc'] = 'US';
$paypal['rm'] = '1';
$paypal['return'] = $base_url.'/?q=paypal/payment';
$paypal['cancel_return'] = $base_url.'/?q=user/register';
$paypal['uname'] = $username;
$paypal['email'] = $user_email;
$paypal['user_type'] = $user_type;
$paypal['first_name'] = $user_first_name;
$paypal['last_name'] = $user_last_name;
$paypal['comp_name'] = $user_company_name;
$paypal['address1'] = $user_address_line_1;
$paypal['address2'] = $user_address_line_2;
$paypal['city'] = $user_city;
$paypal['state'] = $user_state;
$paypal['zip'] = $user_zip;
$paypal['phone'] = $user_phone_number;
$paypal['mobile'] = $user_mobile_number;
$paypal['fax'] = $user_fax_number;
switch($user_type){
case '0':
dpm("General");
$membership_price = 50;
$paypal['amount'] = $membership_price;
$paypal['item_number'] = 1;
$query = http_build_query($paypal, '', '&');
$form_state['redirect'] = 'https://www.sandbox.paypal.com/cgi-bin/webscr?' .$query;
break;
case '1':
dpm("Student");
$membership_price = 50;
$paypal['amount'] = $membership_price;
$paypal['item_number'] = 2;
$query = http_build_query($paypal, '', '&');
$form_state['redirect'] = 'https://www.sandbox.paypal.com/cgi-bin/webscr?' .$query;
break;
case '2':
dpm("Government");
$membership_price = 50;
$paypal['amount'] = $membership_price;
$paypal['item_number'] = 3;
$query = http_build_query($paypal, '', '&');
$form_state['redirect'] = 'https://www.sandbox.paypal.com/cgi-bin/webscr?' .$query;
break;
}
}
I debugged the query which sending user to paypal & it's look like --
cmd=_xclick&business=rajeev_1359782736_biz%40gmail.com&page_style=Primary&bn=PP-DonationsBF&item_name=Membership&currency_code=USD&no_shipping=1&tax=0&lc=US&rm=1&return=http%3A%2F%2Fctaep-test.kr001.us%2F%3Fq%3Dpaypal%2Fpayment&cancel_return=http%3A%2F%2Fctaep-test.kr001.us%2F%3Fq%3Duser%2Fregister&uname=admin_list&email=rajeevkr.dei%40gmail.com&user_type=0&first_name=Rajeev&last_name=Kumar&comp_name=&address1=sector+27&address2=&city=noida&state=ky&zip=201301&phone=9650361380&mobile=&fax=&amount=50&item_number=1
This function I am using to receive the callback --
function paypal_payment_paypal_ipn_callback($vars = array()){
header("Content-type: text/html");
header("Expires: Wed, 29 Jan 1975 04:15:00 GMT");
header("Last-Modified: " . gmdate("D, d M Y H:i:s") . " GMT");
header("Cache-Control: no-cache, must-revalidate");
header("Pragma: no-cache");
watchdog('paypal', '1');
// read the post from PayPal system and add 'cmd'
$req = 'cmd=_notify-validate';
foreach ($_POST as $key => $value) {
$value = urlencode(stripslashes($value));
$req .= "&$key=$value";
}
watchdog('paypal', '2');
// post back to PayPal system to validate
$header = '';
$header .= "POST /cgi-bin/webscr HTTP/1.0\r\n";
$header .= "Content-Type: application/x-www-form-urlencoded\r\n";
$header .= "Host: www.sandbox.paypal.com\r\n";
$header .= "Content-Length: " . strlen($req) . "\r\n\r\n";
$fp = fsockopen ('ssl://www.sandbox.paypal.com', 443, $errno, $errstr, 30);
//Added - new
// reading posted data from 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";
}
// STEP 2: Post IPN data back to paypal to validate
$ch = curl_init('https://www.sandbox.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);
//Added end
if (!$fp) {
watchdog('paypal', 'HTTP error');
} else {
fputs ($fp, $header . $req);
watchdog('paypal', $header . $req);
while (!feof($fp)) {
$res = fgets ($fp, 1024);
watchdog('paypal', '3');
//dpm($res);
watchdog('pay_status',$res);
if (strcmp ($res, "VERIFIED") == 0) {
//if (strcmp ($res, "INVALID") == 0) {
// assign posted variables to local variables
//$txn_id = $_POST['txn_id'];
watchdog('paypal', '4');
//Information about you:
$receiver_email = $_POST['business'];
//Information about the transaction:
$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'];
dpm($receiver_email);
//Information about your buyer:
$user_email = $_POST['email'];
$user_name = $_POST['uname'];
$first_name = $_POST['first_name'];
$last_name = $_POST['last_name'];
$company_name = $_POST['comp_name'];
$address_address_line_1 = $_POST['address1'];
$address_address_line_2 = $_POST['address2'];
$address_city = $_POST['city'];
$address_state = $_POST['state'];
$address_zip = $_POST['zip'];
$user_phone = $_POST['phone'];
$user_mobile = $_POST['mobile'];
$user_fax = $_POST['fax'];
//Information about the payment:
$membership_type = $_POST['item_name'];
//Other information about the transaction:
//watchdog('paypal', '4');
// check 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 payment
$password = user_password(8);
$fields = array(
'name' => $user_name,
'mail' => $user_email,
'pass' => $password,
'status' => 1,
'init' => $user_email,
'roles' => array(
DRUPAL_AUTHENTICATED_RID => $membership_type,),
);
// user_save('', $fields);
$account = user_save('', $fields);
dpm("user registered");
}
else if (stripos($res, "VERIFIED") !== false) {
watchdog('paypal', 'INVALID');
// log for manual investigation
}
}
fclose ($fp);
}
return 'Callback Complete';
}
Here is my watchdog errors --
inside-callback : 1
Notice: Undefined index: item_name in paypal_payment_paypal_ipn_callback()
Notice: Undefined index: item_number in paypal_payment_paypal_ipn_callback()
Notice: Undefined index: payment_status in paypal_payment_paypal_ipn_callback()
Notice: Undefined index: mc_gross in paypal_payment_paypal_ipn_callback()
Notice: Undefined index: mc_currency in paypal_payment_paypal_ipn_callback()
Notice: Undefined index: txn_id in paypal_payment_paypal_ipn_callback()
Notice: Undefined index: receiver_email in paypal_payment_paypal_ipn_callback()
Notice: Undefined index: payer_email in paypal_payment_paypal_ipn_callback()
inside-invalid : 4
Although PayPal extended the support for HTTP1.0 until May 1, 2013 they may have updated the Sandbox already for HTTP1.1 support only.
https://www.x.com/content/bulletin-ipn-and-pdt-scripts-and-http-1-1
If this is true you will need to update your callback script as follows.
// post back to PayPal system to validate
$header .= "POST /cgi-bin/webscr HTTP/1.1\r\n"; // HTTP1.1 Update
$header .= "Content-Length: " . strlen($req) . "\r\n";
$header .= "Content-Type: application/x-www-form-urlencoded\r\n";
$header .= "Host: www.sandbox.paypal.com\r\n"; // Sandbox Host
//$header .= "Host: ipnpb.paypal.com\r\n"; // Live Host
$header .= "Connection: close\r\n\r\n";
For further compatibility
https://ppmts.custhelp.com/app/answers/detail/a_id/926/
1) Your php script should also trim the IPN validation response.
Modify your script:
//From:
if (strcmp ($res, "VERIFIED") == 0) {
..
else if (strcmp ($res, "INVALID") == 0) {
//To:
if (strcmp (trim($res), "VERIFIED") == 0) {
..
else if (strcmp (trim($res), "INVALID") == 0) {
2) In php make sure the last line of your header includes double end-of-line markers: \r\n\r\n as in the example above: $header .="Connection: close\r\n\r\n";
3) In php make sure to open the socket connection to the same host declared in the header. As your header is declaring the host as
$header .="Host: ipnpb.paypal.com\r\n";
You should open the connection to the same host:
$fp = fsockopen ('ssl://ipnpb.paypal.com', 443, $errno, $errstr, 30);
The problem is here:
$paypal['return'] = $base_url.'/?q=paypal/payment';
What you have defined there is where the user ends up after making payment; and unless you have enabled PDT, it won't pass the transaction identifier either.
You need to use the notify_url to register an IPN handler:
$paypal['notify_url'] = $base_url.'/?q=paypal/payment';

PHP - PayPal Integration, failed running my custom transaction function after payment accepted

I have tried using a tutorial script for PayPal payment in the past and it worked. Now it doesn't. The script is simple, all I need is this one page for processing payment:
<?php
session_start();
include ('mydbconfig.php');
// payPal settings
$paypal_email = 'seller#yahoo.com';
$return_url = 'https://www.mytestsite.com/paypal-thanks.php';
$cancel_url = 'https://www.mytestsite.com/paypal-cancel.php';
$notify_url = 'https://www.mytestsite.com/paypal-notify.php';
$item_name = $_POST['item_name'];
$item_amount = $_POST['item_amount']; //price
// check if paypal request or response
if (!isset($_POST["txn_id"]) && !isset($_POST["txn_type"])){
// firstly append paypal account to querystring
$querystring .= "?business=".urlencode($paypal_email)."&";
// append amount& currency (£) to quersytring so it cannot be edited in html
//the item name and amount can be brought in dynamically by querying the $_POST['item_number'] variable.
$querystring .= "item_name=".urlencode($item_name)."&";
$querystring .= "amount=".urlencode($item_amount)."&";
//loop for posted values and append to querystring
foreach($_POST as $key => $value) {
$value = urlencode(stripslashes($value));
$querystring .= "$key=$value&";
}
// Append paypal return addresses
$querystring .= "return=".urlencode(stripslashes($return_url))."&";
$querystring .= "cancel_return=".urlencode(stripslashes($cancel_url))."&";
$querystring .= "notify_url=".urlencode($notify_url);
// Append querystring with custom field
//$querystring .= "&custom=".USERID;
// Redirect to paypal IPN
header('location:https://www.paypal.com/cgi-bin/webscr'.$querystring);
exit();
} else { // response from Paypal
// read the post from PayPal system and add 'cmd'
$req = 'cmd=_notify-validate';
foreach ($_POST as $key => $value) {
$value = urlencode(stripslashes($value));
$value = preg_replace('/(.*[^%^0^D])(%0A)(.*)/i','${1}%0D%0A${3}',$value);// IPN fix
$req .= "&$key=$value";
}
// assign posted variables to local variables
$data['item_name'] = $_POST['item_name'];
$data['item_number'] = $_POST['item_number'];
$data['payment_status'] = $_POST['payment_status'];
$data['payment_amount'] = $_POST['mc_gross'];
$data['payment_currency'] = $_POST['mc_currency'];
$data['txn_id'] = $_POST['txn_id'];
$data['receiver_email'] = $_POST['receiver_email'];
$data['payer_email'] = $_POST['payer_email'];
$data['custom'] = $_POST['custom'];
// post back to PayPal system to validate
$header = "POST /cgi-bin/webscr HTTP/1.0\r\n";
$header .= "Content-Type: application/x-www-form-urlencoded\r\n";
$header .= "Content-Length: " . strlen($req) . "\r\n\r\n";
$fp = fsockopen ('ssl://www.sandbox.paypal.com', 443, $errno, $errstr, 30);
if (!$fp) {
// HTTP ERROR
header('location: https://www.mytestsite.com/paypal-error.php?tr='.$data['txn_id'].'&in='.$data['item_name'].'&pe='.$data['payer_email'].'&pa='.$data['payment_amount'].'&ps='.$data['payment_status']);
} else {
fputs ($fp, $header . $req);
while (!feof($fp)) {
$res = fgets ($fp, 1024);
if (strcmp ($res, "VERIFIED") == 0) {
//payment accepted, insert transaction to my database
//function to insert transaction here
} else if (strcmp ($res, "INVALID") == 0) {
//something to do if failed
}
}
fclose ($fp);
}
}
?>
After the process is completed, I checked and the payment is paid successfully, but my function or anything I wrote in //function to insert transaction here won't be executed. In the end I'm forced to do the function on paypal-thanks.php page. Is there something's wrong in the script?
Is this script can be used to send more than one item purchasing? My cart is my own custom made and I only want to send Item name, number, and price detail, and total price to PayPal order summary.
I checked the other PayPal integration questions here, and most of them direct me to PayPal tutorial, documentation, or integration wizard which're confusing. I use this simple script before because I can't understand PayPal documentation (and the sample code, it didn't even let me know where to start) :(
And lastly my ultimate question, is this script is the correct and secure way to do a payment transaction?
use this
$fp = fsockopen ('ssl://www.paypal.com', 443, $errno, $errstr, 30);
instead of
$fp = fsockopen ('ssl://www.sandbox.paypal.com', 443, $errno, $errstr, 30);
i think it is better to use CURL instead of socket

Why is post data not reflecting on the page?

I am using this code on my site, for paypal checkout
<?php
require('../includes/globals/config.php');
require('myCart.inc.php');
$mycart = new myCart;
$ppemail = $mycart->getPaypalEmail();
$paypal_email = $ppemail['email'];
$paypal_currency = 'USD';
//$shipping = 1.00;
// read the post from PayPal system and add 'cmd'
$req = 'cmd=_notify-validate';
foreach($_POST as $key => $value){
$value = urlencode(stripslashes($value));
$req .= "&$key=$value";
}
// post back to PayPal system to validate
$header .= "POST /cgi-bin/webscr HTTP/1.0\r\n";
$header .= "Content-Type: application/x-www-form-urlencoded\r\n";
$header .= "Content-Length: " . strlen($req) . "\r\n\r\n";
$fp = fsockopen('www.sandbox.paypal.com', 80, $errno, $errstr, 30);
// 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 (!$fp){
// HTTP ERROR
} else {
fputs($fp, $header . $req);
while(!feof($fp)) {
$res = fgets($fp, 1024);
if (strcmp($res,"VERIFIED") == 0){
//blah blah
}
else if (strcmp($res, "INVALID") == 0){
// log for manual investigation
}
}
fclose($fp);
}
?>
The problem is, after the transaction stuff, and I get redirected to a thank you page, the $_POST data doesn't appear on the form inputs, I meant, I extracted the contents of the $_POST data coming from the paypal transaction and placed the tidbits of data on each form fields..but when I clean browser cache/private data/session/cookies and do the same procedure, but this time with the
echo "<pre>",print_r($_POST),"</pre>";
the $_POST content gets printed on the page and the tidbits of $_POST are being displayed also inside the form fields..this happens when I use the print_r. Is there a workaround for this? so that the tidbits of data will immediately appear on the form fields without having to invoke the print_r() func and print the array of data somewhere on the page ?

Why is my PayPal IPN script failing?

I'm developing a lightweight e-commerce solution that uses PayPal as the payment gateway. However, my IPN callback is constantly returning an INVALID response. I even tried using the sample PHP script provided by PayPal:
// read the post from PayPal system and add 'cmd'
$req = 'cmd=_notify-validate';
foreach ($_POST as $key => $value) {
$value = urlencode(stripslashes($value));
$req .= "&$key=$value";
}
// post back to PayPal system to validate
$header .= "POST /cgi-bin/webscr HTTP/1.0\r\n";
$header .= "Content-Type: application/x-www-form-urlencoded\r\n";
$header .= "Content-Length: " . strlen($req) . "\r\n\r\n";
$fp = fsockopen ('ssl://www.paypal.com', 443, $errno, $errstr, 30);
// 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 (!$fp) {
// HTTP ERROR
}
else {
fputs ($fp, $header . $req);
while (!feof($fp)) {
$res = fgets ($fp, 1024);
if (strcmp ($res, "VERIFIED") == 0) {
// check 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 payment
}
else if (strcmp ($res, "INVALID") == 0) {
// log for manual investigation
}
}
fclose ($fp);
}
But as I say, I keep getting an INVALID response. This is in fact the response I get using a PHP class that writes the response to a log file:
[2011-06-02 19:18:49] - FAIL: IPN Validation Failed.
IPN POST data from PayPal:
test_ipn=1,
payment_type=instant,
payment_date=11:07:43 Jun 02, 2011 PDT,
payment_status=Completed,
payer_status=verified,
first_name=John,
last_name=Smith,
payer_email=buyer#paypalsandbox.com,
payer_id=TESTBUYERID01,
business=seller#paypalsandbox.com,
receiver_email=seller#paypalsandbox.com,
receiver_id=TESTSELLERID1,
residence_country=US,
item_name1=something,
item_number1=AK-1234,
quantity1=1,
tax=2.02,
mc_currency=USD,
mc_fee=0.44,
mc_gross=15.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=4362187,
notify_version=2.4,
custom=xyz123,
invoice=abc1234,
charset=windows-1252,
verify_sign=AjbdIvvDAW2fh1O9jAbEym4myX.WAV7-jCEiEWMqoSkewvM6L3Co6oUQ
This is from the official PayPal IPN test tool. So something between PayPal's sample code and test tool is causing my script to fail. Any one have any ideas?
what is encoding of your html/php page ? (charset=windows-1252) ?

Categories