Esempio n. 1
0
 /**
  * Subscribe
  *
  * This is the heart of the Membrr engine, an essentially a wrapper for OpenGateway's Recur API Call.
  *
  * @param int $plan_id
  * @param int $member_id
  * @param array $credit_card
  * @param array $customer
  * @param string/boolean $end_date
  * @param float/boolean $first_charge
  * @param float/boolean $recurring_charge
  * @param string/boolean $cancel_url
  * @param string/boolean $return_url
  * @param int/boolean $gateway_id
  * @param int/boolean $renew_subscription
  * @param string $coupon
  *
  * @return array Response from OpenGateway
  */
 function Subscribe($plan_id, $member_id, $credit_card, $customer, $end_date = FALSE, $first_charge = FALSE, $recurring_charge = FALSE, $cancel_url = '', $return_url = '', $gateway_id = FALSE, $renew_subscription = FALSE, $coupon = FALSE)
 {
     $plan = $this->GetPlan($plan_id);
     // calculate initial charge
     if ($plan['initial_charge'] != $plan['price'] and $first_charge === FALSE) {
         $first_charge = $plan['initial_charge'];
     }
     $config = $this->GetConfig();
     if (!class_exists('Opengateway')) {
         require dirname(__FILE__) . '/opengateway.php';
     }
     $connect_url = $config['api_url'] . '/api';
     $recur = new Recur();
     $recur->Authenticate($config['api_id'], $config['secret_key'], $connect_url);
     // use existing customer_id if we can
     $opengateway = new OpenGateway();
     $opengateway->Authenticate($config['api_id'], $config['secret_key'], $connect_url);
     $opengateway->SetMethod('GetCustomers');
     $opengateway->Param('internal_id', $member_id);
     $response = $opengateway->Process();
     if ($response['total_results'] > 0) {
         // there is already a customer record here
         $customer = !isset($response['customers']['customer'][0]) ? $response['customers']['customer'] : $response['customers']['customer'][0];
         $recur->UseCustomer($customer['id']);
     } else {
         // no customer records, yet
         $recur->Param('internal_id', $member_id, 'customer');
         // let's try to auto-generate a name based if there isn't one there
         if (empty($customer['first_name']) and empty($customer['last_name'])) {
             // do we have a credit card name to generate from?
             if (isset($credit_card['name']) and !empty($credit_card['name'])) {
                 $names = explode(' ', $credit_card['name']);
                 $customer['first_name'] = $names[0];
                 $customer['last_name'] = end($names);
             }
         }
         $recur->Customer($customer['first_name'], $customer['last_name'], $customer['company'], $customer['address'], $customer['address_2'], $customer['city'], $customer['region'], $customer['country'], $customer['postal_code'], $customer['phone'], $customer['email']);
     }
     // coupon?
     if ($coupon != FALSE) {
         // may be using PayPal, so we should store this
         $this->EE->functions->set_cookie('membrr_coupon', $coupon, 86400);
         $recur->Coupon($coupon);
     }
     // end date?
     if ($end_date != FALSE) {
         $recur->Param('end_date', $end_date, 'recur');
     }
     // if different first charge?
     if ($first_charge !== FALSE) {
         $recur->Amount($first_charge);
     } else {
         $recur->Amount($plan['price']);
     }
     // if different recurring rate?
     if ($recurring_charge != FALSE) {
         $recur->Param('amount', $recurring_charge, 'recur');
     }
     // are we renewing an existing subscription?
     if (!empty($renew_subscription)) {
         // is sub active?
         $old_sub = $this->GetSubscription($renew_subscription);
         if ($old_sub['active'] == '1') {
             $recur->Param('renew', $renew_subscription);
             if ($plan['renewal_extend_from_end'] === TRUE) {
                 // we will delay the start of the new subscription until the end of this one
                 $old_sub = $this->GetSubscription($renew_subscription);
                 // calculate real end date
                 $old_end_date = $this->_calculate_end_date($old_sub['end_date'], $old_sub['next_charge_date'], $old_sub['date_created']);
                 // convert to timestamp for calcs
                 $old_end_date = strtotime($old_end_date);
                 // postpone the start date of this new subscription from that end_date
                 $difference_in_days = ($old_end_date - time()) / (60 * 60 * 24);
                 $recur->Param('start_date', date('Y-m-d', $old_end_date), 'recur');
                 $plan['free_trial'] = $difference_in_days;
             } else {
                 // this plan will cancel immediately
                 // let's make CancelSubscription do this
                 $this->EE->db->update('exp_membrr_subscriptions', array('next_charge_date' => '0000-00-00', 'end_date' => date('Y-m-d H:i:s')), array('recurring_id' => $old_sub['id']));
             }
         }
     }
     $recur->UsePlan($plan['api_id']);
     $security = empty($credit_card['security_code']) ? FALSE : $credit_card['security_code'];
     if ($credit_card and !empty($credit_card) and isset($credit_card['number']) and !empty($credit_card['number'])) {
         $recur->CreditCard($credit_card['name'], $credit_card['number'], $credit_card['expiry_month'], $credit_card['expiry_year'], $security);
     }
     // specify the gateway?
     // from arguments first:
     if (!empty($gateway_id)) {
         $recur->Param('gateway_id', $gateway_id);
     } elseif (!empty($plan['gateway'])) {
         $recur->Param('gateway_id', $plan['gateway']);
     } elseif (!empty($config['gateway'])) {
         $recur->Param('gateway_id', $config['gateway']);
     }
     // add IP address to request
     // get true IP
     if (!empty($_SERVER['HTTP_CLIENT_IP'])) {
         $current_ip = $_SERVER['HTTP_CLIENT_IP'];
     } elseif (!empty($_SERVER['HTTP_X_FORWARDED_FOR'])) {
         $current_ip = $_SERVER['HTTP_X_FORWARDED_FOR'];
     } else {
         $current_ip = $_SERVER['REMOTE_ADDR'];
     }
     $recur->Param('customer_ip_address', $current_ip);
     // if they are using PayPal, we need the following parameters
     if (empty($return_url)) {
         $this->EE->db->select('action_id');
         $this->EE->db->where('class', 'Membrr');
         $this->EE->db->where('method', 'post_notify');
         $result = $this->EE->db->get('exp_actions');
         $action_id = $result->row_array();
         $action_id = $action_id['action_id'];
         $return_url = $this->EE->functions->create_url('?ACT=' . $action_id . '&member=' . $member_id . '&plan_id=' . $plan_id, 0);
         // if we are renewing, we will append this to the $return_url so that we can cancel old subscriptions
         // and update channel entries to the new recurring_id for external gateways like PayPal EC
         if (!empty($renew_subscription)) {
             $return_url .= '&renew_recurring_id=' . $renew_subscription;
         }
         // sometimes, with query strings, we get index.php?/?ACT=26...
         $return_url = str_replace('?/?', '?', $return_url);
     }
     $recur->Param('return_url', htmlspecialchars($return_url));
     if (empty($cancel_url)) {
         $cancel_url = $this->EE->functions->fetch_current_uri();
     }
     $recur->Param('cancel_url', htmlspecialchars($cancel_url));
     // call "membrr_pre_subscribe" hook with: $recur, $member_id, $plan_id, $recurring_charge, $first_charge, $end_date
     if ($this->EE->extensions->active_hook('membrr_pre_subscribe') == TRUE) {
         $this->EE->extensions->call('membrr_pre_subscribe', $recur, $member_id, $plan_id, $recurring_charge, $first_charge, $end_date);
         if ($this->EE->extensions->end_script === TRUE) {
             return FALSE;
         }
     }
     $response = $recur->Charge();
     if (isset($response['response_code']) and $response['response_code'] == '100') {
         // success!
         // calculate payment amount
         $recur_payment = $response['recur_amount'];
         $payment = $response['amount'];
         $free_trial = $response['free_trial'];
         $start_date = $response['start_date'];
         // calculate end date
         if ($end_date != FALSE) {
             // we must also account for their signup time
             $time_created = date('H:i:s');
             $end_date = date('Y-m-d', strtotime($end_date)) . ' ' . $time_created;
         } elseif ($end_date == FALSE) {
             if ($plan['occurrences'] == '0') {
                 // unlimited occurrences
                 $end_date = '0000-00-00 00:00:00';
             } else {
                 $time_to_calculate_end = time();
                 if (!empty($renew_subscription)) {
                     $subscription = $this->GetSubscription($renew_subscription);
                     $old_end_date = $this->_calculate_end_date($subscription['end_date'], $subscription['next_charge_date'], $subscription['date_created']);
                     $time_to_calculate_end = strtotime($old_end_date);
                     // we don't want to take on the end dates from previously expired subscriptions
                     if ($time_to_calculate_end < time()) {
                         $time_to_calculate_end = time();
                     }
                 }
                 $end_date = date('Y-m-d H:i:s', $time_to_calculate_end + $free_trial * 86400 + $plan['occurrences'] * $plan['interval'] * 86400);
             }
         }
         // calculate next charge date
         if (!empty($free_trial)) {
             $next_charge_date = time() + $free_trial * 86400;
         } elseif (!empty($start_date) and strtotime($start_date) > time() + 84600) {
             $next_charge_date = strtotime($start_date);
         } else {
             if ($this->same_day_every_month == TRUE and $plan['interval'] % 30 === 0) {
                 $months = $plan['interval'] / 30;
                 $plural = $months > 1 ? 's' : '';
                 $next_charge_date = strtotime('today + ' . $months . ' month' . $plural);
             } else {
                 $next_charge_date = strtotime('today + ' . $plan['interval'] . ' days');
             }
         }
         if ((date('Y-m-d', $next_charge_date) == date('Y-m-d', strtotime($end_date)) or $next_charge_date > strtotime($end_date)) and $end_date != '0000-00-00 00:00:00') {
             $next_charge_date = '0000-00-00';
         } else {
             $next_charge_date = date('Y-m-d', $next_charge_date);
         }
         $this->RecordSubscription($response['recurring_id'], $member_id, $plan_id, $next_charge_date, $end_date, $recur_payment, $coupon, $credit_card);
         if (empty($free_trial) and isset($response['charge_id'])) {
             // create payment record
             $this->RecordPayment($response['recurring_id'], $response['charge_id'], $payment);
         }
         // perform renewing subscription maintenance
         if (!empty($renew_subscription)) {
             $this->RenewalMaintenance($renew_subscription, $response['recurring_id']);
         }
     }
     return $response;
 }
Esempio n. 2
0
 /**
  * Post Charge
  */
 function post()
 {
     $this->load->library('opengateway');
     if ($this->input->post('recurring') == '0') {
         $charge = new Charge();
     } else {
         $charge = new Recur();
     }
     $api_url = site_url('api');
     $api_url = $this->config->item('ssl_active') == TRUE ? str_replace('http://', 'https://', $api_url) : $api_url;
     $charge->Authenticate($this->user->Get('api_id'), $this->user->Get('secret_key'), site_url('api'));
     $charge->Amount($this->input->post('amount'));
     // coupon
     if ($this->input->post('coupon')) {
         $charge->Coupon($this->input->post('coupon'));
     }
     if ($this->input->post('cc_number')) {
         $charge->CreditCard($this->input->post('cc_name'), $this->input->post('cc_number'), $this->input->post('cc_expiry_month'), $this->input->post('cc_expiry_year'), $this->input->post('cc_security'));
     }
     if ($this->input->post('recurring') == '1') {
         $charge->UsePlan($this->input->post('recurring_plan'));
     } elseif ($this->input->post('recurring') == '2') {
         $free_trial = $this->input->post('free_trial');
         $free_trial = empty($free_trial) ? FALSE : $free_trial;
         $occurrences = $this->input->post('recurring_end') == 'occurrences' ? $this->input->post('occurrences') : FALSE;
         $start_date = $this->input->post('start_date_year') . '-' . $this->input->post('start_date_month') . '-' . $this->input->post('start_date_day');
         $end_date = $this->input->post('end_date_year') . '-' . $this->input->post('end_date_month') . '-' . $this->input->post('end_date_day');
         $end_date = $this->input->post('recurring_end') == 'date' ? $end_date : FALSE;
         $charge->Schedule($this->input->post('interval'), $free_trial, $occurrences, $start_date, $end_date);
     }
     if ($this->input->post('customer_id') != '') {
         $charge->UseCustomer($this->input->post('customer_id'));
     } else {
         $first_name = $this->input->post('first_name') == 'First Name' ? '' : $this->input->post('first_name');
         $last_name = $this->input->post('last_name') == 'Last Name' ? '' : $this->input->post('last_name');
         $email = $this->input->post('email') == '*****@*****.**' ? '' : $this->input->post('email');
         $state = ($this->input->post('country') == 'US' or $this->input->post('country') == 'CA') ? $this->input->post('state_select') : $this->input->post('state');
         if (!empty($first_name) and !empty($last_name)) {
             $charge->Customer($first_name, $last_name, $this->input->post('company'), $this->input->post('address_1'), $this->input->post('address_2'), $this->input->post('city'), $state, $this->input->post('country'), $this->input->post('postal_code'), $this->input->post('phone'), $email);
         }
     }
     if ($this->input->post('gateway_type') == 'specify') {
         $charge->UseGateway($this->input->post('gateway'));
     }
     // set return URL
     if ($this->input->post('recurring') == '0') {
         $charge->Param('return_url', site_url('transactions/latest_charge'));
     } else {
         $charge->Param('return_url', site_url('transactions/latest_recur'));
     }
     $charge->Param('cancel_url', site_url('transactions/create'));
     $response = $charge->Charge();
     if (!is_array($response) or isset($response['error'])) {
         $this->notices->SetError($this->lang->line('transaction_error') . $response['error_text'] . ' (#' . $response['error'] . ')');
     } elseif (isset($response['response_code']) and $response['response_code'] == '2') {
         $this->notices->SetError($this->lang->line('transaction_error') . $response['response_text'] . '. ' . $response['reason'] . ' (#' . $response['response_code'] . ')');
     } else {
         $this->notices->SetNotice($this->lang->line('transaction_ok'));
     }
     if (isset($response['recurring_id'])) {
         $redirect = site_url('transactions/recurring/' . $response['recurring_id']);
     } elseif (isset($response['charge_id'])) {
         $redirect = site_url('transactions/charge/' . $response['charge_id']);
     } else {
         $redirect = site_url('transactions/create');
     }
     redirect($redirect);
     return TRUE;
 }