YetAnotherForum
Welcome Guest Search | Active Topics | Log In | Register

Subscription IPN returning lots of subscr_signup per transaction Options
mikemike
#1 Posted : Thursday, February 03, 2011 5:12:16 PM
Rank: Starting Member

Groups: Registered

Joined: 2/3/2011
Posts: 1
Sorry if this is in the wrong forum/thread, I wasn't sure where to put it as it applies to a few different things.

I've implemented PayPal a ton of times into a ton of websites, yet I've never seen this. I'm only dealing with subscriptions. For every transaction PayPal seems to be sending me a bunch of subscr_signup's, probably 6 or 7 each time, but not always the same number. I do get a subscr_payment, but not always. The subscr_payment sometimes comes before the subscr_signup, which is making this impossible to ignore.

I am using PHP and the CodeIgniter framework. I have a PayPal library which I've used before with no issues. The library handles all the faffing with PayPal's verification, and I can confirm that PayPal definitely returned 'VERIFIED' to me, below are the HTTP headers they send for each request:
Quote:
Date: Thu, 03 Feb 2011 17:45:20 GMT
Server: Apache
Set-Cookie: cwrClyrK4LoCV1fydGbAxiNL6iG=oPkp-qmSOrL1QSBzx6vHrhMuuOOCcmL6gQUjk-BzJK-X8svhom3xSYIGY53u7S1VrQRD05qonWfAG3I_JiDHmWNBdC0Xgq6329H_PIeddtkn8xzLUx57VhmEd2MyWHlMYENH8G%7cdBU4hgI-Zfl17cHXotVPUwDkKiyrVhCi0W5hMml-yYZu7KWEVecatYyU9acjthtXP24Kfm%7ceAb5Z0foaqZJc-OPUZjKzCLUwBvHHfTtMf8ODbnXeHOm1n9Ca-H1in5wG6vuL51kb_VvXG%7c1296755121; domain=.paypal.com; path=/; HttpOnly
Set-Cookie: cookie_check=yes; expires=Sun, 31-Jan-2021 17:45:21 GMT; domain=.paypal.com; path=/; HttpOnly
Set-Cookie: navcmd=_notify-validate; domain=.paypal.com; path=/; HttpOnly
Set-Cookie: navlns=0.0; expires=Wed, 29-Jan-2031 17:45:21 GMT; domain=.paypal.com; path=/; HttpOnly
Vary: Accept-Encoding
Connection: close
Transfer-Encoding: chunked
Content-Type: text/html; charset=UTF-8

8
VERIFIED
0

I've excluded the POST vars they send back for security.

It's not a case that my script isn't dealing with the responses correctly, it is definitely a case that PayPal is sending these requests to me, all with the same subscr_id.

Has anyone ever encountered this before? It's utterly baffling and totally bizzare. I've attached my full IPN code below:
Quote:
function ipn()
{

$this->output->enable_profiler(TRUE);

$this->load->model('payments_model');
$this->load->model('paypal_model');
$this->load->model('users_model');


if ($this->paypal_lib->validate_ipn())
{
// if(empty($this->paypal_lib->ipn_data['txn_id']) || !$this->payments_model->paypal_txn_id_exists($this->paypal_lib->ipn_data['txn_id']))
// {

$paypal_id = $this->paypal_model->add_paypal_ipn($this->paypal_lib->ipn_data);
// Split the 'custom' field up, containing ID of temp user, ID of package and coupon
$custom = explode(';', $this->paypal_lib->ipn_data['custom']);

###
# subscription sign up
###
if($this->paypal_lib->ipn_data['txn_type'] == 'subscr_signup') {
// Activate user/move from temp > live
$this->users_model->move_temp($custom[0], $this->paypal_lib->ipn_data['subscr_id']);
} # end subscr_signup


###
# subscription payment
###
if($this->paypal_lib->ipn_data['txn_type'] == 'subscr_payment') {
// Grab the coupon info, if we have one
$discount = 1;
if(!empty($custom[2])){
$this->load->model('coupons_model');
$couponinfo = $this->coupons_model->get_coupon($custom[2]);
$discount = $couponinfo->discount;
}
// Grab the package info
$package = $this->packages_model->get_package($custom[1]);
$price = $package->monthly * $discount; // Calculate discount, 0.8 = 20% off

// Does the price calculated match the gross price? If not something fishy is going on, block it
if($price != $this->paypal_lib->ipn_data['mc_gross']){
mail(CONTACT_EMAIL, SITE_NAME.' failed payment attempt, possible hack', 'Price paid doesnt match price computed... paid: '.$this->paypal_lib->ipn_data['mc_gross'].' - price worked out: '.$price."\n\n".print_r($this->paypal_lib->ipn_data, true));
exit;
}

// Grab the user's details based on the subscr_id
$user = $this->users_model->get_user_by_subscr_id($this->paypal_lib->ipn_data['subscr_id']);

// Add payment to the payments table
$data = array(
'user_id' => $user->user_id,
'subscr_id' => $user->subscr_id,
'txn_id' => $this->paypal_lib->ipn_data['txn_id'],
'amount' => $this->paypal_lib->ipn_data['mc_gross'],
'package_id' => $custom[1],
'coupon' => (empty($custom[2]) ? '' : $custom[2])
);
$this->payments_model->add_payment($data);

// Set (forced) user as active, and update their current active package
$data1 = array(
'package_id' => $custom[1],
'active' => 1
);
$this->users_model->update_user($data1, $user->user_id);
} # end subscr_payment


###
# subscription failed/cancelled
###
if($this->paypal_lib->ipn_data['txn_type'] == 'subscr_cancel' || $this->paypal_lib->ipn_data['txn_type'] == 'subscr_failed') {
// Grab user
$user = $this->users_model->get_user_by_subscr_id($this->paypal_lib->ipn_data['subscr_id']);

// Make user inactive
$data = array('active' => 0);
$this->users_model->update_user($data, $user->user_id);
} # end subscr_cancel|subscr_failed





###
# subscription modified/payment changed
###
if($this->paypal_lib->ipn_data['txn_type'] == 'subscr_modify') {
// Grab the coupon info, if we have one
$discount = 1;
if(!empty($custom[2])){
$this->load->model('coupons_model');
$couponinfo = $this->coupons_model->get_coupon($custom[2]);
$discount = $couponinfo->discount;
}
// Grab the package info
$package = $this->packages_model->get_package($custom[1]);
$price = $package->monthly * $discount; // Calculate discount, 0.8 = 20% off

// Does the price calculated match the gross price? If not something fishy is going on, block it
if($price != $this->paypal_lib->ipn_data['mc_gross']){
mail(CONTACT_EMAIL, SITE_NAME.' failed payment attempt, possible hack', 'Price paid doesnt match price computed... paid: '.$this->paypal_lib->ipn_data['mc_gross'].' - price worked out: '.$price."\n\n".print_r($this->paypal_lib->ipn_data, true));
exit;
}

// Grab the user's details based on the subscr_id
$user = $this->users_model->get_user_by_subscr_id($this->paypal_lib->ipn_data['subscr_id']);

// Add payment to the payments table
$data = array(
'user_id' => $user->user_id,
'subscr_id' => $user->subscr_id,
'txn_id' => $this->paypal_lib->ipn_data['txn_id'],
'amount' => $this->paypal_lib->ipn_data['mc_gross'],
'package_id' => $custom[1],
'coupon' => (empty($custom[2]) ? '' : $custom[2])
);
$this->payments_model->add_payment($data);

// Set (forced) user as active, and update their current active package
$data1 = array(
'package_id' => $custom[1],
'active' => 1
);
$this->users_model->update_user($data1, $user->user_id);
} # end subscr_modify
//}
}
}


The library is widely used, but I'll post the IPN validate method anyway. I'm pretty sure the issue doesn't reside here:
Quote:
function validate_ipn()
{
// parse the paypal URL
$url_parsed = parse_url($this->paypal_url);

// generate the post string from the _POST vars aswell as load the
// _POST vars into an arry so we can play with them from the calling
// script.
$post_string = '';
if (isset($_POST))
{
foreach ($_POST as $field=>$value)
{
// str_replace("\n", "\r\n", $value)
// put line feeds back to CR+LF as that's how PayPal sends them out
// otherwise multi-line data will be rejected as INVALID
$value = str_replace("\n", "\r\n", $value);
$this->ipn_data[$field] = $value;
$post_string .= $field.'='.urlencode(stripslashes($value)).'&';
}
}

$post_string.="cmd=_notify-validate"; // append ipn command

// open the connection to paypal
$fp = fsockopen($url_parsed['host'],"80",$err_num,$err_str,30);
if(!$fp)
{
// could not open the connection. If loggin is on, the error message
// will be in the log.
$this->last_error = "fsockopen error no. $errnum: $errstr";
$this->log_ipn_results(false);
return false;
}
else
{
// Post the data back to paypal
fputs($fp, "POST $url_parsed[path] HTTP/1.1\r\n");
fputs($fp, "Host: $url_parsed[host]\r\n");
fputs($fp, "Content-type: application/x-www-form-urlencoded\r\n");
fputs($fp, "Content-length: ".strlen($post_string)."\r\n");
fputs($fp, "Connection: close\r\n\r\n");
fputs($fp, $post_string . "\r\n\r\n");

// loop through the response from the server and append to variable
while(!feof($fp))
$this->ipn_response .= fgets($fp, 1024);

fclose($fp); // close connection
}

if (eregi("VERIFIED",$this->ipn_response))
{
// Valid IPN transaction.
$this->log_ipn_results(true);
return true;
}
else
{
// Invalid IPN transaction. Check the log for details.
$this->last_error = 'IPN Validation Failed.';
$this->log_ipn_results(false);
return false;
}
}


Thanks
Sponsor  
 
scoutt
#2 Posted : Wednesday, May 04, 2011 10:29:17 AM
Rank: Junior Member

Groups: Registered

Joined: 11/6/2002
Posts: 139
Location: ,
I am getting the same thing, been getting them for like a month now. I get it on cancels as well as signups and renews. Last time I seen this was back a few years ago. And at that time it was a paypal thing, not us on the other end
Users browsing this topic
Guest
Forum Jump  
You cannot post new topics in this forum.
You cannot reply to topics in this forum.
You cannot delete your posts in this forum.
You cannot edit your posts in this forum.
You cannot create polls in this forum.
You cannot vote in polls in this forum.

YAFVision Theme by Jaben Cargman (Tiny Gecko)
Powered by YAF | YAF © 2003-2009, Yet Another Forum.NET
This page was generated in 0.369 seconds.