/**
  * Adds the Pro-Rating discount to an invoice.
  *
  * @since  1.0.1.0
  * @param  MS_Model_Invoice $invoice
  * @return MS_Model_Invoice Modified Invoice.
  */
 public function add_discount($invoice)
 {
     // Only the first invoice can be pro-rated.
     if ($invoice->invoice_number > 1) {
         return $invoice;
     }
     $subscription = $invoice->get_subscription();
     $membership = $invoice->get_membership();
     if (!$subscription->move_from_id) {
         return $invoice;
     }
     $ids = explode(',', $subscription->move_from_id);
     if (empty($ids)) {
         return $invoice;
     }
     if ($membership->is_free()) {
         return $invoice;
     }
     // Calc pro rate discount if moving from another membership.
     $pro_rate = 0;
     foreach ($ids as $id) {
         if (!$id) {
             continue;
         }
         $move_from = MS_Model_Relationship::get_subscription($subscription->user_id, $id);
         if ($move_from->is_valid() && $move_from->id == $id) {
             $pro_rate += $this->get_discount($move_from);
         }
     }
     $pro_rate = floatval(apply_filters('ms_addon_prorate_apply_discount', abs($pro_rate), $invoice));
     if ($pro_rate > $invoice->amount) {
         $pro_rate = $invoice->amount;
     }
     if ($pro_rate > 0) {
         $invoice->pro_rate = $pro_rate;
         $notes[] = sprintf(__('Pro-Rate Discount: %s.', MS_TEXT_DOMAIN) . ' ', $invoice->currency . ' ' . $pro_rate);
     }
     return $invoice;
 }
 /**
  * Adds the Pro-Rating discount to an invoice.
  *
  * @since  1.0.1.0
  * @param  MS_Model_Invoice $invoice
  * @return MS_Model_Invoice Modified Invoice.
  */
 public function add_discount($invoice)
 {
     $subscription = $invoice->get_subscription();
     // If memberships were already cancelled don't pro-rate again!
     if ($subscription->cancelled_memberships) {
         return $invoice;
     }
     $membership = $invoice->get_membership();
     if (!$subscription->move_from_id) {
         return $invoice;
     }
     $ids = explode(',', $subscription->move_from_id);
     if (empty($ids)) {
         return $invoice;
     }
     if ($membership->is_free()) {
         return $invoice;
     }
     // Calc pro rate discount if moving from another membership.
     $pro_rate = 0;
     foreach ($ids as $id) {
         if (!$id) {
             continue;
         }
         $move_from = MS_Model_Relationship::get_subscription($subscription->user_id, $id);
         if ($move_from->is_valid() && $move_from->membership_id == $id) {
             $pro_rate += $this->get_discount($move_from);
         }
     }
     $pro_rate = floatval(apply_filters('ms_addon_prorate_apply_discount', abs($pro_rate), $invoice));
     if ($pro_rate > $invoice->amount) {
         $pro_rate = $invoice->amount;
     }
     if ($pro_rate > 0) {
         $invoice->pro_rate = $pro_rate;
         $notes[] = sprintf(__('Pro-Rate Discount: %s.', 'membership2') . ' ', $invoice->currency . ' ' . $pro_rate);
     }
     return $invoice;
 }
 /**
  * Processes online payments.
  *
  * Send to Authorize.net to process the payment immediatly.
  *
  * @since  1.0.0
  * @param MS_Model_Invoice $invoice The invoice to pay.
  * @param MS_Model_Member The member paying the invoice.
  * @return bool True on success, otherwise throws an exception.
  */
 protected function online_purchase(&$invoice, $member, $log_action)
 {
     $success = false;
     $notes = '';
     $amount = 0;
     $subscription = $invoice->get_subscription();
     do_action('ms_gateway_authorize_online_purchase_before', $invoice, $member, $this);
     $need_code = lib3()->is_true($this->secure_cc);
     $have_code = !empty($_POST['card_code']);
     if (0 == $invoice->total) {
         $notes = __('Total is zero. Payment approved. Not sent to gateway.', 'membership2');
         $invoice->pay_it(MS_Gateway_Free::ID, '');
         $invoice->add_notes($notes);
         $invoice->save();
         $invoice->changed();
     } elseif (!$need_code || $have_code) {
         $amount = MS_Helper_Billing::format_price($invoice->total);
         $cim_transaction = $this->get_cim_transaction($member);
         $cim_transaction->amount = $amount;
         $cim_transaction->order->invoiceNumber = $invoice->id;
         $invoice->timestamp = time();
         $invoice->save();
         $_POST['API Out: Secure Payment'] = lib3()->is_true($this->secure_cc);
         $_POST['API Out: CustomerProfileID'] = $cim_transaction->customerProfileId;
         $_POST['API Out: PaymentProfileID'] = $cim_transaction->customerPaymentProfileId;
         $_POST['API Out: InvoiceNumber'] = $cim_transaction->order->invoiceNumber;
         $response = $this->get_cim()->createCustomerProfileTransaction('AuthCapture', $cim_transaction);
         if (!empty($response->xml) && !empty($response->xml->messages) && !empty($response->xml->messages->message)) {
             $msg = $response->xml->messages->message;
             $_POST['API Response: Short'] = $msg->code . ': ' . $msg->text;
         } else {
             $_POST['API Response: Short'] = '-';
         }
         if (isset($response->response)) {
             if (is_string($response->response)) {
                 $_POST['API Response: XML'] = $response->response;
             } else {
                 $_POST['API Response: XML'] = json_encode($response->response);
             }
         } else {
             $_POST['API Response: XML'] = json_encode($response->response);
         }
         if ($response->isOk()) {
             $transaction_response = $response->getTransactionResponse();
             if ($transaction_response->approved) {
                 $external_id = $response->getTransactionResponse()->transaction_id;
                 $invoice->pay_it($this->id, $external_id);
                 $success = true;
                 $notes = __('Payment successful', 'membership2');
             } else {
                 $notes = sprintf(__('Payment Failed: code %s, subcode %s, reason code %, reason %s', 'membership2'), $transaction_response->response_code, $transaction_response->response_subcode, $transaction_response->response_reason_code, $transaction_response->response_reason);
             }
         } else {
             $notes = __('Payment Failed: ', 'membership2') . $response->getMessageText();
         }
     } elseif ($need_code && !$have_code) {
         $notes = __('Secure payment failed: No Card Code found', 'membership2');
     }
     // Mask the credit card number before logging it to database.
     $card_num = '';
     $card_code = '';
     if (isset($_POST['card_num'])) {
         // Card Num   6789765435678765
         // Becomes    ************8765
         $card_num = str_replace(' ', '', $_POST['card_num']);
         $_POST['card_num'] = str_pad(substr($card_num, -4), strlen($card_num), '*', STR_PAD_LEFT);
     }
     if (isset($_POST['card_code'])) {
         $card_code = $_POST['card_code'];
         $_POST['card_code'] = str_repeat('*', strlen($card_code));
     }
     do_action('ms_gateway_transaction_log', self::ID, $log_action, $success, $subscription->id, $invoice->id, $amount, $notes, $external_id);
     // Restore the POST data in case it's used elsewhere.
     $_POST['card_num'] = $card_num;
     $_POST['card_code'] = $card_code;
     unset($_POST['API Out: CustomerProfileID']);
     unset($_POST['API Out: PaymentProfileID']);
     unset($_POST['API Out: InvoiceNumber']);
     unset($_POST['API Out: Secure Payment']);
     unset($_POST['API Response: Short']);
     unset($_POST['API Response: XML']);
     return $success;
 }
 /**
  * Processes online payments.
  *
  * Send to Authorize.net to process the payment immediatly.
  *
  * @since  1.0.0
  * @param MS_Model_Invoice $invoice The invoice to pay.
  * @param MS_Model_Member The member paying the invoice.
  * @return bool True on success, otherwise throws an exception.
  */
 protected function online_purchase(&$invoice, $member, $log_action)
 {
     $success = false;
     $notes = '';
     $amount = 0;
     $subscription = $invoice->get_subscription();
     do_action('ms_gateway_authorize_online_purchase_before', $invoice, $member, $this);
     if (0 == $invoice->total) {
         $notes = __('Total is zero. Payment approved. Not sent to gateway.', MS_TEXT_DOMAIN);
         $invoice->pay_it(MS_Gateway_Free::ID, '');
         $invoice->add_notes($notes);
         $invoice->save();
         $invoice->changed();
     } else {
         $amount = MS_Helper_Billing::format_price($invoice->total);
         $cim_transaction = $this->get_cim_transaction($member);
         $cim_transaction->amount = $amount;
         $cim_transaction->order->invoiceNumber = $invoice->id;
         $invoice->timestamp = time();
         $invoice->save();
         $response = $this->get_cim()->createCustomerProfileTransaction('AuthCapture', $cim_transaction);
         if ($response->isOk()) {
             $transaction_response = $response->getTransactionResponse();
             if ($transaction_response->approved) {
                 $external_id = $response->getTransactionResponse()->transaction_id;
                 $invoice->pay_it($this->id, $external_id);
                 $success = true;
                 $notes = __('Payment successful', MS_TEXT_DOMAIN);
             } else {
                 $notes = sprintf(__('Payment Failed: code %s, subcode %s, reason code %, reason %s', MS_TEXT_DOMAIN), $transaction_response->response_code, $transaction_response->response_subcode, $transaction_response->response_reason_code, $transaction_response->response_reason);
             }
         } else {
             $notes = __('Payment Failed: ', MS_TEXT_DOMAIN) . $response->getMessageText();
         }
     }
     do_action('ms_gateway_transaction_log', self::ID, $log_action, $success, $subscription->id, $invoice->id, $amount, $notes);
     return $success;
 }