/**
  * Handles payment processing
  *
  * @since 1.0.0
  * @see WC_Payment_Gateway::process_payment()
  * @param int|string $order_id
  * @return array associative array with members 'result' and 'redirect'
  */
 public function process_payment($order_id)
 {
     $default = parent::process_payment($order_id);
     /**
      * Direct Gateway Process Payment Filter.
      *
      * Allow actors to intercept and implement the process_payment() call for
      * this transaction. Return an array value from this filter will return it
      * directly to the checkout processing code and skip this method entirely.
      *
      * @since 1.0.0
      * @param bool $result default true
      * @param int|string $order_id order ID for the payment
      * @param \SV_WC_Payment_Gateway_Direct $this instance
      */
     if (is_array($result = apply_filters('wc_payment_gateway_' . $this->get_id() . '_process_payment', true, $order_id, $this))) {
         return $result;
     }
     // add payment information to order
     $order = $this->get_order($order_id);
     try {
         // registered customer checkout (already logged in or creating account at checkout)
         if ($this->supports_tokenization() && 0 != $order->get_user_id() && $this->get_payment_tokens_handler()->should_tokenize() && (0 == $order->payment_total || $this->tokenize_before_sale())) {
             $order = $this->get_payment_tokens_handler()->create_token($order);
         }
         // payment failures are handled internally by do_transaction()
         // the order amount will be $0 if a WooCommerce Subscriptions free trial product is being processed
         // note that customer id & payment token are saved to order when create_token() is called
         if (0 == $order->payment_total && !$this->transaction_forced() || $this->do_transaction($order)) {
             // add transaction data for zero-dollar "orders"
             if (0 == $order->payment_total) {
                 $this->add_transaction_data($order);
             }
             if ($order->has_status('on-hold')) {
                 $order->reduce_order_stock();
                 // reduce stock for held orders, but don't complete payment
             } else {
                 $order->payment_complete();
                 // mark order as having received payment
             }
             // process_payment() can sometimes be called in an admin-context
             if (isset(WC()->cart)) {
                 WC()->cart->empty_cart();
             }
             /**
              * Payment Gateway Payment Processed Action.
              *
              * Fired when a payment is processed for an order.
              *
              * @since 4.1.0
              * @param \WC_Order $order order object
              * @param \SV_WC_Payment_Gateway_Direct $this instance
              */
             do_action('wc_payment_gateway_' . $this->get_id() . '_payment_processed', $order, $this);
             return array('result' => 'success', 'redirect' => $this->get_return_url($order));
         }
     } catch (SV_WC_Plugin_Exception $e) {
         $this->mark_order_as_failed($order, $e->getMessage());
         return array('result' => 'failure', 'message' => $e->getMessage());
     }
     return $default;
 }