/**
  * Process subscription renewal
  *
  * @since  1.4
  * @param float $amount_to_charge subscription amount to charge, could include
  *              multiple renewals if they've previously failed and the admin
  *              has enabled it
  * @param WC_Order $order original order containing the subscription
  * @param int $product_id the ID of the subscription product
  */
 public function process_renewal_payment($amount_to_charge, $order, $product_id = null)
 {
     require_once 'class-wc-realex-api.php';
     $realex_subscription_count = 0;
     if (is_numeric($order->realex_subscription_count) && $order->realex_subscription_count) {
         $realex_subscription_count = $order->realex_subscription_count;
     }
     // increment the subscription count so we don't get order number clashes
     $realex_subscription_count++;
     update_post_meta($order->id, '_realex_subscription_count', $realex_subscription_count);
     // set custom class member used by the realex gateway
     $order->payment_total = SV_WC_Helper::number_format($amount_to_charge);
     // zero-dollar subscription renewal.  weird, but apparently it happens -- only applicable to Subs 1.5.x
     if (!SV_WC_Plugin_Compatibility::is_wc_subscriptions_version_gte_2_0()) {
         if (0 == $order->payment_total) {
             // add order note
             $order->add_order_note(sprintf(__('%s0 Subscription Renewal Approved', 'woocommerce-gateway-realex'), get_woocommerce_currency_symbol()));
             // update subscription
             WC_Subscriptions_Manager::process_subscription_payments_on_order($order, $product_id);
             return;
         }
     }
     // This order is missing a tokenized card, lets see whether there's one available for the customer
     if (!get_post_meta($order->id, '_realex_cardref', true)) {
         $credit_cards = get_user_meta($order->get_user_id(), 'woocommerce_realex_cc', true);
         if (is_array($credit_cards)) {
             $card_ref = (object) current($credit_cards);
             $card_ref = $card_ref->ref;
             update_post_meta($order->id, '_realex_cardref', $card_ref);
             if (SV_WC_Plugin_Compatibility::is_wc_subscriptions_version_gte_2_0()) {
                 foreach (wcs_get_subscriptions_for_renewal_order($order) as $subscription) {
                     update_post_meta($subscription->id, '_realex_cardref', $card_ref);
                 }
             }
         }
     }
     // create the realex api client
     $realex_client = new Realex_API($this->get_endpoint_url(), $this->get_realvault_endpoint_url(), $this->get_shared_secret());
     // create the customer/cc tokens, and authorize the initial payment amount, if any
     $response = $this->authorize($realex_client, $order);
     if ($response && '00' == $response->result) {
         // add order note
         $order->add_order_note(sprintf(__('Credit Card Subscription Renewal Payment Approved (Payment Reference: %s) ', 'woocommerce-gateway-realex'), $response->pasref));
         // update subscription
         if (SV_WC_Plugin_Compatibility::is_wc_subscriptions_version_gte_2_0()) {
             $order->payment_complete((string) $response->pasref);
         } else {
             WC_Subscriptions_Manager::process_subscription_payments_on_order($order, $product_id);
         }
     } else {
         // generate the result message
         $message = __('Credit Card Subscription Renewal Payment Failed', 'woocommerce-gateway-realex');
         /* translators: Placeholders: %1$s - result, %2$s - result message */
         if ($response) {
             $message .= sprintf(__(' (Result: %1$s - "%2$s").', 'woocommerce-gateway-realex'), $response->result, $response->message);
         }
         $order->add_order_note($message);
         // update subscription
         if (!SV_WC_Plugin_Compatibility::is_wc_subscriptions_version_gte_2_0()) {
             WC_Subscriptions_Manager::process_subscription_payment_failure_on_order($order, $product_id);
         }
     }
 }
 /**
  * Process subscription renewal
  *
  * @since 4.1.0
  * @param float $amount_to_charge subscription amount to charge, could include multiple renewals if they've previously failed and the admin has enabled it
  * @param WC_Order $order original order containing the subscription
  * @param int $product_id the subscription product id
  */
 public function process_renewal_payment_1_5($amount_to_charge, $order, $product_id)
 {
     try {
         // set order defaults
         $order = $this->get_gateway()->get_order($order->id);
         // zero-dollar subscription renewal. weird, but apparently it happens
         if (0 == $amount_to_charge) {
             // add order note
             $order->add_order_note(sprintf(_x('%s0 Subscription Renewal Approved', 'Supports direct credit card subscriptions', $this->get_gateway()->get_text_domain()), get_woocommerce_currency_symbol()));
             // update subscription
             WC_Subscriptions_Manager::process_subscription_payments_on_order($order, $product_id);
             return;
         }
         // set the amount to charge, ensuring that we have a decimal point, even if it's 1.00
         $order->payment_total = SV_WC_Helper::number_format($amount_to_charge);
         // required
         if (!$order->payment->token || !$order->get_user_id()) {
             throw new SV_WC_Payment_Gateway_Exception('Subscription Renewal: Payment Token or User ID is missing/invalid.');
         }
         // get the token, we've already verified it's good
         $token = $this->get_gateway()->get_payment_token($order->get_user_id(), $order->payment->token);
         // perform the transaction
         if ($this->get_gateway()->is_credit_card_gateway()) {
             if ($this->get_gateway()->perform_credit_card_charge()) {
                 $response = $this->get_gateway()->get_api()->credit_card_charge($order);
             } else {
                 $response = $this->get_gateway()->get_api()->credit_card_authorization($order);
             }
         } elseif ($this->get_gateway()->is_echeck_gateway()) {
             $response = $this->get_gateway()->get_api()->check_debit($order);
         }
         // check for success
         if ($response->transaction_approved()) {
             // order note based on gateway type
             if ($this->get_gateway()->is_credit_card_gateway()) {
                 $message = sprintf(_x('%s %s Subscription Renewal Payment Approved: %s ending in %s (expires %s)', 'Supports direct credit card subscriptions', $this->get_gateway()->get_text_domain()), $this->get_gateway()->get_method_title(), $this->get_gateway()->perform_credit_card_authorization() ? 'Authorization' : 'Charge', $token->get_card_type() ? $token->get_type_full() : 'card', $token->get_last_four(), $token->get_exp_month() . '/' . $token->get_exp_year());
             } elseif ($this->get_gateway()->is_echeck_gateway()) {
                 // there may or may not be an account type (checking/savings) available, which is fine
                 $message = sprintf(_x('%s Check Subscription Renewal Payment Approved: %s account ending in %s', 'Supports direct cheque subscriptions', $this->get_gateway()->get_text_domain()), $this->get_gateway()->get_method_title(), $token->get_account_type(), $token->get_last_four());
             }
             // add order note
             $order->add_order_note($message);
             // set transaction ID manually, WCS 1.5.x calls WC_Order::payment_complete() internally
             if ($response->get_transaction_id()) {
                 update_post_meta($order->id, '_transaction_id', $response->get_transaction_id());
             }
             // update subscription
             WC_Subscriptions_Manager::process_subscription_payments_on_order($order, $product_id);
         } else {
             // failure
             throw new SV_WC_Payment_Gateway_Exception(sprintf('%s: %s', $response->get_status_code(), $response->get_status_message()));
         }
     } catch (SV_WC_Plugin_Exception $e) {
         // don't mark the order as failed, Subscriptions will handle marking the renewal order as failed
         $order->add_order_note(sprintf(_x('%s Renewal Payment Failed (%s)', $this->get_gateway()->get_text_domain()), $this->get_gateway()->get_method_title(), $e->getMessage()));
         // update subscription
         WC_Subscriptions_Manager::process_subscription_payment_failure_on_order($order, $product_id);
     }
 }
 /**
  * Add payment and transaction information as class members of WC_Order
  * instance for use in credit card capture transactions.  Standard information
  * can include:
  *
  * $order->capture->amount - amount to capture (partial captures are not supported by the framework yet)
  * $order->capture->description - capture description
  * $order->capture->trans_id - transaction ID for the order being captured
  *
  * included for backwards compat (4.1 and earlier)
  *
  * $order->capture_total
  * $order->description
  *
  * @since 2.0.0
  * @param WC_Order $order order being processed
  * @return WC_Order object with payment and transaction information attached
  */
 protected function get_order_for_capture($order)
 {
     if (is_numeric($order)) {
         $order = wc_get_order($order);
     }
     // add capture info
     $order->capture = new stdClass();
     $order->capture->amount = SV_WC_Helper::number_format($order->get_total());
     /* translators: Placeholders: %1$s - site title, %2$s - order number. Definitions: Capture as in capture funds from a credit card. */
     $order->capture->description = sprintf(esc_html__('%1$s - Capture for Order %2$s', 'woocommerce-plugin-framework'), wp_specialchars_decode(get_bloginfo('name')), $order->get_order_number());
     $order->capture->trans_id = $this->get_order_meta($order->id, 'trans_id');
     // backwards compat for 4.1 and earlier
     $order->capture_total = $order->capture->amount;
     $order->description = $order->capture->description;
     /**
      * Direct Gateway Capture Get Order Filter.
      *
      * Allow actors to modify the order object used for performing charge captures.
      *
      * @since 2.0.0
      * @param \WC_Order $order order object
      * @param \SV_WC_Payment_Gateway_Direct $this instance
      */
     return apply_filters('wc_payment_gateway_' . $this->get_id() . '_get_order_for_capture', $order, $this);
 }
 /**
  * Adds shipping information to the request
  *
  * @since 2.0.0
  * @return array
  */
 protected function get_shipping()
 {
     if ($this->order->get_total_shipping() > 0) {
         return array('amount' => SV_WC_Helper::number_format($this->order->get_total_shipping()), 'name' => __('Order Shipping', 'woocommerce-gateway-authorize-net-cim'), 'description' => SV_WC_Helper::str_truncate($this->order->get_shipping_method(), 255));
     } else {
         return array();
     }
 }