Exemplo n.º 1
0
 function Callback_confirm_recur($client_id, $gateway, $subscription, $params)
 {
     $CI =& get_instance();
     // retrieve charge data
     $CI->load->model('charge_data_model');
     $data = $CI->charge_data_model->Get('r' . $subscription['id']);
     // this gets complex below, so we'll track the general success of this process
     // with a simple boolean variable
     $process_status = FALSE;
     $url = $this->GetAPIUrl($gateway);
     // regardless of it's a single or recurring charge at PayPal, we need to retrieve the token
     $post = array();
     $post['method'] = 'GetExpressCheckoutDetails';
     $post['token'] = $params['token'];
     $post['version'] = '95.0';
     $post['user'] = $gateway['user'];
     $post['pwd'] = $gateway['pwd'];
     $post['signature'] = $gateway['signature'];
     $response = $this->Process($url, $post);
     if ($this->debug) {
         $this->log_it('PayPal Express Callback Confirm Recur Params: ', $post);
         $this->log_it('PayPal Express Charge Callback Confirm Response: ', $response);
     }
     if (isset($response['TOKEN']) and $response['TOKEN'] == $params['token']) {
         // tokens match.  this is a legitimate PayPal request
         // do we need a first charge?
         if (date('Y-m-d', strtotime($subscription['start_date'])) == date('Y-m-d', strtotime($subscription['date_created']))) {
             $CI->load->model('charge_model');
             // get the first charge amount (it may be different)
             $first_charge_amount = isset($data['first_charge']) ? $data['first_charge'] : $subscription['amount'];
             $first_charge_amount = (double) $first_charge_amount;
             if (!empty($first_charge_amount)) {
                 $customer_id = isset($subscription['customer']['id']) ? $subscription['customer']['id'] : FALSE;
                 $order_id = $CI->charge_model->CreateNewOrder($client_id, $gateway['gateway_id'], $first_charge_amount, array(), $subscription['id'], $customer_id);
                 // yes, the first charge is today
                 $post = $response;
                 // most of the data is from here
                 unset($post['NOTE']);
                 $post['METHOD'] = 'DoExpressCheckoutPayment';
                 $post['TOKEN'] = $response['TOKEN'];
                 $post['PAYMENTACTION'] = 'Sale';
                 $post['version'] = '95.0';
                 $post['user'] = $gateway['user'];
                 $post['pwd'] = $gateway['pwd'];
                 $post['signature'] = $gateway['signature'];
                 $response_charge = $this->Process($url, $post);
                 if ($this->debug) {
                     $this->log_it('PayPal Express Callback Confirm Recur - First Charge Params: ', $post);
                     $this->log_it('PayPal Express Callback Confirm Recur - First Charge Response: ', $response_charge);
                 }
                 if (!isset($response_charge) or $response_charge['PAYMENTINFO_0_PAYMENTSTATUS'] != 'Completed' and $response_charge['PAYMENTINFO_0_PAYMENTSTATUS'] != 'Pending' and $response_charge['PAYMENTINFO_0_PAYMENTSTATUS'] != 'Processed') {
                     die('Your initial PayPal payment failed.  <a href="' . $data['cancel_url'] . '">Go back to merchant</a>.');
                 } else {
                     // create today's order
                     // we assume it's good because the profile is OK
                     $CI->load->model('order_authorization_model');
                     // we may not have the transaction ID if it's Pending
                     $response_charge['PAYMENTINFO_0_TRANSACTIONID'] = isset($response_charge['PAYMENTINFO_0_TRANSACTIONID']) ? $response_charge['PAYMENTINFO_0_TRANSACTIONID'] : 'pending_payment';
                     $CI->order_authorization_model->SaveAuthorization($order_id, $response_charge['PAYMENTINFO_0_TRANSACTIONID']);
                     $CI->charge_model->SetStatus($order_id, 1);
                 }
                 // we'll also adjust the profile start date
                 $adjusted_start_date = TRUE;
                 $subscription['start_date'] = date('Y-m-d', strtotime($subscription['start_date']) + 60 * 60 * 24 * $subscription['interval']);
             }
         }
         // if this was sent to PayPal as a recurring payment, we'll create the profile here
         if ($data['paypal_charge_type'] == 'subscription') {
             // continue with creating payment profile
             $post = $response;
             // most of the data is from here
             unset($post['NOTE']);
             // If we're keeping charges on the same day every month,
             // we need to calculate the proper interval, but only
             // if the interval is evenly divided by 30
             if ($this->same_day_every_month === true && $subscription['interval'] % 30 === 0) {
                 $interval = $subscription['interval'] / 30;
             } else {
                 $interval = $subscription['interval'];
             }
             $post['METHOD'] = 'CreateRecurringPaymentsProfile';
             $post['VERSION'] = '95.0';
             $post['user'] = $gateway['user'];
             $post['pwd'] = $gateway['pwd'];
             $post['signature'] = $gateway['signature'];
             $post['TOKEN'] = $response['TOKEN'];
             $post['DESC'] = $data['profile_description'];
             $post['PROFILESTARTDATE'] = date('c', strtotime($subscription['start_date']));
             $post['BILLINGPERIOD'] = $this->same_day_every_month === true ? 'Month' : 'Day';
             $post['BILLINGFREQUENCY'] = $interval;
             $post['AMT'] = $subscription['amount'];
             $response_sub = $this->Process($url, $post);
             if ($this->debug) {
                 $this->log_it('PayPal Express Create Payment Profile Params: ', $post);
                 $this->log_it('PayPal Express Create Payment Profile Response: ', $response_sub);
             }
             if (isset($response_sub['PROFILEID'])) {
                 // success!
                 $CI->recurring_model->SaveApiCustomerReference($subscription['id'], $response_sub['PROFILEID']);
                 $process_status = TRUE;
             }
         } else {
             // we know we are good because the first charge was executed before and, if it failed
             // we'd have die()'d above
             $process_status = TRUE;
         }
         if ($process_status === TRUE) {
             // success!
             $order_id = isset($order_id) ? $order_id : FALSE;
             $CI->recurring_model->SetActive($client_id, $subscription['id']);
             // Update the end_date if necessary due to same_day_every_month
             if ($this->same_day_every_month == true && $subscription['interval'] % 30 === 0) {
                 $end_date = strtotime('+' . $subscription['number_occurrences'] . ' month');
                 $CI->db->where('subscription_id', $subscription['id']);
                 $CI->db->update('subscriptions', array('end_date' => date('Y-m-d', $end_date)));
             }
             // trip it - were golden!
             TriggerTrip('new_recurring', $client_id, $order_id, $subscription['id']);
             // trip a recurring charge?
             if ($order_id) {
                 TriggerTrip('recurring_charge', $client_id, $order_id, $subscription['id']);
             }
             if (!empty($coupon_id)) {
                 // track coupon
                 $CI->load->model('coupon_model');
                 $CI->coupon_model->add_usage($coupon_id, $subscription_id, $order_id, $customer_id);
             }
             // redirect back to user's site
             header('Location: ' . $data['return_url']);
             die;
         } else {
             die('Error completing payment (subscription profile error).');
         }
     }
 }
Exemplo n.º 2
0
 function SubscriptionMaintenance($key)
 {
     if ($this->config->item('cron_key') != $key) {
         echo 'Invalid key.';
         if ($this->debug) {
             $this->log_it('Invalid Key for SubscriptionMaintenance cronjob: ' . $key);
         }
         return FALSE;
     }
     if ($this->debug) {
         $this->log_it('Starting SubscriptionMaintenance Cron');
     }
     $this->load->model('recurring_model');
     $this->load->model('gateway_model');
     $this->load->library('email');
     // Run PayPal fixes
     if ($this->run_paypal_fix()) {
         $this->load->library('paypal_fix');
         $this->paypal_fix->run_fix();
         $this->db->update('version', array('paypal_fix_ran' => date('Y-m-d H:i:s')));
     }
     // Expire subscription if the end date is today or before
     $cancelled = array();
     $subscriptions = $this->recurring_model->GetAllSubscriptionsForExpiring();
     if ($subscriptions) {
         foreach ($subscriptions as $subscription) {
             // cancel the subscription
             $response = $this->recurring_model->CancelRecurring($subscription['client_id'], $subscription['subscription_id'], TRUE);
             if ($response) {
                 $trip_trigger = TRUE;
                 if (!empty($subscription['renewed'])) {
                     // let's verify this subscription is active
                     $renewing_sub = $this->recurring_model->GetSubscriptionDetails($subscription['client_id'], $subscription['renewed']);
                     if ($renewing_sub['active'] == '1') {
                         $trip_trigger = FALSE;
                     }
                 }
                 if ($trip_trigger == TRUE) {
                     // not being renewed, send expiration notice
                     TriggerTrip('recurring_expire', $subscription['client_id'], FALSE, $subscription['subscription_id']);
                 }
                 $cancelled[] = $subscription['subscription_id'];
             }
         }
     }
     // get all the subscriptions with a next_charge date of today for the next charge
     $today = date('Y-m-d');
     $subscriptions = $this->recurring_model->GetAllSubscriptionsForCharging($today);
     $charge_success = array();
     $charge_failure = array();
     if ($subscriptions) {
         foreach ($subscriptions as $subscription) {
             // Try and make the charge
             $response = $this->gateway_model->ChargeRecurring($subscription['client_id'], $subscription);
             if ($response) {
                 $charge_success[] = $subscription['subscription_id'];
             } else {
                 $charge_failure[] = $subscription['subscription_id'];
             }
         }
     }
     // Check for emails to send
     // Get all the recurring charge emails to send in one week
     $sent_emails['recurring_autorecur_in_week'] = array();
     $next_week = mktime(0, 0, 0, date('m'), date('d') + 7, date('Y'));
     $charges = $this->recurring_model->GetChargesByDate($next_week);
     if ($charges) {
         foreach ($charges as $charge) {
             if (TriggerTrip('recurring_autorecur_in_week', $charge['client_id'], false, $charge['subscription_id'])) {
                 $sent_emails['recurring_autorecur_in_week'][] = $charge['subscription_id'];
             }
         }
     }
     // Get all the recurring charge emails to send in one month
     $sent_emails['recurring_autorecur_in_month'] = array();
     $next_month = mktime(0, 0, 0, date('m') + 1, date('d'), date('Y'));
     $charges = $this->recurring_model->GetChargesByDate($next_month);
     if ($charges) {
         foreach ($charges as $charge) {
             if (TriggerTrip('recurring_autorecur_in_month', $charge['client_id'], false, $charge['subscription_id'])) {
                 $sent_emails['recurring_autorecur_in_month'][] = $charge['subscription_id'];
             }
         }
     }
     // Get all the recurring expiration emails to send in one week
     $sent_emails['recurring_expiring_in_week'] = array();
     $charges = $this->recurring_model->GetChargesByExpiryDate($next_week);
     if ($charges) {
         foreach ($charges as $charge) {
             $trip_trigger = TRUE;
             if (!empty($charge['renewed'])) {
                 // let's verify this subscription is active
                 $renewing_sub = $this->recurring_model->GetSubscriptionDetails($charge['client_id'], $charge['renewed']);
                 if ($renewing_sub['active'] == '1') {
                     $trip_trigger = FALSE;
                 }
             }
             if ($trip_trigger == TRUE) {
                 if (TriggerTrip('recurring_expiring_in_week', $charge['client_id'], false, $charge['subscription_id'])) {
                     $sent_emails['recurring_expiring_in_week'][] = $charge['subscription_id'];
                 }
             }
         }
     }
     // Get all the recurring expiration emails to send in one month
     $sent_emails['recurring_expiring_in_month'] = array();
     $charges = $this->recurring_model->GetChargesByExpiryDate($next_month);
     if ($charges) {
         foreach ($charges as $charge) {
             $trip_trigger = TRUE;
             if (!empty($charge['renewed'])) {
                 // let's verify this subscription is active
                 $renewing_sub = $this->recurring_model->GetSubscriptionDetails($charge['client_id'], $charge['renewed']);
                 if ($renewing_sub['active'] == '1') {
                     $trip_trigger = FALSE;
                 }
             }
             if ($trip_trigger == TRUE) {
                 if (TriggerTrip('recurring_expiring_in_month', $charge['client_id'], false, $charge['subscription_id'])) {
                     $sent_emails['recurring_expiring_in_month'][] = $charge['subscription_id'];
                 }
             }
         }
     }
     $charge_success = count($charge_success);
     $charge_failure = count($charge_failure);
     $cancelled = count($cancelled);
     $autorecur_week = count($sent_emails['recurring_autorecur_in_week']);
     $autorecur_month = count($sent_emails['recurring_autorecur_in_month']);
     $expire_week = count($sent_emails['recurring_expiring_in_week']);
     $expire_month = count($sent_emails['recurring_expiring_in_month']);
     $response = $charge_success . " Successful Charges. \n";
     $response .= $charge_failure . " Failed Charges. \n";
     $response .= $cancelled . " Expired Subscriptions. \n";
     $response .= $autorecur_week . " Weekly Charge Reminders Sent. \n";
     $response .= $autorecur_month . " Monthly Charge Reminders Sent. \n";
     $response .= $expire_week . " Weekly Expiration Reminders Sent. \n";
     $response .= $expire_month . " Monthly Expiration Reminders Sent. \n";
     echo $response;
     $this->save_cron_date($key, 'cron_last_run_subs');
     if ($this->debug) {
         $this->log_it('Finished SubscriptionMaintenance Cron');
     }
     die;
 }
Exemplo n.º 3
0
 function Callback_confirm_recur($client_id, $gateway, $subscription, $params)
 {
     $CI =& get_instance();
     $CI->load->model('charge_data_model');
     $data = $CI->charge_data_model->Get('r' . $subscription['id']);
     $url = $this->GetAPIUrl($gateway);
     $order_id = $CI->charge_model->CreateNewOrder($client_id, $gateway['gateway_id'], $subscription['amount'], array(), $subscription['id'], $customer_id);
     $CI->load->model('order_authorization_model');
     $CI->order_authorization_model->SaveAuthorization($order_id, 'n/a');
     $CI->charge_model->SetStatus($order_id, 1);
     $CI->recurring_model->SetActive($client_id, $subscription['id']);
     // trip it - were golden!
     TriggerTrip('new_recurring', $client_id, $order_id, $subscription['id']);
     TriggerTrip('recurring_charge', $client_id, $order_id, $subscription['id']);
     // redirect back to user's site
     header('Location: ' . $data['return_url']);
     die;
 }
Exemplo n.º 4
0
 public function Callback_recurring_installment_stopped($client_id, $gateway, $subscription, $params)
 {
     // Mark the subscription as inactive
     $this->CI->load->model('recurring_model');
     $this->CI->recurring_model->MakeInactive($subscription['id']);
     $this->CI->recurring_model->CancelRecurring($client_id, $subscription['id'], TRUE);
     TriggerTrip('recurring_fail', $client_id, FALSE, $subscription['id']);
 }
Exemplo n.º 5
0
 function SaveNewCustomer($client_id, $first_name, $last_name, $company = '', $internal_id = '', $address_1 = '', $address_2 = '', $city = '', $state = '', $postal_code = '', $country_id = '', $phone = '', $email = '')
 {
     $insert_data = array('client_id' => $client_id, 'first_name' => $first_name, 'last_name' => $last_name, 'company' => $company, 'internal_id' => $internal_id, 'address_1' => $address_1, 'address_2' => $address_2, 'city' => $city, 'state' => $state, 'postal_code' => $postal_code, 'country' => $country_id, 'phone' => $phone, 'email' => $email, 'active' => '1', 'date_created' => date('Y-m-d, H:i:s'));
     $this->db->insert('customers', $insert_data);
     $customer_id = $this->db->insert_id();
     TriggerTrip('new_customer', $client_id, false, false, $customer_id);
     return $customer_id;
 }
Exemplo n.º 6
0
 /**
  * Process a credit card recurring charge
  *
  * Processes a credit card CHARGE transaction for a recurring subscription using the gateway_id to use the proper client gateway.
  * Returns an array response from the appropriate payment library.
  *
  * The gateway may return a 'next_charge' == YYYY-MM-DD in their response array, thus specifying the date of the next charge
  * and not relying on OG's date calculator.
  *
  * @param int $client_id	The Client ID
  * @param array $params The subscription array, from GetSubscription, for the recurring charge
  *
  * @return mixed Array with response_code and response_text
  */
 function ChargeRecurring($client_id, $params)
 {
     $CI =& get_instance();
     $gateway_id = $params['gateway_id'];
     // Get the gateway info to load the proper library
     $gateway = $this->GetGatewayDetails($client_id, $gateway_id);
     if (!$gateway or $gateway['enabled'] == '0') {
         return FALSE;
     }
     // get the credit card last four digits
     $params['credit_card'] = array();
     $params['credit_card']['card_num'] = $params['card_last_four'];
     // Create a new order
     $CI->load->model('charge_model');
     $order_id = $CI->charge_model->CreateNewOrder($client_id, $params['gateway_id'], $params['amount'], $params['credit_card'], $params['subscription_id'], $params['customer_id']);
     if ($params['amount'] > 0) {
         // Load the proper library
         $gateway_name = $gateway['name'];
         $this->load->library('payment/' . $gateway_name);
         // send to gateway for charging
         // gateway responds with:
         // 	success as TRUE or FALSE
         //	reason (error if success == FALSE)
         //	next_charge (if standard next_charge won't apply)
         $response = $this->{$gateway_name}->AutoRecurringCharge($client_id, $order_id, $gateway, $params);
     } else {
         $response = array();
         $response['success'] = TRUE;
     }
     $CI->load->model('recurring_model');
     if ($response['success'] == TRUE) {
         // save the last_charge and next_charge
         $last_charge = date('Y-m-d');
         if (!isset($response['next_charge'])) {
             $next_charge = $CI->recurring_model->GetNextChargeDate($params['subscription_id'], $params['next_charge']);
         } else {
             $next_charge = $response['next_charge'];
         }
         $CI->recurring_model->SetChargeDates($params['subscription_id'], $last_charge, $next_charge);
         $CI->charge_model->SetStatus($order_id, 1);
         TriggerTrip('recurring_charge', $client_id, $order_id, $params['subscription_id']);
     } else {
         $response = FALSE;
         // Check the number of failures allowed
         $num_allowed = $this->config->item('recurring_charge_failures_allowed');
         $failures = $params['number_charge_failures'];
         $CI->charge_model->SetStatus($order_id, 0);
         $failures++;
         $CI->recurring_model->AddFailure($params['subscription_id'], $failures);
         if ($failures >= $num_allowed) {
             $CI->recurring_model->CancelRecurring($client_id, $params['subscription_id'], TRUE);
             TriggerTrip('recurring_fail', $client_id, FALSE, $params['subscription_id']);
         }
     }
     return $response;
 }
Exemplo n.º 7
0
 function CancelRecurring($client_id, $recurring_id, $not_user_cancellation = FALSE)
 {
     // Get the subscription information
     $subscription = $this->GetSubscriptionDetails($client_id, $recurring_id);
     // Get the gateway info to load the proper library
     $CI =& get_instance();
     $CI->load->model('gateway_model');
     $gateway = $CI->gateway_model->GetGatewayDetails($client_id, $subscription['gateway_id']);
     if ((double) $subscription['amount'] > 0) {
         $gateway_name = $subscription['name'];
         $this->load->library('payment/' . $gateway_name);
         $cancelled = $this->{$gateway_name}->CancelRecurring($client_id, $subscription, $gateway);
     } else {
         $cancelled = TRUE;
     }
     $this->MakeInactive($recurring_id);
     if ($not_user_cancellation == FALSE) {
         TriggerTrip('recurring_cancel', $client_id, FALSE, $recurring_id);
     }
     if ($cancelled) {
         return TRUE;
     } else {
         return FALSE;
     }
 }
Exemplo n.º 8
0
 public function Callback_confirm($client_id, $gateway, $charge, $params)
 {
     $post = array('MD' => $params['MD'], 'PARes' => $params['PaRes']);
     $post_url = $this->GetAPIUrl($gateway, '3d');
     $response = $this->Process($charge['id'], $post_url, $post);
     $VPSTxId = isset($response['VPSTxId']) ? $response['VPSTxId'] : false;
     $TxAuthNo = isset($response['TxAuthNo']) ? $response['TxAuthNo'] : false;
     $SecurityKey = isset($response['SecurityKey']) ? $response['SecurityKey'] : false;
     $this->ci->load->model('charge_data_model');
     $data = $this->ci->charge_data_model->Get($charge['id']);
     if ($this->debug) {
         $this->log_it('Callback_confirm data', $data);
         $this->log_it('Callback_confirm charge', $charge);
         $this->log_it('Callback_confirm Params', $params);
         $this->log_it('Callback_Confirm Response', $response);
     }
     // A successful transaction
     if ($response['Status'] == 'OK' || $response['Status'] == 'AUTHENTICATED' && $response['3DSecureStatus'] == 'OK') {
         /*
         	Recurring Charge
         */
         if (isset($charge['type']) && $charge['type'] == 'recurring_charge' || isset($charge['type']) && $charge['type'] == 'recurring_repeat') {
             // Do we have a recurring id passed in the $charge var?
             $subscription_id = $charge['recurring_id'];
             // We need to find our subscription id by backtracing based
             // on the charge id.
             $query = $this->ci->db->where('order_data_value', $charge['id'])->get('order_data');
             if (isset($subscription_id) || $query->num_rows() > 0) {
                 if (empty($subscription_id)) {
                     $subscription_id = str_replace('r', '', $query->row()->order_id);
                 }
                 $this->ci->charge_model->SetStatus($charge['id'], 1);
                 // Since we didn't get to save these for REPEATS earlier, we'll save them now
                 // these authorizations were saved during $this->Process()
                 $this->ci->load->model('recurring_model');
                 $this->ci->recurring_model->SaveApiCustomerReference($subscription_id, $VPSTxId);
                 $this->ci->recurring_model->SaveApiPaymentReference($subscription_id, $charge['id'] . '|' . $TxAuthNo);
                 $this->ci->recurring_model->SaveApiAuthNumber($subscription_id, $SecurityKey);
                 // Set the subscription to active
                 $this->ci->load->model('recurring_model');
                 $this->ci->recurring_model->SetActive($client_id, $subscription_id);
                 $response_array = array('charge_id' => $charge['id'], 'recurring_id' => $subscription_id);
                 $response = $this->ci->response->TransactionResponse(100, $response_array);
             }
         }
         /*
         	Single Charge
         */
         // save authorization (transaction id #)
         $this->ci->load->model('order_authorization_model');
         $this->ci->order_authorization_model->SaveAuthorization($charge['id'], $VPSTxId, $TxAuthNo);
         $this->ci->charge_model->SetStatus($charge['id'], 1);
         TriggerTrip('charge', $client_id, $charge['id']);
         // Save our SecurityKey so that we can do refunds...
         if (isset($SecurityKey) && !empty($SecurityKey)) {
             $this->ci->charge_data_model->Save($charge['id'], 'token', $params['Token']);
         }
         $coupon_id = (isset($charge['coupon']) and isset($charge['coupon']['coupon_id'])) ? $charge['coupon']['coupon_id'] : null;
         if (!empty($coupon_id)) {
             // track coupon
             $this->ci->load->model('coupon_model');
             $this->ci->coupon_model->add_usage($coupon_id, FALSE, $charge['id'], $customer_id);
         }
         // redirect back to user's site
         header('Location: ' . $data['return_url']);
         die;
     } else {
         $this->ci->load->model('charge_model');
         $this->ci->charge_model->SetStatus($charge['id'], 0);
         // Make sure to show an error here since we won't know anywhere else.
         $this->ci->load->library('session');
         $this->ci->load->model('cp/notices');
         $this->ci->notices->SetError('Charge failed: ' . $response['StatusDetail']);
         // redirect back to user's site
         header('Location: ' . $data['cancel_url']);
         die;
     }
 }
Exemplo n.º 9
0
 /**
  * Record Subscription Payment
  *
  * This is a hidden API call used for Membrr to record payments for subscriptions manually
  * when extending an expiry date.
  *
  * @param int $recurring_id
  * @param string $amount
  *
  * @return int $charge_id
  */
 function RecordSubscriptionpayment($client_id, $params)
 {
     if (!isset($params['recurring_id']) or !isset($params['amount'])) {
         die($this->response->Error(1004));
     }
     $this->load->model('recurring_model');
     $subscription = $this->recurring_model->GetRecurring($client_id, $params['recurring_id']);
     // get gateway_id from previous subscription payments, else make it 0
     $result = $this->db->select('gateway_id')->where('subscription_id', $params['recurring_id'])->limit(1)->get('subscriptions');
     if ($result->num_rows() > 0) {
         $gateway_id = $result->row()->gateway_id;
     } else {
         $gateway_id = 0;
     }
     // record payment
     $this->load->model('charge_model');
     $charge_id = $this->charge_model->CreateNewOrder($client_id, $gateway_id, (double) $params['amount'], FALSE, $subscription['id'], $subscription['customer']['id']);
     if (empty($charge_id)) {
         return array('error' => 'Unable to create order.');
     } else {
         $this->charge_model->SetStatus($charge_id, 1);
         TriggerTrip('recurring_charge', $client_id, $charge_id, $subscription['id']);
         // extend next_charge and end_date
         $start = $subscription['next_charge_date'];
         $next_charge = date('Y-m-d', strtotime($start . ' + ' . $subscription['interval'] . ' days'));
         // if the end_date is less than the next charge date, we'll push it back 2 intervals
         if (strtotime($subscription['end_date']) < strtotime($next_charge)) {
             $end_date = date('Y-m-d', strtotime($start . ' + ' . $subscription['interval'] * 2 . ' days'));
         } else {
             $end_date = date('Y-m-d', strtotime($subscription['end_date']));
         }
         $update = array('next_charge' => $next_charge, 'end_date' => $end_date);
         // update locally
         $this->db->update('subscriptions', array('next_charge' => $next_charge, 'end_date' => $end_date), array('subscription_id' => $subscription['id']));
         // return
         return array('charge_id' => $charge_id, 'next_charge' => $next_charge, 'end_date' => $end_date);
     }
 }