function _buy_membership()
 {
     // system
     $system_obj = mgm_get_class('system');
     $s_packs = mgm_get_class('subscription_packs');
     $dge = bool_from_yn($system_obj->get_setting('disable_gateway_emails'));
     $dpne = bool_from_yn($system_obj->get_setting('disable_payment_notify_emails'));
     // parse
     $custom = $this->_get_transaction_passthrough($_REQUEST['trans_id']);
     extract($custom);
     // currency
     if (!$currency) {
         $currency = $system_obj->get_setting('currency');
     }
     // find user
     $user = get_userdata($user_id);
     // another_subscription modification
     if (isset($custom['is_another_membership_purchase']) && bool_from_yn($custom['is_another_membership_purchase'])) {
         $member = mgm_get_member_another_purchase($user_id, $custom['membership_type']);
     } else {
         $member = mgm_get_member($user_id);
     }
     // Get the current AC join date
     if (!($join_date = $member->join_date)) {
         $member->join_date = time();
     }
     // Set current AC join date
     //if there is no duration set in the user object then run the following code
     if (empty($duration_type)) {
         //if there is no duration type then use Months
         $duration_type = 'm';
     }
     // membership type default
     if (empty($membership_type)) {
         //if there is no account type in the custom string then use the existing type
         $membership_type = md5($member->membership_type);
     }
     // validate parent method
     $membership_type_verified = $this->_validate_membership_type($membership_type, 'md5|plain');
     // verified
     if (!$membership_type_verified) {
         if (strtolower($member->membership_type) != 'free') {
             // notify admin, only if gateway emails on
             if (!$dge) {
                 mgm_notify_admin_membership_verification_failed($this->name);
             }
             // abort
             return;
         } else {
             $membership_type_verified = $member->membership_type;
         }
     }
     // set
     $membership_type = $membership_type_verified;
     // sub pack
     $subs_pack = $s_packs->get_pack($pack_id);
     // if trial on
     if ($subs_pack['trial_on']) {
         $member->trial_on = $subs_pack['trial_on'];
         $member->trial_cost = $subs_pack['trial_cost'];
         $member->trial_duration = $subs_pack['trial_duration'];
         $member->trial_duration_type = $subs_pack['trial_duration_type'];
         $member->trial_num_cycles = $subs_pack['trial_num_cycles'];
     }
     //pack currency over rides genral setting currency - issue #1602
     if (isset($subs_pack['currency']) && $subs_pack['currency'] != $currency) {
         $currency = $subs_pack['currency'];
     }
     // duration
     $member->duration = $duration;
     $member->duration_type = strtolower($duration_type);
     $member->amount = $amount;
     $member->currency = $currency;
     $member->membership_type = $membership_type;
     $member->pack_id = $pack_id;
     // $member->payment_type    = ($_POST['cprodtype']=='RECURRING') ?'subscription' : 'one-time';
     $member->active_num_cycles = isset($num_cycles) && !empty($num_cycles) ? $num_cycles : $subs_pack['num_cycles'];
     $member->payment_type = (int) $member->active_num_cycles == 1 ? 'one-time' : 'subscription';
     // payment info for unsubscribe
     if (!isset($member->payment_info)) {
         $member->payment_info = new stdClass();
     }
     // set
     $member->payment_info->module = $this->code;
     // subscription id
     if (isset($_REQUEST['subscr_id'])) {
         $member->payment_info->subscr_id = $_REQUEST['subscr_id'];
     }
     // sisow txn id
     if (isset($_REQUEST['trxid'])) {
         $member->payment_info->txn_id = $_REQUEST['trxid'];
         // ideal txn for cancel subscription
     } elseif (isset($_REQUEST['trans_id'])) {
         $member->payment_info->txn_id = $_REQUEST['trans_id'];
     }
     // magicmem txn id
     if (isset($_REQUEST['ec'])) {
         $member->transaction_id = $_REQUEST['ec'];
     } elseif (isset($_REQUEST['trans_id'])) {
         $member->transaction_id = $_REQUEST['trans_id'];
     }
     // author id
     if (isset($_REQUEST['authorisationId'])) {
         $member->payment_info->authorisation_id = $_REQUEST['authorisationId'];
     }
     // process response
     $new_status = $update_role = false;
     // errors
     $errors = array();
     // set status
     if ('sisow' == $this->setting['aquirer']) {
         $payment_status = isset($_REQUEST['status']) ? $_REQUEST['status'] : 'Error';
     } else {
         $payment_status = isset($_REQUEST['status']) && $_REQUEST['status'] == 'success' ? 'SALE' : 'ERROR';
     }
     // on transaction
     switch (trim($payment_status)) {
         case "SALE":
         case 'Success':
             $new_status = MGM_STATUS_ACTIVE;
             $member->status_str = __('Last payment was successful', 'mgm');
             $time = time();
             $last_pay_date = isset($member->last_pay_date) ? $member->last_pay_date : null;
             $member->last_pay_date = date('Y-m-d', $time);
             // update expire date
             /* ***********************************
             			if ($member->expire_date) {
             				$expiry = strtotime($member->expire_date);
             				if ($expiry > 0) {
             					if ($expiry > $time) {
             						$time = $expiry;
             					}
             				}
             			}
             			*************************************/
             // check subscription_option
             if (isset($subscription_option)) {
                 // on option
                 switch ($subscription_option) {
                     // @ToDo, apply expire date login
                     case 'create':
                         // expire date will be based on current time
                     // expire date will be based on current time
                     case 'upgrade':
                         // expire date will be based on current time
                         // already on top
                         break;
                     case 'downgrade':
                         // expire date will be based on expire_date if exists, current time other wise
                     // expire date will be based on expire_date if exists, current time other wise
                     case 'extend':
                         // expire date will be based on expire_date if exists, current time other wise
                         // extend/expire date
                         // calc expiry	- issue #1226
                         // membership extend functionality broken if we try to extend the same day so removed && $last_pay_date != date('Y-m-d', $time) check
                         if (!empty($member->expire_date)) {
                             $expiry = strtotime($member->expire_date);
                             if ($expiry > 0 && $expiry > $time) {
                                 $time = $expiry;
                             }
                         }
                         break;
                 }
             }
             // type expanded
             $duration_exprs = $s_packs->get_duration_exprs();
             // if not lifetime/date range
             if (in_array($member->duration_type, array_keys($duration_exprs))) {
                 // take only date exprs
                 //consider trial duration if trial period is applicable
                 if (isset($trial_on) && $trial_on == 1) {
                     //Do it only once
                     if (!isset($member->rebilled) && isset($member->active_num_cycles) && $member->active_num_cycles != 1) {
                         $time = strtotime("+{$trial_duration} {$duration_exprs[$trial_duration_type]}", $time);
                     }
                 } else {
                     // time - issue #1068
                     $time = strtotime("+{$member->duration} {$duration_exprs[$member->duration_type]}", $time);
                 }
                 // formatted
                 $time_str = date('Y-m-d', $time);
                 // date extended
                 if (!$member->expire_date || strtotime($time_str) > strtotime($member->expire_date)) {
                     $member->expire_date = $time_str;
                 }
             } else {
                 //if lifetime:
                 if ($member->duration_type == 'l') {
                     // el = lifetime
                     $member->expire_date = '';
                 }
                 //issue #1096
                 if ($member->duration_type == 'dr') {
                     // el = /date range
                     $member->expire_date = $duration_range_end_dt;
                 }
             }
             //update rebill: issue #: 489
             if ($member->active_num_cycles != 1 && (int) $member->rebilled < (int) $member->active_num_cycles) {
                 // rebill
                 $member->rebilled = !$member->rebilled ? 1 : (int) $member->rebilled + 1;
             }
             //cancel previous subscription:
             //issue#: 565
             $this->cancel_recurring_subscription($_REQUEST['trans_id'], null, null, $pack_id);
             // role update
             if ($role) {
                 $update_role = true;
             }
             // transaction_id
             $transaction_id = $this->_get_transaction_id('trans_id', $_REQUEST);
             // hook args
             $args = array('user_id' => $user_id, 'transaction_id' => $transaction_id);
             // another membership
             if (isset($custom['is_another_membership_purchase']) && bool_from_yn($custom['is_another_membership_purchase'])) {
                 $args['another_membership'] = $custom['membership_type'];
             }
             // after succesful payment hook
             do_action('mgm_membership_transaction_success', $args);
             // backward compatibility
             do_action('mgm_subscription_purchase_payment_success', $args);
             // new organized name
             break;
         case "ERROR":
         case 'Failure':
             $new_status = MGM_STATUS_NULL;
             $member->status_str = __('Last payment was refunded or denied', 'mgm');
             // error
             $errors[] = $member->status_str;
             break;
         case "CANCEL-REBILL":
         case "UNCANCEL-REBILL":
         case 'Pending':
             $new_status = MGM_STATUS_PENDING;
             $reason = 'Unknown';
             $member->status_str = sprintf(__('Last payment is pending. Reason: %s', 'mgm'), $reason);
             // error
             $errors[] = $member->status_str;
             break;
         default:
             $new_status = MGM_STATUS_ERROR;
             $member->status_str = sprintf(__('Last payment status: %s', 'mgm'), $ctransaction);
             // error
             $errors[] = $member->status_str;
             break;
     }
     // old status
     $old_status = $member->status;
     // set new status
     $member->status = $new_status;
     // whether to acknowledge the user - This should happen only once
     $acknowledge_user = $this->send_payment_email($_REQUEST['trans_id']);
     // whether to subscriber the user to Autoresponder - This should happen only once
     $acknowledge_ar = mgm_subscribe_to_autoresponder($member, $_REQUEST['trans_id']);
     //another_subscription modification
     if (isset($custom['is_another_membership_purchase']) && bool_from_yn($custom['is_another_membership_purchase'])) {
         //issue #1227
         if ($subs_pack['hide_old_content']) {
             $member->hide_old_content = $subs_pack['hide_old_content'];
         }
         mgm_save_another_membership_fields($member, $user_id);
         // Multiple membership upgrade: first time
         if (isset($member->transaction_id) && isset($custom['multiple_upgrade_prev_packid']) && is_numeric($custom['multiple_upgrade_prev_packid'])) {
             mgm_multiple_upgrade_save_memberobject($custom, $member->transaction_id);
         }
     } else {
         $member->save();
     }
     // status change event
     do_action('mgm_user_status_change', $user_id, $new_status, $old_status, 'module_' . $this->module, $member->pack_id);
     //update coupon usage
     do_action('mgm_update_coupon_usage', array('user_id' => $user_id));
     // update role
     if ($update_role) {
         $obj_role = new mgm_roles();
         $obj_role->add_user_role($user_id, $role);
     }
     // return action
     do_action('mgm_return_' . $this->module, array('user_id' => $user_id));
     // backward compatibility
     do_action('mgm_return_subscription_payment_' . $this->module, array('user_id' => $user_id));
     // new , individual
     do_action('mgm_return_subscription_payment', array('user_id' => $user_id, 'acknowledge_ar' => $acknowledge_ar, 'mgm_member' => $member));
     // new, global: pass mgm_member object to consider multiple level purchases as well.
     // another_subscription modification
     if (isset($custom['is_another_membership_purchase']) && bool_from_yn($custom['is_another_membership_purchase'])) {
         $member = mgm_get_member_another_purchase($user_id, $custom['membership_type']);
     } else {
         $member = mgm_get_member($user_id);
     }
     // transaction status
     mgm_update_transaction_status($member->transaction_id, $member->status, $member->status_str);
     // send email notification to client
     $blogname = get_option('blogname');
     // notify
     if ($acknowledge_user) {
         // notify user, only if gateway emails on
         if (!$dpne) {
             // notify
             if (mgm_notify_user_membership_purchase($blogname, $user, $member, $custom, $subs_pack, $s_packs, $system_obj)) {
                 // update as email sent
                 $this->update_paymentemail_sent($alt_tran_id);
             }
         }
         // notify admin, only if gateway emails on
         if (!$dge) {
             // pack duration
             $pack_duration = $s_packs->get_pack_duration($subs_pack);
             // notify admin,
             mgm_notify_admin_membership_purchase($blogname, $user, $member, $pack_duration);
         }
     }
     // error condition redirect
     if (count($errors) > 0) {
         if ($this->is_webhook_called_by('self')) {
             // only when proxied via payment_return
             mgm_redirect(add_query_arg(array('status' => 'error', 'errors' => implode('|', $errors)), $this->_get_thankyou_url()));
         }
     }
 }
 function _buy_membership()
 {
     // system
     $system_obj = mgm_get_class('system');
     $s_packs = mgm_get_class('subscription_packs');
     $dge = bool_from_yn($system_obj->get_setting('disable_gateway_emails'));
     $dpne = bool_from_yn($system_obj->get_setting('disable_payment_notify_emails'));
     // passthrough
     $alt_tran_id = $this->_get_alternate_transaction_id();
     // get passthrough, stop further process if fails to parse
     $custom = $this->_get_transaction_passthrough($alt_tran_id);
     // local var
     extract($custom);
     // currency
     if (!$currency) {
         $currency = $system_obj->get_setting('currency');
     }
     // find user
     $user = get_userdata($user_id);
     //another_subscription modification
     if (isset($custom['is_another_membership_purchase']) && bool_from_yn($custom['is_another_membership_purchase'])) {
         $member = mgm_get_member_another_purchase($user_id, $custom['membership_type']);
     } else {
         $member = mgm_get_member($user_id);
     }
     // Get the current AC join date
     if (!($join_date = $member->join_date)) {
         $member->join_date = time();
     }
     // Set current AC join date
     //if there is no duration set in the user object then run the following code
     if (empty($duration_type)) {
         //if there is no duration type then use Months
         $duration_type = 'm';
     }
     //issue #1624  - some times membership type showing only under score so getting from the pack
     if ($pack_id && !empty($membership_type)) {
         $sub_pack = $s_packs->get_pack($pack_id);
         $membership_type = $sub_pack['membership_type'];
     }
     // membership type default
     if (empty($membership_type)) {
         //if there is no account type in the custom string then use the existing type
         $membership_type = md5($member->membership_type);
     }
     // validate parent method
     $membership_type_verified = $this->_validate_membership_type($membership_type, 'md5|plain');
     // verified
     if (!$membership_type_verified) {
         if (strtolower($member->membership_type) != 'free') {
             // notify admin, only if gateway emails on
             if (!$dge) {
                 mgm_notify_admin_membership_verification_failed($this->name);
             }
             // abort
             return;
         } else {
             $membership_type_verified = $member->membership_type;
         }
     }
     // set
     $membership_type = $membership_type_verified;
     // sub pack
     $subs_pack = $s_packs->get_pack($pack_id);
     // if trial on
     if (isset($subs_pack['trial_on']) && (bool) $subs_pack['trial_on'] == true) {
         $member->trial_on = $subs_pack['trial_on'];
         $member->trial_cost = $subs_pack['trial_cost'];
         $member->trial_duration = $subs_pack['trial_duration'];
         $member->trial_duration_type = $subs_pack['trial_duration_type'];
         $member->trial_num_cycles = $subs_pack['trial_num_cycles'];
     }
     //pack currency over rides genral setting currency - issue #1602
     if (isset($subs_pack['currency']) && $subs_pack['currency'] != $currency) {
         $currency = $subs_pack['currency'];
     }
     // duration
     $member->duration = $duration;
     $member->duration_type = strtolower($duration_type);
     $member->amount = $amount;
     $member->currency = $currency;
     $member->membership_type = $membership_type;
     $member->pack_id = $pack_id;
     // $member->payment_type = 'subscription';
     //save num_cycles in mgm_member object:(issue#: 478)
     $member->active_num_cycles = isset($num_cycles) && !empty($num_cycles) ? $num_cycles : $subs_pack['num_cycles'];
     $member->payment_type = (int) $member->active_num_cycles == 1 ? 'one-time' : 'subscription';
     // payment info for unsubscribe
     if (!isset($member->payment_info)) {
         $member->payment_info = new stdClass();
     }
     // module
     $member->payment_info->module = $this->code;
     // transaction type
     if (isset($this->response['transaction_type'])) {
         $member->payment_info->txn_type = $this->response['transaction_type'];
     }
     // subscription
     if (isset($this->response['subscription_id'])) {
         // set
         $member->payment_info->subscr_id = $this->response['subscription_id'];
         // reset rebilled count
         if (isset($member->rebilled)) {
             unset($member->rebilled);
         }
     }
     // transaction
     if (isset($this->response['transaction_id'])) {
         $member->payment_info->txn_id = $this->response['transaction_id'];
     }
     // mgm transaction id
     $member->transaction_id = $alt_tran_id;
     // process response
     $new_status = $update_role = false;
     // errors
     $errors = array();
     // response code
     $response_code = $this->_get_response_code($this->response['response_status'], 'status');
     // status
     switch ($response_code) {
         case 'Approved':
             // status
             $new_status = MGM_STATUS_ACTIVE;
             $member->status_str = __('Last payment was successful', 'mgm');
             // current time
             $time = time();
             $last_pay_date = isset($member->last_pay_date) ? $member->last_pay_date : null;
             // last pay date
             $member->last_pay_date = date('Y-m-d', $time);
             // default expire_date_ts to calculate next cycle expire date
             $expire_date_ts = $time;
             // check subscription_option
             if (isset($subscription_option)) {
                 // on option
                 switch ($subscription_option) {
                     // @ToDo, apply expire date login
                     case 'create':
                         // expire date will be based on current time
                     // expire date will be based on current time
                     case 'upgrade':
                         // expire date will be based on current time
                         // already on top
                         $expire_date_ts = $time;
                         break;
                     case 'downgrade':
                         // expire date will be based on expire_date if exists, current time other wise
                     // expire date will be based on expire_date if exists, current time other wise
                     case 'extend':
                         // expire date will be based on expire_date if exists, current time other wise
                         $expire_date_ts = $time;
                         // extend/expire date
                         //if (!empty($member->expire_date) && $member->last_pay_date != date('Y-m-d', $expire_date_ts)) {
                         // calc expiry	- issue #1226
                         // membership extend functionality broken if we try to extend the same day so removed && $last_pay_date != date('Y-m-d', $time) check
                         if (!empty($member->expire_date)) {
                             // expiry
                             $expire_date_ts2 = strtotime($member->expire_date);
                             // valid
                             // valid && expiry date is greater than today
                             if ($expire_date_ts2 > 0 && $expire_date_ts2 > $expire_date_ts) {
                                 // set it for next calc
                                 $expire_date_ts = $expire_date_ts2;
                             }
                         }
                         break;
                 }
             }
             // type expanded
             $duration_exprs = $s_packs->get_duration_exprs();
             // if not lifetime/date range
             if (in_array($member->duration_type, array_keys($duration_exprs))) {
                 // take only date exprs
                 // consider trial duration if trial period is applicable
                 if (isset($trial_on) && (bool) $trial_on == true) {
                     // Do it only once
                     if (!isset($member->rebilled) && isset($member->active_num_cycles) && $member->active_num_cycles != 1) {
                         $expire_date_ts = strtotime('+' . $trial_duration . ' ' . $duration_exprs[$trial_duration_type], $expire_date_ts);
                     }
                 } else {
                     // recalc - issue #1068
                     $expire_date_ts = strtotime('+' . $member->duration . ' ' . $duration_exprs[$member->duration_type], $expire_date_ts);
                 }
                 // formatted
                 $expire_date = date('Y-m-d', $expire_date_ts);
                 // date extended
                 if (!$member->expire_date || $expire_date_ts > strtotime($member->expire_date)) {
                     $member->expire_date = $expire_date;
                 }
             } else {
                 //if lifetime:
                 if ($member->duration_type == 'l') {
                     // el = lifetime
                     $member->expire_date = '';
                 }
                 //issue #1096
                 if ($member->duration_type == 'dr') {
                     // el = /date range
                     $member->expire_date = $duration_range_end_dt;
                 }
             }
             // update rebill: issue #: 489
             if ($member->active_num_cycles != 1) {
                 // check
                 if (!isset($member->rebilled)) {
                     $member->rebilled = 1;
                 } else {
                     if ((int) $member->rebilled < (int) $member->active_num_cycles) {
                         // 100
                         // rebill
                         $member->rebilled = (int) $member->rebilled + 1;
                     }
                 }
             }
             //clear cancellation status if already cancelled:
             if (isset($member->status_reset_on)) {
                 unset($member->status_reset_on);
             }
             if (isset($member->status_reset_as)) {
                 unset($member->status_reset_as);
             }
             // role update
             if ($role) {
                 $update_role = true;
             }
             // transaction_id
             $transaction_id = $this->_get_transaction_id();
             // hook args
             $args = array('user_id' => $user_id, 'transaction_id' => $transaction_id);
             // another membership
             if (isset($custom['is_another_membership_purchase']) && bool_from_yn($custom['is_another_membership_purchase'])) {
                 $args['another_membership'] = $custom['membership_type'];
             }
             // after succesful payment hook
             do_action('mgm_membership_transaction_success', $args);
             // backward compatibility
             do_action('mgm_subscription_purchase_payment_success', $args);
             // new organized name
             break;
         case 'Declined':
         case 'Refunded':
         case 'Denied':
             $new_status = MGM_STATUS_NULL;
             $member->status_str = __('Last payment was refunded or denied', 'mgm');
             // error
             $errors[] = $member->status_str;
             break;
         case 'Pending':
         case 'Held for Review':
             $new_status = MGM_STATUS_PENDING;
             $reason = $this->response['message_text'];
             $member->status_str = sprintf(__('Last payment is pending. Reason: %s', 'mgm'), $reason);
             // error
             $errors[] = $member->status_str;
             break;
         default:
             $new_status = MGM_STATUS_ERROR;
             $member->status_str = sprintf(__('Last payment status: %s', 'mgm'), $response_code . ' - ' . $this->response['message_text']);
             // error
             $errors[] = $member->status_str;
             break;
     }
     // old status
     $old_status = $member->status;
     // set new status
     $member->status = $new_status;
     // whether to acknowledge the user by email - This should happen only once
     $acknowledge_user = $this->send_payment_email($alt_tran_id);
     // whether to subscriber the user to Autoresponder - This should happen only once
     $acknowledge_ar = mgm_subscribe_to_autoresponder($member, $alt_tran_id);
     // update member
     // another_subscription modification
     if (isset($custom['is_another_membership_purchase']) && bool_from_yn($custom['is_another_membership_purchase'])) {
         // issue #1227
         // hide old content
         if ($subs_pack['hide_old_content']) {
             $member->hide_old_content = $subs_pack['hide_old_content'];
         }
         // save
         mgm_save_another_membership_fields($member, $user_id);
         // Multiple membership upgrade: first time
         if (isset($custom['multiple_upgrade_prev_packid']) && is_numeric($custom['multiple_upgrade_prev_packid'])) {
             mgm_multiple_upgrade_save_memberobject($custom, $member->transaction_id);
         }
     } else {
         $member->save();
     }
     // status change event
     do_action('mgm_user_status_change', $user_id, $new_status, $old_status, 'module_' . $this->module, $member->pack_id);
     //update coupon usage
     do_action('mgm_update_coupon_usage', array('user_id' => $user_id));
     // update role
     if ($update_role) {
         $obj_role = new mgm_roles();
         $obj_role->add_user_role($user_id, $role);
     }
     // return action
     do_action('mgm_return_' . $this->module, array('user_id' => $user_id));
     // backward compatibility
     do_action('mgm_return_subscription_payment_' . $this->module, array('user_id' => $user_id));
     // new , individual
     do_action('mgm_return_subscription_payment', array('user_id' => $user_id, 'acknowledge_ar' => $acknowledge_ar, 'mgm_member' => $member));
     // new, global: pass mgm_member object to consider multiple level purchases as well.
     // read member again for internal updates if any
     // another_subscription modification
     if (isset($custom['is_another_membership_purchase']) && bool_from_yn($custom['is_another_membership_purchase'])) {
         $member = mgm_get_member_another_purchase($user_id, $custom['membership_type']);
     } else {
         $member = mgm_get_member($user_id);
     }
     // transaction status
     mgm_update_transaction_status($member->transaction_id, $member->status, $member->status_str);
     // send email notification to client
     $blogname = get_option('blogname');
     // notify
     if ($acknowledge_user) {
         // notify user, only if gateway emails on
         if (!$dpne) {
             // notify
             if (mgm_notify_user_membership_purchase($blogname, $user, $member, $custom, $subs_pack, $s_packs, $system_obj)) {
                 // update as email sent
                 $this->update_paymentemail_sent($alt_tran_id);
             }
         }
         // notify admin, only if gateway emails on
         if (!$dge) {
             // pack duration
             $pack_duration = $s_packs->get_pack_duration($subs_pack);
             // notify admin,
             mgm_notify_admin_membership_purchase($blogname, $user, $member, $pack_duration);
         }
     }
     //exit if from Silent Post:
     if (isset($_POST['x_subscription_id'])) {
         exit;
     }
     // error condition redirect
     if (count($errors) > 0) {
         mgm_redirect(add_query_arg(array('status' => 'error', 'errors' => implode('|', $errors)), $this->_get_thankyou_url()));
     }
 }
 /**
  * update buy subscription response
  *
  */
 function _buy_membership($internal)
 {
     $send_email = !$internal;
     // system
     $system_obj = mgm_get_class('system');
     $s_packs = mgm_get_class('subscription_packs');
     $dge = bool_from_yn($system_obj->get_setting('disable_gateway_emails'));
     $dpne = bool_from_yn($system_obj->get_setting('disable_payment_notify_emails'));
     // get passthrough, stop further process if fails to parse
     $custom = $this->_get_transaction_passthrough($_POST['custom']);
     // local var
     extract($custom);
     // currency
     if (!$currency) {
         $currency = $this->setting['currency'];
     }
     // find user
     $user = get_userdata($user_id);
     // multiple subscription level modification
     if (isset($custom['is_another_membership_purchase']) && bool_from_yn($custom['is_another_membership_purchase'])) {
         $member = mgm_get_member_another_purchase($user_id, $custom['membership_type']);
     } else {
         $member = mgm_get_member($user_id);
     }
     // Get the current AC join date
     if (!($join_date = $member->join_date)) {
         $member->join_date = time();
     }
     // Set current AC join date
     // if there is no duration set in the user object then run the following code
     if (empty($duration_type)) {
         //if there is no duration type then use Months
         $duration_type = 'm';
     }
     // membership type default
     if (empty($membership_type)) {
         //if there is no account type in the custom string then use the existing type
         $membership_type = md5($member->membership_type);
     }
     // validate parent method
     $membership_type_verified = $this->_validate_membership_type($membership_type, 'md5|plain');
     // verified
     if (!$membership_type_verified) {
         if (strtolower($member->membership_type) != 'free') {
             // notify admin, only if gateway emails on
             if (!$dge) {
                 mgm_notify_admin_membership_verification_failed($this->name);
             }
             // abort
             return;
         } else {
             $membership_type_verified = $member->membership_type;
         }
     }
     // set
     $membership_type = $membership_type_verified;
     // sub pack
     $subs_pack = $s_packs->get_pack($pack_id);
     // if trial on
     if ($subs_pack['trial_on']) {
         $member->trial_on = $subs_pack['trial_on'];
         $member->trial_cost = $subs_pack['trial_cost'];
         $member->trial_duration = $subs_pack['trial_duration'];
         $member->trial_duration_type = $subs_pack['trial_duration_type'];
         $member->trial_num_cycles = $subs_pack['trial_num_cycles'];
     }
     //pack currency over rides genral setting currency - issue #1602
     if (isset($subs_pack['currency']) && $subs_pack['currency'] != $currency) {
         $currency = $subs_pack['currency'];
     }
     // duration
     $member->duration = $duration;
     $member->duration_type = strtolower($duration_type);
     $member->amount = $amount;
     $member->currency = $currency;
     $member->membership_type = $membership_type;
     $member->pack_id = $pack_id;
     // $member->payment_type    = 'subscription';
     $member->active_num_cycles = isset($num_cycles) && !empty($num_cycles) ? $num_cycles : $subs_pack['num_cycles'];
     $member->payment_type = (int) $member->active_num_cycles == 1 ? 'one-time' : 'subscription';
     // payment info for unsubscribe
     if (!isset($member->payment_info)) {
         $member->payment_info = new stdClass();
     }
     $member->payment_info->module = $this->code;
     // transaction type
     $member->payment_info->txn_type = 'subscription';
     // subscriber id
     if (isset($this->response['PROFILEID'])) {
         $member->payment_info->subscr_id = $this->response['PROFILEID'];
     }
     // refer id
     if (isset($this->response['CORRELATIONID'])) {
         $member->payment_info->txn_id = $this->response['CORRELATIONID'];
     }
     // mgm transaction id
     $member->transaction_id = $_POST['custom'];
     // process PayPal response
     $new_status = $update_role = false;
     // status
     $payment_status = 'Error';
     //if submitted FROM IPN
     if (isset($_POST['txn_type'])) {
         //exit if IPN posts after a successful recurring proile creation
         if ($_POST['txn_type'] == 'recurring_payment_profile_created') {
             exit;
         } elseif (in_array($_POST['txn_type'], array('recurring_payment', 'subscr_payment', 'express_checkout'))) {
             //for sandbox only
             if ($this->status == 'test' && $_POST['payment_status'] == 'Pending') {
                 $_POST['payment_status'] = 'Completed';
             }
             $payment_status = $_POST['payment_status'];
         }
     } else {
         //NORMAL SUBMISSION:
         //if recurring:
         if (isset($this->response['PROFILEID']) && !empty($this->response['PROFILEID'])) {
             $send_email = true;
             $payment_status = 'Completed';
         } else {
             //one-time
             $payment_status = isset($this->response['PAYMENTINFO_0_PAYMENTSTATUS']) ? $this->response['PAYMENTINFO_0_PAYMENTSTATUS'] : $this->response['PAYMENTSTATUS'];
         }
         //if in test mode, treat Pending as Completed
         if ($this->status == 'test' && strtoupper($payment_status) == 'PENDING') {
             $payment_status = 'Completed';
         }
     }
     // status
     switch ($payment_status) {
         case 'Success':
         case 'SuccessWithWarning':
         case 'Completed':
         case 'Processed':
             $new_status = MGM_STATUS_ACTIVE;
             $member->status_str = __('Last payment was successful', 'mgm');
             $time = time();
             $last_pay_date = isset($member->last_pay_date) ? $member->last_pay_date : null;
             $member->last_pay_date = date('Y-m-d', $time);
             // check subscription_option
             if (isset($subscription_option)) {
                 // on option
                 switch ($subscription_option) {
                     // @ToDo, apply expire date login
                     case 'create':
                         // expire date will be based on current time
                     // expire date will be based on current time
                     case 'upgrade':
                         // expire date will be based on current time
                         // already on top
                         break;
                     case 'downgrade':
                         // expire date will be based on expire_date if exists, current time other wise
                     // expire date will be based on expire_date if exists, current time other wise
                     case 'extend':
                         // expire date will be based on expire_date if exists, current time other wise
                         // extend/expire date
                         // calc expiry	- issue #1226
                         // membership extend functionality broken if we try to extend the same day so removed && $last_pay_date != date('Y-m-d', $time) check
                         if (!empty($member->expire_date)) {
                             $expiry = strtotime($member->expire_date);
                             if ($expiry > 0 && $expiry > $time) {
                                 $time = $expiry;
                             }
                         }
                         break;
                 }
             }
             // type expanded
             $duration_exprs = $s_packs->get_duration_exprs();
             // if not lifetime/date range
             if (in_array($member->duration_type, array_keys($duration_exprs))) {
                 // take only date exprs
                 //consider trial duration if trial period is applicable
                 if (isset($trial_on) && $trial_on == 1) {
                     //Do it only once
                     if (!isset($member->rebilled) && isset($member->active_num_cycles) && $member->active_num_cycles != 1) {
                         $time = strtotime('+' . $trial_duration . ' ' . $duration_exprs[$trial_duration_type], $time);
                     }
                 } else {
                     // time - issue #1068
                     $time = strtotime('+' . $member->duration . ' ' . $duration_exprs[$member->duration_type], $time);
                 }
                 // formatted
                 $time_str = date('Y-m-d', $time);
                 // date extended
                 if (!$member->expire_date || strtotime($time_str) > strtotime($member->expire_date)) {
                     $member->expire_date = $time_str;
                 }
             } else {
                 //if lifetime:
                 if ($member->duration_type == 'l') {
                     // el = lifetime
                     $member->expire_date = '';
                 }
                 //issue #1096
                 if ($member->duration_type == 'dr') {
                     // el = /date range
                     $member->expire_date = $duration_range_end_dt;
                 }
             }
             //update rebill: issue #: 489
             if ($member->active_num_cycles != 1 && (int) $member->rebilled < (int) $member->active_num_cycles) {
                 // rebill
                 $member->rebilled = !$member->rebilled ? 1 : (int) $member->rebilled + 1;
             }
             //cancel previous subscription:
             //This is required only for the transactions initiated by the user
             $this->cancel_recurring_subscription($_POST['custom'], null, null, $pack_id);
             //clear cancellation status if already cancelled:
             if (isset($member->status_reset_on)) {
                 unset($member->status_reset_on);
             }
             if (isset($member->status_reset_as)) {
                 unset($member->status_reset_as);
             }
             // role update
             if ($role) {
                 $update_role = true;
             }
             // transaction_id
             $transaction_id = $this->_get_transaction_id();
             // hook args
             $args = array('user_id' => $user_id, 'transaction_id' => $transaction_id);
             // another membership
             if (isset($custom['is_another_membership_purchase']) && bool_from_yn($custom['is_another_membership_purchase'])) {
                 $args['another_membership'] = $custom['membership_type'];
             }
             // after succesful payment hook
             do_action('mgm_membership_transaction_success', $args);
             // backward compatibility
             do_action('mgm_subscription_purchase_payment_success', $args);
             // new organized name
             break;
         case 'Failure':
         case 'FailureWithWarning':
         case 'Failed':
             $new_status = MGM_STATUS_NULL;
             $member->status_str = __('Last paymentis failed', 'mgm');
             break;
         case 'Denied':
         case 'Refunded':
             $new_status = MGM_STATUS_NULL;
             $member->status_str = __('Last payment was refunded or denied', 'mgm');
             break;
         case 'Pending':
         case 'In-Progress':
             $new_status = MGM_STATUS_PENDING;
             if (isset($this->response['PAYMENTINFO_0_PENDINGREASON'])) {
                 $reason = $this->response['PAYMENTINFO_0_PENDINGREASON'];
             } elseif (isset($_POST['pending_reason'])) {
                 $reason = $_POST['pending_reason'];
             } else {
                 $reason = $payment_status;
             }
             $member->status_str = sprintf(__('Last payment is pending. Reason: %s', 'mgm'), $reason);
             break;
         default:
             $new_status = MGM_STATUS_ERROR;
             $member->status_str = sprintf(__('Last payment status: %s', 'mgm'), $payment_status);
             break;
     }
     // handle exceptions from the subscription specific fields
     if ($new_status == MGM_STATUS_ACTIVE && in_array($_POST['txn_type'], array('subscr_failed', 'subscr_eot'))) {
         $new_status = MGM_STATUS_NULL;
         $member->status_str = __('The subscription is not active', 'mgm');
     }
     // old status
     $old_status = $member->status;
     // set new status
     $member->status = $new_status;
     // whether to acknowledge the user - This should happen only once
     $acknowledge_user = $this->send_payment_email($_POST['custom']);
     // whether to subscriber the user to Autoresponder - This should happen only once
     $acknowledge_ar = mgm_subscribe_to_autoresponder($member, $_POST['custom']);
     // another_subscription modification
     if (isset($custom['is_another_membership_purchase']) && bool_from_yn($custom['is_another_membership_purchase'])) {
         //issue #1227
         if ($subs_pack['hide_old_content']) {
             $member->hide_old_content = $subs_pack['hide_old_content'];
         }
         // save
         mgm_save_another_membership_fields($member, $user_id);
         // Multiple membership upgrade: first time
         if (isset($custom['multiple_upgrade_prev_packid']) && is_numeric($custom['multiple_upgrade_prev_packid'])) {
             mgm_multiple_upgrade_save_memberobject($custom, $member->transaction_id);
         }
     } else {
         $member->save();
     }
     // status change event
     do_action('mgm_user_status_change', $user_id, $new_status, $old_status, 'module_' . $this->module, $member->pack_id);
     //update coupon usage
     do_action('mgm_update_coupon_usage', array('user_id' => $user_id));
     // role
     if ($update_role) {
         $obj_role = new mgm_roles();
         $obj_role->add_user_role($user_id, $role);
     }
     // return action
     do_action('mgm_return_' . $this->module, array('user_id' => $user_id));
     // backward compatibility
     do_action('mgm_return_subscription_payment_' . $this->module, array('user_id' => $user_id));
     // new , individual
     do_action('mgm_return_subscription_payment', array('user_id' => $user_id, 'acknowledge_ar' => $acknowledge_ar, 'mgm_member' => $member));
     // new, global: pass mgm_member object to consider multiple level purchases as well.
     // read member again for internal updates if any
     // another_subscription modification
     if (isset($custom['is_another_membership_purchase']) && bool_from_yn($custom['is_another_membership_purchase'])) {
         $member = mgm_get_member_another_purchase($user_id, $custom['membership_type']);
     } else {
         $member = mgm_get_member($user_id);
     }
     // transaction status
     mgm_update_transaction_status($member->transaction_id, $member->status, $member->status_str);
     // send email notification to client
     $blogname = get_option('blogname');
     //let the mail send only for IPN update:
     if ($send_email) {
         if ($acknowledge_user) {
             // notify user, only if gateway emails on
             if (!$dpne) {
                 // notify
                 if (mgm_notify_user_membership_purchase($blogname, $user, $member, $custom, $subs_pack, $s_packs, $system_obj)) {
                     // update as email sent
                     $this->update_paymentemail_sent($_POST['custom']);
                 }
             }
             // notify admin, only if gateway emails on
             if (!$dge) {
                 // pack duration
                 $pack_duration = $s_packs->get_pack_duration($subs_pack);
                 // notify admin,
                 mgm_notify_admin_membership_purchase($blogname, $user, $member, $pack_duration);
             }
         }
     }
     //error redirection:
     if ($internal && $member->status != MGM_STATUS_ACTIVE) {
         $errors = isset($this->response['L_ERRORCODE0']) && !empty($this->response['L_ERRORCODE0']) ? urlencode($this->response['L_ERRORCODE0'] . ': ' . $this->response['L_SHORTMESSAGE0'] . ' - ' . $this->response['L_LONGMESSAGE0']) : __('An error occured while porcessing payment.', 'mgm') . ': ' . $member->status_str;
         mgm_redirect(add_query_arg(array('status' => 'error', 'errors' => $errors), $this->_get_thankyou_url()));
         exit;
     }
 }
 function _buy_membership()
 {
     // system
     $system_obj = mgm_get_class('system');
     $s_packs = mgm_get_class('subscription_packs');
     $dge = bool_from_yn($system_obj->get_setting('disable_gateway_emails'));
     $dpne = bool_from_yn($system_obj->get_setting('disable_payment_notify_emails'));
     // passthrough
     $alt_tran_id = $this->_get_alternate_transaction_id();
     // get passthrough, stop further process if fails to parse
     $custom = $this->_get_transaction_passthrough($alt_tran_id);
     // local var
     extract($custom);
     // currency
     if (!$currency) {
         $currency = $this->setting['currency'];
     }
     // find user
     $user = get_userdata($user_id);
     // another_subscription modification
     if (isset($custom['is_another_membership_purchase']) && bool_from_yn($custom['is_another_membership_purchase'])) {
         $member = mgm_get_member_another_purchase($user_id, $custom['membership_type']);
     } else {
         $member = mgm_get_member($user_id);
     }
     // Get the current AC join date
     if (!($join_date = $member->join_date)) {
         $member->join_date = time();
     }
     // Set current AC join date
     //if there is no duration set in the user object then run the following code
     if (empty($duration_type)) {
         //if there is no duration type then use Months
         $duration_type = 'm';
     }
     // membership type default
     if (empty($membership_type)) {
         //if there is no account type in the custom string then use the existing type
         $membership_type = md5($member->membership_type);
     }
     // validate parent method
     $membership_type_verified = $this->_validate_membership_type($membership_type, 'md5|plain');
     // verified
     if (!$membership_type_verified) {
         if (strtolower($member->membership_type) != 'free') {
             // notify admin, only if gateway emails on
             if (!$dge) {
                 mgm_notify_admin_membership_verification_failed($this->name);
             }
             // abort
             return;
         } else {
             $membership_type_verified = $member->membership_type;
         }
     }
     // set
     $membership_type = $membership_type_verified;
     // sub pack
     $subs_pack = $s_packs->get_pack($pack_id);
     // if trial on
     if ($subs_pack['trial_on']) {
         $member->trial_on = $subs_pack['trial_on'];
         $member->trial_cost = $subs_pack['trial_cost'];
         $member->trial_duration = $subs_pack['trial_duration'];
         $member->trial_duration_type = $subs_pack['trial_duration_type'];
         $member->trial_num_cycles = $subs_pack['trial_num_cycles'];
     }
     //pack currency over rides genral setting currency - issue #1602
     if (isset($subs_pack['currency']) && $subs_pack['currency'] != $currency) {
         $currency = $subs_pack['currency'];
     }
     // duration
     $member->duration = $duration;
     $member->duration_type = strtolower($duration_type);
     $member->amount = $amount;
     $member->currency = $currency;
     $member->membership_type = $membership_type;
     $member->pack_id = $pack_id;
     // $member->payment_type    = 'subscription';
     $member->active_num_cycles = isset($num_cycles) && !empty($num_cycles) ? $num_cycles : $subs_pack['num_cycles'];
     $member->payment_type = (int) $member->active_num_cycles == 1 ? 'one-time' : 'subscription';
     // payment info for unsubscribe
     // tracking fields module_field => post_field
     $tracking_fields = array('txn_type' => 'message_type', 'subscr_id' => array('order_number', 'sale_id'), 'txn_id' => array('order_number', 'sale_id'));
     // save tracking fields
     $this->_save_tracking_fields($tracking_fields, $member);
     // mgm transaction_id id
     $member->transaction_id = $alt_tran_id;
     // process response
     $new_status = false;
     $update_role = false;
     //FOR INS recurring
     if (isset($_POST['credit_card_processed'])) {
         $response_status = $_POST['credit_card_processed'];
     } elseif (isset($_POST['recurring']) && $_POST['recurring'] == 1) {
         switch ($_POST['message_type']) {
             case 'RECURRING_INSTALLMENT_SUCCESS':
                 $response_status = 'Y';
                 break;
             case 'RECURRING_INSTALLMENT_FAILED':
                 $response_status = 'K';
                 break;
             case 'RECURRING_STOPPED':
             case 'RECURRING_COMPLETE':
                 $response_status = 'Expired';
                 break;
             default:
                 $response_status = 'Other';
                 break;
         }
     }
     // response status
     switch ($response_status) {
         case 'Y':
             $new_status = MGM_STATUS_ACTIVE;
             $member->status_str = __('Last payment was successful', 'mgm');
             $time = time();
             $last_pay_date = isset($member->last_pay_date) ? $member->last_pay_date : null;
             $member->last_pay_date = date('Y-m-d', $time);
             // check subscription_option
             if (isset($subscription_option)) {
                 // on option
                 switch ($subscription_option) {
                     // @ToDo, apply expire date login
                     case 'create':
                         // expire date will be based on current time
                     // expire date will be based on current time
                     case 'upgrade':
                         // expire date will be based on current time
                         // already on top
                         break;
                     case 'downgrade':
                         // expire date will be based on expire_date if exists, current time other wise
                     // expire date will be based on expire_date if exists, current time other wise
                     case 'extend':
                         // expire date will be based on expire_date if exists, current time other wise
                         // extend/expire date
                         // update expire date
                         // calc expiry	- issue #1226
                         // membership extend functionality broken if we try to extend the same day so removed && $last_pay_date != date('Y-m-d', $time) check
                         if (!empty($member->expire_date)) {
                             $expiry = strtotime($member->expire_date);
                             if ($expiry > 0 && $expiry > $time) {
                                 $time = $expiry;
                             }
                         }
                         break;
                 }
             }
             // type expanded
             $duration_exprs = $s_packs->get_duration_exprs();
             // if not lifetime/date range
             if (in_array($member->duration_type, array_keys($duration_exprs))) {
                 // take only date exprs
                 //consider trial duration if trial period is applicable
                 if (isset($trial_on) && $trial_on == 1) {
                     //Do it only once
                     if (!isset($member->rebilled) && isset($member->active_num_cycles) && $member->active_num_cycles != 1) {
                         $time = strtotime("+{$trial_duration} {$duration_exprs[$trial_duration_type]}", $time);
                     }
                 } else {
                     // time - issue #1068
                     $time = strtotime("+{$member->duration} {$duration_exprs[$member->duration_type]}", $time);
                 }
                 // formatted
                 $time_str = date('Y-m-d', $time);
                 // date extended
                 if (!$member->expire_date || strtotime($time_str) > strtotime($member->expire_date)) {
                     $member->expire_date = $time_str;
                 }
             } else {
                 //if lifetime:
                 if ($member->duration_type == 'l') {
                     // el = lifetime
                     $member->expire_date = '';
                 }
                 //issue #1096
                 if ($member->duration_type == 'dr') {
                     // el = /date range
                     $member->expire_date = $duration_range_end_dt;
                 }
             }
             //update rebill: issue #: 489
             if ($member->active_num_cycles != 1 && (int) $member->rebilled < (int) $member->active_num_cycles) {
                 // rebill
                 $member->rebilled = !$member->rebilled ? 1 : (int) $member->rebilled + 1;
             }
             //cancel previous subscription:
             //issue#: 565
             $this->cancel_recurring_subscription($alt_tran_id, null, null, $pack_id);
             //clear cancellation status if already cancelled:
             if (isset($member->status_reset_on)) {
                 unset($member->status_reset_on);
             }
             if (isset($member->status_reset_as)) {
                 unset($member->status_reset_as);
             }
             // role
             if ($role) {
                 $update_role = true;
             }
             // transaction_id
             $transaction_id = $this->_get_transaction_id();
             // hook args
             $args = array('user_id' => $user_id, 'transaction_id' => $transaction_id);
             // another membership
             if (isset($custom['is_another_membership_purchase']) && bool_from_yn($custom['is_another_membership_purchase'])) {
                 $args['another_membership'] = $custom['membership_type'];
             }
             // after succesful payment hook
             do_action('mgm_membership_transaction_success', $args);
             // backward compatibility
             do_action('mgm_subscription_purchase_payment_success', $args);
             // new organized name
             break;
         case 'K':
             $new_status = MGM_STATUS_NULL;
             $member->status_str = __('Last payment was refunded or denied', 'mgm');
             break;
         case 'Pending':
             $new_status = MGM_STATUS_PENDING;
             $reason = 'Unknown';
             $member->status_str = sprintf(__('Last payment is pending. Reason: %s', 'mgm'), $reason);
             break;
         case 'Expired':
             $new_status = MGM_STATUS_EXPIRED;
             $reason = 'Expired';
             $member->status_str = sprintf(__('Recurring subscription expired. Reason: %s', 'mgm'), $reason);
             break;
         default:
             $new_status = MGM_STATUS_ERROR;
             $member->status_str = sprintf(__('Last payment status: %s', 'mgm'), $_POST['credit_card_processed']);
             break;
     }
     // old status
     $old_status = $member->status;
     // set new status
     $member->status = $new_status;
     // whether to acknowledge the user - This should happen only once
     $acknowledge_user = $this->send_payment_email($alt_tran_id);
     // whether to subscriber the user to Autoresponder - This should happen only once
     $acknowledge_ar = mgm_subscribe_to_autoresponder($member, $alt_tran_id);
     //another_subscription modification
     if (isset($custom['is_another_membership_purchase']) && bool_from_yn($custom['is_another_membership_purchase'])) {
         //issue #1227
         if ($subs_pack['hide_old_content']) {
             $member->hide_old_content = $subs_pack['hide_old_content'];
         }
         mgm_save_another_membership_fields($member, $user_id);
         // Multiple membership upgrade: first time
         if (isset($custom['multiple_upgrade_prev_packid']) && is_numeric($custom['multiple_upgrade_prev_packid'])) {
             mgm_multiple_upgrade_save_memberobject($custom, $member->transaction_id);
         }
     } else {
         $member->save();
     }
     // action
     do_action('mgm_user_status_change', $user_id, $new_status, $old_status, 'module_' . $this->module, $member->pack_id);
     //update coupon usage
     do_action('mgm_update_coupon_usage', array('user_id' => $user_id));
     // update role
     if ($update_role) {
         //update role;
         $obj_role = new mgm_roles();
         // add
         $obj_role->add_user_role($user_id, $role);
     }
     // return action
     do_action('mgm_return_' . $this->module, array('user_id' => $user_id));
     // backward compatibility
     do_action('mgm_return_subscription_payment_' . $this->module, array('user_id' => $user_id));
     // new , individual
     do_action('mgm_return_subscription_payment', array('user_id' => $user_id, 'acknowledge_ar' => $acknowledge_ar, 'mgm_member' => $member));
     // new, global: pass mgm_member object to consider multiple level purchases as well.
     // another_subscription modification
     if (isset($custom['is_another_membership_purchase']) && bool_from_yn($custom['is_another_membership_purchase'])) {
         $member = mgm_get_member_another_purchase($user_id, $custom['membership_type']);
     } else {
         $member = mgm_get_member($user_id);
     }
     // transaction status
     mgm_update_transaction_status($member->transaction_id, $member->status, $member->status_str);
     // send email notification to client
     $blogname = get_option('blogname');
     // notify
     if ($acknowledge_user) {
         // notify user, only if gateway emails on
         if (!$dpne) {
             // notify
             if (mgm_notify_user_membership_purchase($blogname, $user, $member, $custom, $subs_pack, $s_packs, $system_obj)) {
                 // update as email sent
                 $this->update_paymentemail_sent($alt_tran_id);
             }
         }
         // notify admin, only if gateway emails on
         if (!$dge) {
             // pack duration
             $pack_duration = $s_packs->get_pack_duration($subs_pack);
             // notify admin,
             mgm_notify_admin_membership_purchase($blogname, $user, $member, $pack_duration);
         }
     }
 }
 function _buy_membership()
 {
     // system
     $system_obj = mgm_get_class('system');
     $s_packs = mgm_get_class('subscription_packs');
     $dge = bool_from_yn($system_obj->get_setting('disable_gateway_emails'));
     $dpne = bool_from_yn($system_obj->get_setting('disable_payment_notify_emails'));
     // get passthrough, stop further process if fails to parse
     $custom = $this->_get_transaction_passthrough($_POST['custom']);
     // local var
     extract($custom);
     // currency
     if (!$currency) {
         $currency = $system_obj->get_setting('currency');
     }
     // find user
     $user = get_userdata($user_id);
     // another_subscription modification
     if (isset($custom['is_another_membership_purchase']) && bool_from_yn($custom['is_another_membership_purchase'])) {
         $member = mgm_get_member_another_purchase($user_id, $custom['membership_type']);
     } else {
         $member = mgm_get_member($user_id);
     }
     // Get the current AC join date
     if (!($join_date = $member->join_date)) {
         $member->join_date = time();
     }
     // Set current AC join date
     //if there is no duration set in the user object then run the following code
     if (empty($duration_type)) {
         //if there is no duration type then use Months
         $duration_type = 'm';
     }
     // membership type default
     if (empty($membership_type)) {
         //if there is no account type in the custom string then use the existing type
         $membership_type = md5($member->membership_type);
     }
     // validate parent method
     $membership_type_verified = $this->_validate_membership_type($membership_type, 'md5|plain');
     // verified
     if (!$membership_type_verified) {
         // free
         if (strtolower($member->membership_type) != 'free') {
             // notify admin, only if gateway emails on
             if (!$dge) {
                 mgm_notify_admin_membership_verification_failed($this->name);
             }
             // abort
             return;
         } else {
             $membership_type_verified = $member->membership_type;
         }
     }
     // set
     $membership_type = $membership_type_verified;
     // sub pack
     $subs_pack = $s_packs->get_pack($pack_id);
     // if trial on
     if ($subs_pack['trial_on']) {
         $member->trial_on = $subs_pack['trial_on'];
         $member->trial_cost = $subs_pack['trial_cost'];
         $member->trial_duration = $subs_pack['trial_duration'];
         $member->trial_duration_type = $subs_pack['trial_duration_type'];
         $member->trial_num_cycles = $subs_pack['trial_num_cycles'];
     }
     //pack currency over rides genral setting currency - issue #1602
     if (isset($subs_pack['currency']) && $subs_pack['currency'] != $currency) {
         $currency = $subs_pack['currency'];
     }
     // duration
     $member->duration = $duration;
     $member->duration_type = strtolower($duration_type);
     $member->amount = $amount;
     $member->currency = $currency;
     $member->membership_type = $membership_type;
     $member->pack_id = $pack_id;
     // $member->payment_type = ($_POST['txn_type']=='subscr_signup' || $_POST['txn_type'] =='subscr_payment') ? 'subscription' : 'one-time';
     $member->active_num_cycles = isset($num_cycles) && !empty($num_cycles) ? $num_cycles : $subs_pack['num_cycles'];
     $member->payment_type = (int) $member->active_num_cycles == 1 ? 'one-time' : 'subscription';
     // payment info for unsubscribe
     if (!isset($member->payment_info)) {
         $member->payment_info = new stdClass();
     }
     // set module
     $member->payment_info->module = $this->code;
     // pagseguro transaction type
     if (isset($_POST['type'])) {
         $member->payment_info->txn_type = $_POST['type'];
     }
     // pagsegurosubscription id
     /*if(isset($_POST['code'])){
     			$member->payment_info->subscr_id = $_POST['code'];		
     		}*/
     // pagseguro transaction id
     if (isset($_POST['code'])) {
         $member->payment_info->txn_id = $_POST['code'];
     }
     // mgm transaction id
     $member->transaction_id = $_POST['custom'];
     // process PagSeguro response
     $new_status = $update_role = false;
     // status
     switch ($_POST['status_code']) {
         case 'Paid':
         case 'Available':
             // 2 IPN occurs for successful payment, Paid first and after 14 days Available
             // refer https://pagseguro.uol.com.br/v2/guia-de-integracao/api-de-notificacoes.html
             // status
             $new_status = MGM_STATUS_ACTIVE;
             $member->status_str = __('Last payment was successful', 'mgm');
             // old type match
             $old_membership_type = mgm_get_user_membership_type($user_id, 'code');
             // set new pack join date
             if ($old_membership_type != $membership_type) {
                 $member->join_date = time();
                 // type join date as different var
             }
             // old content hide
             $member->hide_old_content = $hide_old_content;
             // time
             $time = time();
             $last_pay_date = isset($member->last_pay_date) ? $member->last_pay_date : null;
             // last pay
             $member->last_pay_date = date('Y-m-d', $time);
             // THIS will cause double calculation pagseguro, check applied
             /* *********************************************************************************/
             // check subscription_option
             if (isset($subscription_option)) {
                 // on option
                 switch ($subscription_option) {
                     // @ToDo, apply expire date login
                     case 'create':
                         // expire date will be based on current time
                     // expire date will be based on current time
                     case 'upgrade':
                         // expire date will be based on current time
                         // already on top
                         break;
                     case 'downgrade':
                         // expire date will be based on expire_date if exists, current time other wise
                     // expire date will be based on expire_date if exists, current time other wise
                     case 'extend':
                         // expire date will be based on expire_date if exists, current time other wise
                         // extend/expire date
                         // calc expiry	- issue #1226
                         // membership extend functionality broken if we try to extend the same day so removed && $last_pay_date != date('Y-m-d', $time) check
                         if (!empty($member->expire_date)) {
                             $expiry = strtotime($member->expire_date);
                             if ($expiry > 0 && $expiry > $time) {
                                 $time = $expiry;
                             }
                         }
                         break;
                 }
             }
             /***********************************************************************************/
             // type expanded
             $duration_exprs = $s_packs->get_duration_exprs();
             // if not lifetime/date range
             if (in_array($member->duration_type, array_keys($duration_exprs))) {
                 // take only date exprs
                 //consider trial duration if trial period is applicable
                 if (isset($trial_on) && $trial_on == 1) {
                     //Do it only once
                     if (!isset($member->rebilled) && isset($member->active_num_cycles) && $member->active_num_cycles != 1) {
                         $time = strtotime("+{$trial_duration} {$duration_exprs[$trial_duration_type]}", $time);
                     }
                 } else {
                     // time - issue #1068
                     $time = strtotime("+{$member->duration} {$duration_exprs[$member->duration_type]}", $time);
                 }
                 // formatted
                 $time_str = date('Y-m-d', $time);
                 // date extended
                 if (!$member->expire_date || strtotime($time_str) > strtotime($member->expire_date)) {
                     $member->expire_date = $time_str;
                 }
             } else {
                 //if lifetime:
                 if ($member->duration_type == 'l') {
                     // el = lifetime
                     $member->expire_date = '';
                 }
                 //issue #1096
                 if ($member->duration_type == 'dr') {
                     // el = /date range
                     $member->expire_date = $duration_range_end_dt;
                 }
             }
             //update rebill: issue #: 489
             if ($member->active_num_cycles != 1 && (int) $member->rebilled < (int) $member->active_num_cycles) {
                 // rebill
                 $member->rebilled = !$member->rebilled ? 1 : (int) $member->rebilled + 1;
             }
             //cancel previous subscription:
             //issue#: 565
             $this->cancel_recurring_subscription($_POST['custom'], null, null, $pack_id);
             // role update
             if ($role) {
                 $update_role = true;
             }
             // transaction_id
             $transaction_id = $this->_get_transaction_id();
             // hook args
             $args = array('user_id' => $user_id, 'transaction_id' => $transaction_id);
             // another membership
             if (isset($custom['is_another_membership_purchase']) && bool_from_yn($custom['is_another_membership_purchase'])) {
                 $args['another_membership'] = $custom['membership_type'];
             }
             // after succesful payment hook
             do_action('mgm_membership_transaction_success', $args);
             // backward compatibility
             do_action('mgm_subscription_purchase_payment_success', $args);
             // new organized name
             break;
         case 'Returned':
         case 'In dispute':
             $new_status = MGM_STATUS_NULL;
             $member->status_str = __('Last payment was refunded or denied', 'mgm');
             break;
         case 'Awaiting Payment':
         case 'In analysis':
             $new_status = MGM_STATUS_PENDING;
             $reason = 'Awaiting Payment';
             $member->status_str = sprintf(__('Last payment is pending. Reason: %s', 'mgm'), $reason);
             break;
         default:
             $new_status = MGM_STATUS_ERROR;
             $member->status_str = sprintf(__('Last payment status: %s', 'mgm'), $_POST['status_code']);
             break;
     }
     // old status
     $old_status = $member->status;
     // set new status
     $member->status = $new_status;
     // whether to acknowledge the user - This should happen only once
     $acknowledge_user = $this->send_payment_email($_POST['custom']);
     // whether to subscriber the user to Autoresponder - This should happen only once
     $acknowledge_ar = mgm_subscribe_to_autoresponder($member, $_POST['custom']);
     // another_subscription modification
     if (isset($custom['is_another_membership_purchase']) && bool_from_yn($custom['is_another_membership_purchase'])) {
         //issue #1227
         if ($subs_pack['hide_old_content']) {
             $member->hide_old_content = $subs_pack['hide_old_content'];
         }
         mgm_save_another_membership_fields($member, $user_id);
         // Multiple membership upgrade: first time
         if (isset($custom['multiple_upgrade_prev_packid']) && is_numeric($custom['multiple_upgrade_prev_packid'])) {
             mgm_multiple_upgrade_save_memberobject($custom, $member->transaction_id);
         }
     } else {
         $member->save();
     }
     // status change event
     do_action('mgm_user_status_change', $user_id, $new_status, $old_status, 'module_' . $this->module, $member->pack_id);
     //update coupon usage
     do_action('mgm_update_coupon_usage', array('user_id' => $user_id));
     // role
     if ($update_role) {
         $obj_role = new mgm_roles();
         $obj_role->add_user_role($user_id, $role);
     }
     // return action
     do_action('mgm_return_' . $this->module, array('user_id' => $user_id));
     // backward compatibility
     do_action('mgm_return_subscription_payment_' . $this->module, array('user_id' => $user_id));
     // new , individual
     do_action('mgm_return_subscription_payment', array('user_id' => $user_id, 'acknowledge_ar' => $acknowledge_ar, 'mgm_member' => $member));
     // new, global: pass mgm_member object to consider multiple level purchases as well.
     // read member again for internal updates if any
     // another_subscription modification
     if (isset($custom['is_another_membership_purchase']) && bool_from_yn($custom['is_another_membership_purchase'])) {
         $member = mgm_get_member_another_purchase($user_id, $custom['membership_type']);
     } else {
         $member = mgm_get_member($user_id);
     }
     // transaction status
     mgm_update_transaction_status($member->transaction_id, $member->status, $member->status_str);
     // send email notification to client
     $blogname = get_option('blogname');
     // notify
     if ($acknowledge_user) {
         // notify user, only if gateway emails on
         if (!$dpne) {
             // notify
             if (mgm_notify_user_membership_purchase($blogname, $user, $member, $custom, $subs_pack, $s_packs, $system_obj)) {
                 // update as email sent
                 $this->update_paymentemail_sent($alt_tran_id);
             }
         }
         // notify admin, only if gateway emails on
         if (!$dge) {
             // pack duration
             $pack_duration = $s_packs->get_pack_duration($subs_pack);
             // notify admin,
             mgm_notify_admin_membership_purchase($blogname, $user, $member, $pack_duration);
         }
     }
 }
/** 
 * rebill notify on rebill status change
 * 
 * @param array $options saved in usermeta
 * @param int user_id
 * @return void	
 * @since 2.7
 */
function mgm_notify_on_rebill_status_change($user_id, $new_status, $old_status, $context)
{
    // system
    $system_obj = mgm_get_class('system');
    $dge = bool_from_yn($system_obj->get_setting('disable_gateway_emails'));
    $dpne = bool_from_yn($system_obj->get_setting('disable_payment_notify_emails'));
    // get member
    $member = mgm_get_member($user_id);
    // log
    // mgm_log($member, __FUNCTION__);
    // notify
    $notify = false;
    // @todo check by last_pay_date
    // check
    if (!($last_email_notify_date = get_user_option('_mgm_last_email_notify_date', $user_id))) {
        // check
        $notify = true;
        // log
        // mgm_log('Block1: ' . $last_email_notify_date . ' - ' . $member->last_pay_date . ' ' . $notify, __FUNCTION__);
    } else {
        // check
        if (!empty($member->last_pay_date) && $last_email_notify_date != $member->last_pay_date) {
            $notify = true;
        }
        // log
        // mgm_log('Block2: ' . $last_email_notify_date . ' - ' . $member->last_pay_date . ' ' . $notify, __FUNCTION__);
    }
    // notify user
    if ($notify) {
        // packs
        $s_packs = mgm_get_class('subscription_packs');
        // get user
        $user = get_userdata($user_id);
        // blog
        $blogname = get_option('blogname');
        // notify user
        if (!$dpne) {
            // get pack
            if ($member->pack_id) {
                $subs_pack = $s_packs->get_pack($member->pack_id);
            } else {
                $subs_pack = $s_packs->validate_pack($member->amount, $member->duration, $member->duration_type, $member->membership_type);
            }
            // custom
            $custom = mgm_get_transaction($member->transaction_id);
            // notify
            if (mgm_notify_user_membership_purchase($blogname, $user, $member, $custom, $subs_pack, $s_packs, $system_obj)) {
                // tracking
                update_user_option($user_id, '_mgm_last_email_notify_date', $member->last_pay_date, true);
                // log
                // mgm_log('mgm_last_email_notify_date updated: ' . $member->last_pay_date, __FUNCTION__);
                // update as email sent
                /*				
                				if( $module = mgm_is_valid_module($member->payment_info->module) ){
                					$module->update_paymentemail_sent( $member->transaction_id );	
                				}*/
                // check
                if ($module = $member->payment_info->module) {
                    // if a valid module
                    if ($obj_module = mgm_is_valid_module($module, 'payment', 'object')) {
                        $obj_module->update_paymentemail_sent($member->transaction_id);
                    }
                }
            }
        }
        // notify admin
        if (!$dge) {
            // pack duration
            $pack_duration = $s_packs->get_pack_duration($subs_pack);
            // notify admin,
            mgm_notify_admin_membership_purchase($blogname, $user, $member, $pack_duration);
        }
    }
}
 function _buy_membership()
 {
     // system
     $system_obj = mgm_get_class('system');
     $s_packs = mgm_get_class('subscription_packs');
     $dge = bool_from_yn($system_obj->get_setting('disable_gateway_emails'));
     $dpne = bool_from_yn($system_obj->get_setting('disable_payment_notify_emails'));
     // custom var
     $alt_tran_id = $this->_get_alternate_transaction_id();
     // get passthrough, stop further process if fails to parse
     $custom = $this->_get_transaction_passthrough($alt_tran_id);
     // local var
     extract($custom);
     // currency
     if (!$currency) {
         $currency = $system_obj->get_setting('currency');
     }
     // find user
     $user = get_userdata($user_id);
     // another_subscription modification
     if (isset($custom['is_another_membership_purchase']) && bool_from_yn($custom['is_another_membership_purchase'])) {
         $member = mgm_get_member_another_purchase($user_id, $custom['membership_type']);
     } else {
         $member = mgm_get_member($user_id);
     }
     // Get the current AC join date
     if (!($join_date = $member->join_date)) {
         $member->join_date = time();
     }
     // Set current AC join date\
     // if there is no duration set in the user object then run the following code
     if (empty($duration_type)) {
         // if there is no duration type then use Months
         $duration_type = 'm';
     }
     // membership type default
     if (empty($membership_type)) {
         // if there is no account type in the custom string then use the existing type
         $membership_type = md5($member->membership_type);
     }
     // validate parent method
     $membership_type_verified = $this->_validate_membership_type($membership_type, 'md5|plain');
     // verified
     if (!$membership_type_verified) {
         if (strtolower($member->membership_type) != 'free') {
             // notify admin, only if gateway emails on
             if (!$dge) {
                 mgm_notify_admin_membership_verification_failed($this->name);
             }
             // abort
             return;
         } else {
             $membership_type_verified = $member->membership_type;
         }
     }
     // set
     $membership_type = $membership_type_verified;
     // sub pack
     $subs_pack = $s_packs->get_pack($pack_id);
     // exit flag
     $exitif_subscr_signup = true;
     // if trial on
     if (isset($custom['trial_on']) && $custom['trial_on'] == 1) {
         $member->trial_on = $custom['trial_on'];
         $member->trial_cost = $custom['trial_cost'];
         $member->trial_duration = $custom['trial_duration'];
         $member->trial_duration_type = $custom['trial_duration_type'];
         $member->trial_num_cycles = $custom['trial_num_cycles'];
         // 0 cost trial does not send payment_status, make check here
         // this should be causing trouble for MGA #969, mis firing payment success for failed payment, add support
         if ($member->trial_cost == 0 && !isset($_POST['payment_status'])) {
             // when subscr_id present, treat it as Processed , #287 issue, with trial cost is 0, only subscr_signup is sent without payment_status
             // with trial cost > 0, subscr_signup and subscr_payment sent with payment_status
             if (isset($_POST['subscr_id'])) {
                 $_POST['payment_status'] = 'Processed';
                 $exitif_subscr_signup = false;
             }
         }
     } elseif ($subs_pack['trial_on']) {
         $member->trial_on = $subs_pack['trial_on'];
         $member->trial_cost = $subs_pack['trial_cost'];
         $member->trial_duration = $subs_pack['trial_duration'];
         $member->trial_duration_type = $subs_pack['trial_duration_type'];
         $member->trial_num_cycles = $subs_pack['trial_num_cycles'];
         // 0 cost trial does not send payment_status, make check here
         // this should be causing trouble for MGA #969, mis firing payment success for failed payment, add support
         if ($member->trial_cost == 0 && !isset($_POST['payment_status'])) {
             // when subscr_id present, treat it as Processed , #287 issue, with trial cost is 0, only subscr_signup is sent without payment_status
             // with trial cost > 0, subscr_signup and subscr_payment sent with payment_status
             if (isset($_POST['subscr_id'])) {
                 $_POST['payment_status'] = 'Processed';
                 $exitif_subscr_signup = false;
             }
         }
     }
     // exit scenarios
     if (!isset($_POST['payment_status']) || $exitif_subscr_signup && isset($_POST['txn_type']) && $_POST['txn_type'] == 'subscr_signup') {
         exit;
     }
     // double check txn type for MGA#969, subscr_failed triggers successful payment for trial packs
     if (isset($_POST['txn_type']) && $_POST['txn_type'] == 'subscr_failed') {
         exit;
     }
     //pack currency over rides genral setting currency - issue #1602
     if (isset($subs_pack['currency']) && $subs_pack['currency'] != $currency) {
         $currency = $subs_pack['currency'];
     }
     // member fields
     $member->duration = $duration;
     $member->duration_type = strtolower($duration_type);
     $member->amount = $amount;
     $member->currency = $currency;
     $member->membership_type = $membership_type;
     $member->pack_id = $pack_id;
     $member->active_num_cycles = isset($num_cycles) && !empty($num_cycles) ? $num_cycles : $subs_pack['num_cycles'];
     $member->payment_type = (int) $member->active_num_cycles == 1 ? 'one-time' : 'subscription';
     //one time pack subscription id option become an issue #1507
     if (isset($subs_pack['num_cycles']) == 1 && !isset($_POST['subscr_id'])) {
         $_POST['subscr_id'] = 'ONE-TIME SUBSCRIPTION';
     }
     // tracking fields module_field => post_field, will be used to unsubscribe
     $tracking_fields = array('txn_type' => 'txn_type', 'subscr_id' => 'subscr_id', 'txn_id' => 'txn_id');
     // save tracking fields
     $this->_save_tracking_fields($tracking_fields, $member);
     // check here: ->module is absent in payment_info, its is _save_tracking_fields
     // if (!isset($member->payment_info->module)) $member->payment_info->module = $this->code;
     // set parent transaction id
     $member->transaction_id = $alt_tran_id;
     // process PayPal response
     $new_status = $update_role = false;
     // status
     switch ($_POST['payment_status']) {
         case 'Completed':
         case 'Processed':
             // status
             $new_status = MGM_STATUS_ACTIVE;
             $member->status_str = __('Last payment was successful', 'mgm');
             // old type match
             $old_membership_type = mgm_get_user_membership_type($user_id, 'code');
             // set
             if ($old_membership_type != $membership_type) {
                 $member->join_date = time();
                 // type join date as different var
             }
             // old content hide
             $member->hide_old_content = $hide_old_content;
             $time = time();
             $last_pay_date = isset($member->last_pay_date) ? $member->last_pay_date : null;
             // last pay
             $member->last_pay_date = date('Y-m-d', $time);
             // as per version 1.0, there was chance of double process, with new separation logic for rebill, this is safe
             // check subscription_option
             if (isset($subscription_option)) {
                 // on option
                 switch ($subscription_option) {
                     // @ToDo, apply expire date login
                     case 'create':
                         // expire date will be based on current time
                     // expire date will be based on current time
                     case 'upgrade':
                         // expire date will be based on current time
                         // already on top
                         break;
                     case 'downgrade':
                         // expire date will be based on expire_date if exists, current time other wise
                     // expire date will be based on expire_date if exists, current time other wise
                     case 'extend':
                         // expire date will be based on expire_date if exists, current time other wise
                         // extend/expire date
                         // calc expiry	- issue #1226
                         // membership extend functionality broken if we try to extend the same day so removed && $last_pay_date != date('Y-m-d', $time) check
                         if (!empty($member->expire_date)) {
                             $expiry = strtotime($member->expire_date);
                             if ($expiry > 0 && $expiry > $time) {
                                 $time = $expiry;
                             }
                         }
                         break;
                 }
             }
             // type expanded
             $duration_exprs = $s_packs->get_duration_exprs();
             // if not lifetime/date range
             if (in_array($member->duration_type, array_keys($duration_exprs))) {
                 // take only date exprs
                 // consider trial duration if trial period is applicable
                 if (isset($trial_on) && $trial_on == 1 && (!isset($member->trial_used) || (int) $member->trial_used < (int) $member->trial_num_cycles)) {
                     // is it the root of #1150 issue
                     // Do it only once
                     if (!isset($member->rebilled) && isset($member->active_num_cycles) && $member->active_num_cycles != 1) {
                         // set
                         $time = strtotime("+{$trial_duration} {$duration_exprs[$trial_duration_type]}", $time);
                         // increment trial used, each IPN should increement this and extend
                         $member->trial_used = !$member->trial_used ? 1 : (int) $member->trial_used + 1;
                     }
                 } else {
                     // time - issue #1068
                     $time = strtotime("+{$member->duration} {$duration_exprs[$member->duration_type]}", $time);
                 }
                 // formatted
                 $time_str = date('Y-m-d', $time);
                 // date extended
                 if (!$member->expire_date || strtotime($time_str) > strtotime($member->expire_date)) {
                     $member->expire_date = $time_str;
                 }
             } else {
                 //if lifetime:
                 if ($member->duration_type == 'l') {
                     // el = lifetime
                     $member->expire_date = '';
                 }
                 //issue #1096
                 if ($member->duration_type == 'dr') {
                     // el = /date range
                     $member->expire_date = $duration_range_end_dt;
                 }
             }
             // update rebill: issue #: 489
             if ($member->active_num_cycles != 1 && (int) $member->rebilled < (int) $member->active_num_cycles) {
                 // rebill
                 $member->rebilled = !$member->rebilled ? 1 : (int) $member->rebilled + 1;
             }
             // cancel previous subscription:
             // issue#: 565
             $this->cancel_recurring_subscription($alt_tran_id, null, null, $pack_id);
             // role update
             if ($role) {
                 $update_role = true;
             }
             // transaction_id
             $transaction_id = $this->_get_transaction_id();
             // hook args
             $args = array('user_id' => $user_id, 'transaction_id' => $transaction_id);
             // another membership
             if (isset($custom['is_another_membership_purchase']) && bool_from_yn($custom['is_another_membership_purchase'])) {
                 $args['another_membership'] = $custom['membership_type'];
             }
             // after succesful payment hook
             do_action('mgm_membership_transaction_success', $args);
             // backward compatibility
             do_action('mgm_subscription_purchase_payment_success', $args);
             // new organized name
             break;
         case 'Reversed':
         case 'Refunded':
         case 'Denied':
             // status
             $new_status = MGM_STATUS_NULL;
             $member->status_str = __('Last payment was refunded or denied', 'mgm');
             break;
         case 'Pending':
             // status
             $new_status = MGM_STATUS_PENDING;
             $reason = 'Unknown';
             $member->status_str = sprintf(__('Last payment is pending. Reason: %s', 'mgm'), $reason);
             break;
         default:
             // status
             $new_status = MGM_STATUS_ERROR;
             $member->status_str = sprintf(__('Last payment status: %s', 'mgm'), $_POST['payment_status']);
             break;
     }
     // handle exceptions from the subscription specific fields
     if ($new_status == MGM_STATUS_ACTIVE && in_array($_POST['txn_type'], array('subscr_failed', 'subscr_eot'))) {
         $new_status = MGM_STATUS_NULL;
         $member->status_str = __('The subscription is not active', 'mgm');
     }
     // old status
     $old_status = $member->status;
     // set new status
     $member->status = $new_status;
     // whether to acknowledge the user - This should happen only once
     $acknowledge_user = $this->send_payment_email($alt_tran_id);
     // whether to subscriber the user to Autoresponder - This should happen only once
     $acknowledge_ar = mgm_subscribe_to_autoresponder($member, $_POST['custom']);
     // another_subscription modification
     if (isset($custom['is_another_membership_purchase']) && bool_from_yn($custom['is_another_membership_purchase'])) {
         //issue #1227
         if ($subs_pack['hide_old_content']) {
             $member->hide_old_content = $subs_pack['hide_old_content'];
         }
         // save
         mgm_save_another_membership_fields($member, $user_id);
         // Multiple membership upgrade: first time
         if (isset($custom['multiple_upgrade_prev_packid']) && is_numeric($custom['multiple_upgrade_prev_packid'])) {
             mgm_multiple_upgrade_save_memberobject($custom, $member->transaction_id);
         }
     } else {
         // save
         $member->save();
     }
     // status change event
     do_action('mgm_user_status_change', $user_id, $new_status, $old_status, 'module_' . $this->module, $member->pack_id);
     //update coupon usage
     do_action('mgm_update_coupon_usage', array('user_id' => $user_id));
     // role update
     if ($update_role) {
         $obj_role = new mgm_roles();
         $obj_role->add_user_role($user_id, $role);
     }
     // return action
     do_action('mgm_return_' . $this->module, array('user_id' => $user_id, 'acknowledge_user' => $acknowledge_user));
     // backward compatibility
     do_action('mgm_return_subscription_payment_' . $this->module, array('user_id' => $user_id));
     // new , individual
     do_action('mgm_return_subscription_payment', array('user_id' => $user_id, 'acknowledge_ar' => $acknowledge_ar, 'mgm_member' => $member));
     // new, global: pass mgm_member object to consider multiple level purchases as well.
     // read member again for internal updates if any
     // another_subscription modification
     if (isset($custom['is_another_membership_purchase']) && bool_from_yn($custom['is_another_membership_purchase'])) {
         $member = mgm_get_member_another_purchase($user_id, $custom['membership_type']);
     } else {
         $member = mgm_get_member($user_id);
     }
     // transaction status
     mgm_update_transaction_status($member->transaction_id, $member->status, $member->status_str);
     // send email notification to client
     $blogname = get_option('blogname');
     // for paypal only
     if (in_array($_POST['txn_type'], array('subscr_payment', 'subscr_signup', 'web_accept')) && in_array($_POST['payment_status'], array('Processed', 'Completed'))) {
         $acknowledge_user = true;
     } else {
         $acknowledge_user = false;
     }
     // notify
     if ($acknowledge_user) {
         // notify user, only if gateway emails on
         if (!$dpne) {
             // notify
             if (mgm_notify_user_membership_purchase($blogname, $user, $member, $custom, $subs_pack, $s_packs, $system_obj)) {
                 // update as email sent
                 $this->update_paymentemail_sent($alt_tran_id);
             }
         }
         // notify admin, only if gateway emails on
         if (!$dge) {
             // pack duration
             $pack_duration = $s_packs->get_pack_duration($subs_pack);
             // notify admin,
             mgm_notify_admin_membership_purchase($blogname, $user, $member, $pack_duration);
         }
     }
 }