/**
  * When a new order is inserted, add the subscriptions period to the order. 
  * 
  * It's important that the period is tied to the order so that changing the products
  * period does not change the past. 
  *
  * @since 1.0
  */
 public static function add_order_meta($order_id)
 {
     global $woocommerce;
     if (WC_Subscriptions_Order::order_contains_subscription($order_id)) {
         $order = new WC_Order($order_id);
         $order_subscription_periods = array();
         $order_subscription_intervals = array();
         $order_subscription_lengths = array();
         $order_subscription_trial_lengths = array();
         foreach ($order->get_items() as $item) {
             $period = WC_Subscriptions_Product::get_period($item['id']);
             if (!empty($period)) {
                 $order_subscription_periods[$item['id']] = $period;
             }
             $interval = WC_Subscriptions_Product::get_interval($item['id']);
             if (!empty($interval)) {
                 $order_subscription_intervals[$item['id']] = $interval;
             }
             $length = WC_Subscriptions_Product::get_length($item['id']);
             if (!empty($length)) {
                 $order_subscription_lengths[$item['id']] = $length;
             }
             $trial_length = WC_Subscriptions_Product::get_trial_length($item['id']);
             if (!empty($trial_length)) {
                 $order_subscription_trial_lengths[$item['id']] = $trial_length;
             }
         }
         update_post_meta($order_id, '_order_subscription_periods', $order_subscription_periods);
         update_post_meta($order_id, '_order_subscription_intervals', $order_subscription_intervals);
         update_post_meta($order_id, '_order_subscription_lengths', $order_subscription_lengths);
         update_post_meta($order_id, '_order_subscription_trial_lengths', $order_subscription_trial_lengths);
         // Store sign-up fee details
         foreach (WC_Subscriptions_Cart::get_sign_up_fee_fields() as $field_name) {
             update_post_meta($order_id, "_{$field_name}", $woocommerce->cart->{$field_name});
         }
         // Prepare sign up fee taxes to store in same format as order taxes
         $sign_up_fee_taxes = array();
         foreach (array_keys($woocommerce->cart->sign_up_fee_taxes) as $key) {
             $is_compound = $woocommerce->cart->tax->is_compound($key) ? 1 : 0;
             $sign_up_fee_taxes[] = array('label' => $woocommerce->cart->tax->get_rate_label($key), 'compound' => $is_compound, 'cart_tax' => number_format($woocommerce->cart->sign_up_fee_taxes[$key], 2, '.', ''));
         }
         update_post_meta($order_id, '_sign_up_fee_taxes', $sign_up_fee_taxes);
     }
 }
 /**
  * Removes a couple of notifications that are less relevant for Subscription orders.
  * 
  * @since 1.0
  */
 public static function maybe_remove_customer_processing_order($order_id)
 {
     if (WC_Subscriptions_Order::order_contains_subscription($order_id)) {
         remove_action('woocommerce_order_status_pending_to_processing_notification', array(self::$woocommerce_email, 'customer_processing_order'));
         remove_action('woocommerce_order_status_pending_to_on-hold_notification', array(self::$woocommerce_email, 'customer_processing_order'));
     }
 }
 /**
  * Process payment for an order:
  * 1) If the order contains a subscription, process the initial subscription payment (could be $0 if a free trial exists)
  * 2) If the order contains a pre-order, process the pre-order total (could be $0 if the pre-order is charged upon release)
  * 3) Otherwise use the parent::process_payment() method for regular product purchases
  *
  * @since 2.0
  * @param int $order_id
  * @return array
  */
 public function process_payment($order_id)
 {
     global $wc_braintree;
     $order = $this->get_order($order_id);
     try {
         /* processing subscription */
         if ($wc_braintree->is_subscriptions_active() && WC_Subscriptions_Order::order_contains_subscription($order_id)) {
             return $this->process_subscription_payment($order);
             /* processing pre-order */
         } elseif ($wc_braintree->is_pre_orders_active() && WC_Pre_Orders_Order::order_contains_pre_order($order_id)) {
             return $this->process_pre_order_payment($order);
             /* processing regular product */
         } else {
             return parent::process_payment($order_id);
         }
     } catch (WC_Gateway_Braintree_Exception $e) {
         // mark order as failed, which adds an order note for the admin and displays a generic "payment error" to the customer
         $this->mark_order_as_failed($order, $e->getMessage());
         // add detailed debugging information
         $this->add_debug_message($e->getErrors());
     } catch (Braintree_Exception_Authorization $e) {
         $this->mark_order_as_failed($order, __('Authorization failed, ensure that your API key is correct and has permissions to create transactions.', WC_Braintree::TEXT_DOMAIN));
     } catch (Exception $e) {
         $this->mark_order_as_failed($order, sprintf(__('Error Type %s', WC_Braintree::TEXT_DOMAIN), get_class($e)));
     }
 }
 /**
  * When a new order is inserted, add the subscriptions period to the order. 
  * 
  * It's important that the period is tied to the order so that changing the products
  * period does not change the past. 
  *
  * @since 1.0
  */
 public static function add_order_meta($order_id, $posted)
 {
     global $woocommerce;
     if (WC_Subscriptions_Order::order_contains_subscription($order_id)) {
         // This works because the 'new_order_item' runs before the 'woocommerce_checkout_update_order_meta' hook
         // Set the recurring totals so totals display correctly on order page
         update_post_meta($order_id, '_order_recurring_discount_cart', WC_Subscriptions_Cart::get_recurring_discount_cart());
         update_post_meta($order_id, '_order_recurring_discount_total', WC_Subscriptions_Cart::get_recurring_discount_total());
         update_post_meta($order_id, '_order_recurring_shipping_tax_total', WC_Subscriptions_Cart::get_recurring_shipping_tax_total());
         update_post_meta($order_id, '_order_recurring_tax_total', WC_Subscriptions_Cart::get_recurring_total_tax());
         update_post_meta($order_id, '_order_recurring_total', WC_Subscriptions_Cart::get_recurring_total());
         // Get recurring taxes into same format as _order_taxes
         $order_recurring_taxes = array();
         foreach (WC_Subscriptions_Cart::get_recurring_taxes() as $tax_key => $tax_amount) {
             $is_compound = $woocommerce->cart->tax->is_compound($tax_key) ? 1 : 0;
             if (isset($woocommerce->cart->taxes[$tax_key])) {
                 $cart_tax = $tax_amount;
                 $shipping_tax = 0;
             } else {
                 $cart_tax = 0;
                 $shipping_tax = $tax_amount;
             }
             $order_recurring_taxes[] = array('label' => $woocommerce->cart->tax->get_rate_label($tax_key), 'compound' => $is_compound, 'cart_tax' => woocommerce_format_total($cart_tax), 'shipping_tax' => woocommerce_format_total($shipping_tax));
         }
         update_post_meta($order_id, '_order_recurring_taxes', $order_recurring_taxes);
         $payment_gateways = $woocommerce->payment_gateways->payment_gateways();
         if (!$payment_gateways[$posted['payment_method']]->supports('subscriptions')) {
             update_post_meta($order_id, '_wcs_requires_manual_renewal', 'true');
         }
     }
 }
 /**
  * Process the payment
  */
 function process_payment($order_id)
 {
     global $woocommerce;
     if (class_exists('WC_Subscriptions_Order') && WC_Subscriptions_Order::order_contains_subscription($order_id)) {
         $order = new WC_Order($order_id);
         $stripe_token = isset($_POST['stripe_token']) ? woocommerce_clean($_POST['stripe_token']) : '';
         // Use Stripe CURL API for payment
         try {
             $post_data = array();
             $customer_id = 0;
             // Check if paying via customer ID
             if (isset($_POST['stripe_customer_id']) && $_POST['stripe_customer_id'] !== 'new' && is_user_logged_in()) {
                 $customer_ids = get_user_meta(get_current_user_id(), '_stripe_customer_id', false);
                 if (isset($customer_ids[$_POST['stripe_customer_id']]['customer_id'])) {
                     $customer_id = $customer_ids[$_POST['stripe_customer_id']]['customer_id'];
                 } else {
                     throw new Exception(__('Invalid card.', 'wc_stripe'));
                 }
             } elseif (empty($stripe_token)) {
                 throw new Exception(__('Please make sure your card details have been entered correctly and that your browser supports JavaScript.', 'wc_stripe'));
             }
             if (method_exists('WC_Subscriptions_Order', 'get_total_initial_payment')) {
                 $initial_payment = WC_Subscriptions_Order::get_total_initial_payment($order);
             } else {
                 $initial_payment = WC_Subscriptions_Order::get_sign_up_fee($order) + WC_Subscriptions_Order::get_price_per_period($order);
             }
             $customer_response = $this->add_customer_to_order($order, $customer_id, $stripe_token);
             if ($initial_payment > 0) {
                 $payment_response = $this->process_subscription_payment($order, $initial_payment);
             }
             if (is_wp_error($customer_response)) {
                 throw new Exception($customer_response->get_error_message());
             } else {
                 if (isset($payment_response) && is_wp_error($payment_response)) {
                     throw new Exception($payment_response->get_error_message());
                 } else {
                     // Payment complete
                     $order->payment_complete();
                     // Remove cart
                     $woocommerce->cart->empty_cart();
                     // Activate subscriptions
                     WC_Subscriptions_Manager::activate_subscriptions_for_order($order);
                     // Store token
                     if ($stripe_token) {
                         update_post_meta($order->id, '_stripe_token', $stripe_token);
                     }
                     // Return thank you page redirect
                     return array('result' => 'success', 'redirect' => $this->get_return_url($order));
                 }
             }
         } catch (Exception $e) {
             $woocommerce->add_error(__('Error:', 'wc_stripe') . ' "' . $e->getMessage() . '"');
             return;
         }
     } else {
         return parent::process_payment($order_id);
     }
 }
 /**
  * Process the payment
  *
  * @param  int $order_id
  * @return array
  */
 public function process_payment($order_id, $retry = true)
 {
     // Processing subscription
     if (class_exists('WC_Subscriptions_Order') && WC_Subscriptions_Order::order_contains_subscription($order_id)) {
         return $this->process_subscription($order_id, $retry);
         // Processing pre-order or standard ordre
     } else {
         return parent::process_payment($order_id, $retry);
     }
 }
 /**
  * Only displays the gateways which support subscriptions. 
  * 
  * @since 1.0
  */
 public static function get_available_payment_gateways($available_gateways)
 {
     if (WC_Subscriptions_Cart::cart_contains_subscription() || isset($_GET['order_id']) && WC_Subscriptions_Order::order_contains_subscription($_GET['order_id'])) {
         // || WC_Subscriptions_Order::order_contains_subscription( $order_id )
         foreach ($available_gateways as $gateway_id => $gateway) {
             if (!method_exists($gateway, 'supports') || $gateway->supports('subscriptions') !== true) {
                 unset($available_gateways[$gateway_id]);
             }
         }
     }
     return $available_gateways;
 }
 /**
  * Only display the gateways which support subscriptions if manual payments are not allowed.
  *
  * @since 1.0
  */
 public static function get_available_payment_gateways($available_gateways)
 {
     $accept_manual_payment = get_option(WC_Subscriptions_Admin::$option_prefix . '_accept_manual_renewals', 'no');
     if ('no' == $accept_manual_payment && (WC_Subscriptions_Cart::cart_contains_subscription() || isset($_GET['order_id']) && WC_Subscriptions_Order::order_contains_subscription($_GET['order_id']))) {
         foreach ($available_gateways as $gateway_id => $gateway) {
             if (!method_exists($gateway, 'supports') || $gateway->supports('subscriptions') !== true) {
                 unset($available_gateways[$gateway_id]);
             }
         }
     }
     return $available_gateways;
 }
 /**
  * Process the payment and return the result
  *
  * @access      public
  * @param       int $order_id
  * @return      array
  */
 public function process_payment($order_id)
 {
     if (WC_Subscriptions_Order::order_contains_subscription($order_id)) {
         if ($this->send_to_stripe($order_id)) {
             $this->order_complete();
             WC_Subscriptions_Manager::activate_subscriptions_for_order($this->order);
             $result = array('result' => 'success', 'redirect' => $this->get_return_url($this->order));
             return $result;
         } else {
             $this->payment_failed();
             // Add a generic error message if we don't currently have any others
             if (wc_notice_count('error') == 0) {
                 wc_add_notice(__('Transaction Error: Could not complete your subscription payment.', 'stripe-for-woocommerce'), 'error');
             }
         }
     } else {
         return parent::process_payment($order_id);
     }
 }
 /**
  * Process an initial subscription payment if the order contains a
  * subscription, otherwise use the parent::process_payment() method
  *
  * @since  1.4
  * @param int $order_id the order identifier
  * @return array
  */
 public function process_payment($order_id)
 {
     require_once 'class-wc-realex-api.php';
     // processing subscription (which means we are ineligible for 3DSecure for now)
     if (SV_WC_Plugin_Compatibility::is_wc_subscriptions_version_gte_2_0() ? wcs_order_contains_subscription($order_id) : WC_Subscriptions_Order::order_contains_subscription($order_id)) {
         $order = wc_get_order($order_id);
         // redirect to payment page for payment if 3D secure is enabled
         if ($this->get_threedsecure()->is_3dsecure_available() && !SV_WC_Helper::get_post('woocommerce_pay_page')) {
             // empty cart before redirecting from Checkout page
             WC()->cart->empty_cart();
             // redirect to payment page to continue payment
             return array('result' => 'success', 'redirect' => $order->get_checkout_payment_url(true));
         }
         $order->payment_total = SV_WC_Helper::number_format(SV_WC_Plugin_Compatibility::is_wc_subscriptions_version_gte_2_0() ? $order->get_total() : WC_Subscriptions_Order::get_total_initial_payment($order));
         // 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
         $result = $this->authorize($realex_client, $order);
         // subscription with initial payment, everything is now taken care of
         if (is_array($result)) {
             // for Subscriptions 2.0.x, save payment token to subscription object
             if (SV_WC_Plugin_Compatibility::is_wc_subscriptions_version_gte_2_0()) {
                 // a single order can contain multiple subscriptions
                 foreach (wcs_get_subscriptions_for_order($order->id) as $subscription) {
                     // payment token
                     update_post_meta($subscription->id, '_realex_cardref', get_post_meta($order->id, '_realex_cardref', true));
                 }
             }
             return $result;
         }
         // otherwise there was no initial payment, so we mark the order as complete, etc
         if ($order->payment_total == 0) {
             // mark order as having received payment
             $order->payment_complete();
             WC()->cart->empty_cart();
             return array('result' => 'success', 'redirect' => $this->get_return_url($order));
         }
     } else {
         // processing regular product
         return parent::process_payment($order_id);
     }
 }
 public function request_access_code($order, $method = 'ProcessPayment', $trx_type = 'Purchase')
 {
     $customer_ip = get_post_meta($order->id, '_customer_ip_address', true);
     // Check if order is for a subscription, if it is check for fee and charge that
     if (class_exists('WC_Subscriptions_Order') && WC_Subscriptions_Order::order_contains_subscription($order->id)) {
         if (0 == WC_Subscriptions_Order::get_total_initial_payment($order)) {
             $method = 'CreateTokenCustomer';
         } else {
             $method = 'TokenPayment';
         }
         $trx_type = 'Recurring';
         $order_total = WC_Subscriptions_Order::get_total_initial_payment($order) * 100;
     } else {
         $order_total = $order->get_total() * 100.0;
     }
     // set up request object
     $request = array('Method' => $method, 'TransactionType' => $trx_type, 'RedirectUrl' => str_replace('https:', 'http:', add_query_arg(array('wc-api' => 'WC_Gateway_EWAY', 'order_id' => $order->id, 'order_key' => $order->order_key, 'sig_key' => md5($order->order_key . 'WOO' . $order->id)), home_url('/'))), 'IPAddress' => $customer_ip, 'DeviceID' => '0b38ae7c3c5b466f8b234a8955f62bdd', 'PartnerID' => '0b38ae7c3c5b466f8b234a8955f62bdd', 'Payment' => array('TotalAmount' => $order_total, 'CurrencyCode' => get_woocommerce_currency(), 'InvoiceDescription' => apply_filters('woocommerce_eway_description', '', $order), 'InvoiceNumber' => ltrim($order->get_order_number(), _x('#', 'hash before order number', 'woocommerce')), 'InvoiceReference' => $order->id), 'Customer' => array('FirstName' => $order->billing_first_name, 'LastName' => $order->billing_last_name, 'CompanyName' => substr($order->billing_company, 0, 50), 'Street1' => $order->billing_address_1, 'Street2' => $order->billing_address_2, 'City' => $order->billing_city, 'State' => $order->billing_state, 'PostalCode' => $order->billing_postcode, 'Country' => $order->billing_country, 'Email' => $order->billing_email, 'Phone' => $order->billing_phone));
     // Add customer ID if logged in
     if (is_user_logged_in()) {
         $request['Options'][] = array('customerID' => get_current_user_id());
     }
     return $this->perform_request('/CreateAccessCode.json', json_encode($request));
 }
 public function set_expiration_reminder($user_id, $subs_key)
 {
     global $wpdb;
     $parts = explode('_', $subs_key);
     $order_id = $parts[0];
     $order = new WC_Order($order_id);
     if (WC_Subscriptions_Order::order_contains_subscription($order)) {
         // look for renewal emails
         $emails = $wpdb->get_results("SELECT * FROM {$wpdb->prefix}followup_emails WHERE `interval_type` = 'subs_before_expire' AND status = 1");
         if (count($emails) > 0) {
             $subs = WC_Subscriptions_Manager::get_subscription($subs_key);
             $expiry = WC_Subscriptions_Manager::get_subscription_expiration_date($subs_key, $user_id, 'timestamp');
             if (0 == $expiry) {
                 return;
             }
             foreach ($emails as $email) {
                 // add this email to the queue
                 $interval = (int) $email->interval_num;
                 $add = FUE::get_time_to_add($interval, $email->interval_duration);
                 $send_on = $expiry - $add;
                 $insert = array('user_id' => $user_id, 'send_on' => $send_on, 'email_id' => $email->id, 'product_id' => 0, 'order_id' => $order_id);
                 if ($subs_key) {
                     $insert['meta']['subs_key'] = $subs_key;
                 }
                 FUE::insert_email_order($insert);
             }
         }
     }
 }
Esempio n. 13
0
 /**
  * Registers the "Renewal Orders" meta box for the "Edit Order" page.
  */
 public static function add_related_orders_meta_box()
 {
     global $current_screen, $post_id;
     // Only display the meta box if an order relates to a subscription
     if ('shop_order' == $current_screen->id && (WC_Subscriptions_Renewal_Order::is_renewal($post_id, array('order_role' => 'child')) || WC_Subscriptions_Order::order_contains_subscription($post_id))) {
         add_meta_box('subscription_renewal_orders', __('Related Subscription Orders', WC_Subscriptions::$text_domain), __CLASS__ . '::related_orders_meta_box', 'shop_order');
     }
 }
 /**
  * Adjust renew membership URL for subscription-based memberships
  *
  * @since 1.0.0
  * @param string $url Renew membership URL
  * @param WC_Memberships_User_Membership $user_membership
  * @return string Modified renew URL
  */
 public function renew_membership_url($url, WC_Memberships_User_Membership $user_membership)
 {
     if ($this->has_membership_plan_subscription($user_membership->get_plan_id())) {
         // note that we must also check if order contains a subscription since users
         // can be manually-assigned to memberships and not have an associated subscription
         // 2.0 onwards
         if ($this->is_subscriptions_gte_2_0()) {
             if (wcs_order_contains_subscription($user_membership->get_order())) {
                 $url = wcs_get_users_resubscribe_link($this->get_user_membership_subscription_id($user_membership->get_id()));
             }
         } else {
             if (WC_Subscriptions_Order::order_contains_subscription($user_membership->get_order())) {
                 $subscription_key = $this->get_user_membership_subscription_key($user_membership->get_id());
                 $url = WC_Subscriptions_Renewal_Order::get_users_renewal_link($subscription_key);
             }
         }
     }
     return $url;
 }
 /**
  * Creates a new order for renewing a subscription product based on the details of a previous order.
  *
  * No trial periods or sign up fees are applied to the renewal order. However, if the order has failed
  * payments and the store manager has set failed payments to be added to renewal orders, then the
  * orders totals will be set to include the outstanding balance.
  *
  * If the $new_order_role flag is set to 'parent', then the renewal order will supersede the existing 
  * order. The existing order and subscription associated with it will be cancelled. A new order and
  * subscription will be created. 
  *
  * If the $new_order_role flag is 'child', the $original_order will remain the master order for the
  * subscription and the new order is just for accepting a recurring payment on the subscription.
  *
  * Renewal orders have the same meta data as the original order. If the renewal order is set to be a 'child'
  * then any subscription related meta data will not be stored on the new order. This is to keep subscription
  * meta data associated only with the one master order for the subscription.
  *
  * @param $order WC_Order | int The WC_Order object or ID of the order for which the a new order should be created.
  * @param $product_id string The ID of the subscription product in the order which needs to be added to the new order.
  * @param $new_order_role string A flag to indicate whether the new order should become the master order for the subscription. Accepts either 'parent' or 'child'. Defaults to 'parent' - replace the existing order.
  * @since 1.2
  */
 public static function generate_renewal_order($original_order, $product_id, $new_order_role = 'parent')
 {
     global $wpdb;
     if (!is_object($original_order)) {
         $original_order = new WC_Order($original_order);
     }
     if (!WC_Subscriptions_Order::order_contains_subscription($original_order) || !WC_Subscriptions_Order::is_item_a_subscription($original_order, $product_id)) {
         return false;
     }
     if (self::is_renewal($original_order, 'child')) {
         $original_order = self::get_parent_order($original_order);
     }
     $renewal_order_key = uniqid('order_');
     // Create the new order
     $renewal_order_data = array('post_type' => 'shop_order', 'post_title' => sprintf(__('Subscription Renewal Order – %s', WC_Subscriptions::$text_domain), strftime(_x('%b %d, %Y @ %I:%M %p', 'Order date parsed by strftime', WC_Subscriptions::$text_domain))), 'post_status' => 'publish', 'ping_status' => 'closed', 'post_excerpt' => $original_order->customer_note, 'post_author' => 1, 'post_password' => $renewal_order_key);
     if ('child' == $new_order_role) {
         $renewal_order_data['post_parent'] = $original_order->id;
     }
     $renewal_order_id = wp_insert_post($renewal_order_data);
     // Set the order as pending
     wp_set_object_terms($renewal_order_id, 'pending', 'shop_order_status');
     // Set a unique key for this order
     update_post_meta($renewal_order_id, '_order_key', $renewal_order_key);
     $order_meta_query = "SELECT `meta_key`, `meta_value` FROM {$wpdb->postmeta} WHERE `post_id` = {$original_order->id} AND `meta_key` NOT IN ('_paid_date', '_completed_date', '_order_key', '_edit_lock', '_original_order')";
     // Superseding existing order so don't carry over payment details
     if ('parent' == $new_order_role) {
         $order_meta_query .= " AND `meta_key` NOT IN ('_payment_method', '_payment_method_title')";
     } else {
         $order_meta_query .= " AND `meta_key` NOT LIKE '_order_recurring_%'";
     }
     // Allow extensions to add/remove order meta
     $order_meta_query = apply_filters('woocommerce_subscriptions_renewal_order_meta_query', $order_meta_query, $original_order->id, $renewal_order_id, $new_order_role);
     // Carry all the required meta from the old order over to the new order
     $order_meta = $wpdb->get_results($order_meta_query, 'ARRAY_A');
     $order_meta = apply_filters('woocommerce_subscriptions_renewal_order_meta', $order_meta, $original_order->id, $renewal_order_id, $new_order_role);
     foreach ($order_meta as $meta_item) {
         add_post_meta($renewal_order_id, $meta_item['meta_key'], maybe_unserialize($meta_item['meta_value']), true);
     }
     $outstanding_balance = WC_Subscriptions_Order::get_outstanding_balance($original_order, $product_id);
     // If there are outstanding payment amounts, add them to the order, otherwise set the order details to the values of the recurring totals
     if ($outstanding_balance > 0 && 'yes' == get_option(WC_Subscriptions_Admin::$option_prefix . '_add_outstanding_balance')) {
         $failed_payment_multiplier = WC_Subscriptions_Order::get_failed_payment_count($original_order, $product_id);
     } else {
         $failed_payment_multiplier = 1;
     }
     // Set order totals based on recurring totals from the original order
     $cart_discount = $failed_payment_multiplier * get_post_meta($original_order->id, '_order_recurring_discount_cart', true);
     $order_discount = $failed_payment_multiplier * get_post_meta($original_order->id, '_order_recurring_discount_total', true);
     $order_shipping_tax = $failed_payment_multiplier * get_post_meta($original_order->id, '_order_recurring_shipping_tax_total', true);
     $order_tax = $failed_payment_multiplier * get_post_meta($original_order->id, '_order_recurring_tax_total', true);
     $order_total = $failed_payment_multiplier * get_post_meta($original_order->id, '_order_recurring_total', true);
     update_post_meta($renewal_order_id, '_cart_discount', $cart_discount);
     update_post_meta($renewal_order_id, '_order_discount', $order_discount);
     update_post_meta($renewal_order_id, '_order_shipping_tax', $order_shipping_tax);
     update_post_meta($renewal_order_id, '_order_tax', $order_tax);
     update_post_meta($renewal_order_id, '_order_total', $order_total);
     // Set order taxes based on recurring taxes from the original order
     $recurring_order_taxes = get_post_meta($original_order->id, '_order_recurring_taxes', true);
     foreach ($recurring_order_taxes as $index => $recurring_order_tax) {
         if (isset($recurring_order_tax['cart_tax']) && $recurring_order_tax['cart_tax'] > 0) {
             $recurring_order_taxes[$index]['cart_tax'] = $failed_payment_multiplier * $recurring_order_tax['cart_tax'];
         } else {
             $recurring_order_taxes[$index]['cart_tax'] = 0;
         }
         if (isset($recurring_order_tax['shipping_tax']) && $recurring_order_tax['shipping_tax'] > 0) {
             $recurring_order_taxes[$index]['shipping_tax'] = $failed_payment_multiplier * $recurring_order_tax['shipping_tax'];
         } else {
             $recurring_order_taxes[$index]['shipping_tax'] = 0;
         }
     }
     update_post_meta($renewal_order_id, '_order_taxes', $recurring_order_taxes);
     // Set line totals to be recurring line totals and remove the subscription/recurring related item meta from each order item
     $order_items = WC_Subscriptions_Order::get_recurring_items($original_order);
     // Allow extensions to add/remove items or item meta
     $order_items = apply_filters('woocommerce_subscriptions_renewal_order_items', $order_items, $original_order->id, $renewal_order_id, $product_id, $new_order_role);
     foreach ($order_items as $item_index => $order_item) {
         $item_meta = new WC_Order_Item_Meta($order_item['item_meta']);
         // Remove recurring line items and set item totals based on recurring line totals
         foreach ($item_meta->meta as $meta_index => $meta_item) {
             switch ($meta_item['meta_name']) {
                 case '_recurring_line_total':
                     $order_items[$item_index]['line_total'] = $failed_payment_multiplier * $meta_item['meta_value'];
                 case '_recurring_line_tax':
                     $order_items[$item_index]['line_tax'] = $failed_payment_multiplier * $meta_item['meta_value'];
                 case '_recurring_line_subtotal':
                     $order_items[$item_index]['line_subtotal'] = $failed_payment_multiplier * $meta_item['meta_value'];
                 case '_recurring_line_subtotal_tax':
                     $order_items[$item_index]['line_subtotal_tax'] = $failed_payment_multiplier * $meta_item['meta_value'];
                 case '_recurring_line_total':
                 case '_recurring_line_tax':
                 case '_recurring_line_subtotal':
                 case '_recurring_line_subtotal_tax':
                 case '_recurring_line_subtotal_tax':
                 case '_subscription_recurring_amount':
                 case '_subscription_sign_up_fee':
                 case '_subscription_period':
                 case '_subscription_interval':
                 case '_subscription_length':
                 case '_subscription_trial_length':
                 case '_subscription_trial_period':
                     if ('child' == $new_order_role) {
                         unset($item_meta->meta[$meta_index]);
                     }
                     break;
             }
         }
         if ('child' == $new_order_role) {
             $order_items[$item_index]['name'] = sprintf(__('Renewal of "%s" purchased in Order %s', WC_Subscriptions::$text_domain), $order_item['name'], $original_order->get_order_number());
         }
         $order_items[$item_index]['item_meta'] = $item_meta->meta;
     }
     // Save the item meta on the new order
     update_post_meta($renewal_order_id, '_order_items', $order_items);
     // Keep a record of the original order's ID on the renewal order
     update_post_meta($renewal_order_id, '_original_order', $original_order->id, true);
     $renewal_order = new WC_Order($renewal_order_id);
     if ('parent' == $new_order_role) {
         WC_Subscriptions_Manager::process_subscriptions_on_checkout($renewal_order_id);
         $original_order->add_order_note(sprintf(__('Order superseded by Renewal Order %s.', WC_Subscriptions::$text_domain), $renewal_order->get_order_number()));
     }
     do_action('woocommerce_subscriptions_renewal_order_created', $renewal_order, $original_order, $product_id, $new_order_role);
     return apply_filters('woocommerce_subscriptions_renewal_order_id', $renewal_order_id, $original_order, $product_id, $new_order_role);
 }
 /**
  * When a new order is inserted, add subscriptions related order meta.
  *
  * @since 1.0
  */
 public static function add_order_meta($order_id, $posted)
 {
     global $woocommerce;
     if (!WC_Subscriptions_Cart::cart_contains_subscription_renewal('child') && WC_Subscriptions_Order::order_contains_subscription($order_id)) {
         // This works because the 'woocommerce_add_order_item_meta' runs before the 'woocommerce_checkout_update_order_meta' hook
         // Set the recurring totals so totals display correctly on order page
         update_post_meta($order_id, '_order_recurring_discount_cart', WC_Subscriptions_Cart::get_recurring_discount_cart());
         update_post_meta($order_id, '_order_recurring_discount_cart_tax', WC_Subscriptions_Cart::get_recurring_discount_cart_tax());
         update_post_meta($order_id, '_order_recurring_discount_total', WC_Subscriptions_Cart::get_recurring_discount_total());
         update_post_meta($order_id, '_order_recurring_shipping_tax_total', WC_Subscriptions_Cart::get_recurring_shipping_tax_total());
         update_post_meta($order_id, '_order_recurring_shipping_total', WC_Subscriptions_Cart::get_recurring_shipping_total());
         update_post_meta($order_id, '_order_recurring_tax_total', WC_Subscriptions_Cart::get_recurring_total_tax());
         update_post_meta($order_id, '_order_recurring_total', WC_Subscriptions_Cart::get_recurring_total());
         // Set the recurring payment method - it starts out the same as the original by may change later
         update_post_meta($order_id, '_recurring_payment_method', get_post_meta($order_id, '_payment_method', true));
         update_post_meta($order_id, '_recurring_payment_method_title', get_post_meta($order_id, '_payment_method_title', true));
         $order = new WC_Order($order_id);
         $order_fees = $order->get_fees();
         // the fee order items have already been set, we just need to to add the recurring total meta
         $cart_fees = $woocommerce->cart->get_fees();
         foreach ($order->get_fees() as $item_id => $order_fee) {
             // Find the matching fee in the cart
             foreach ($cart_fees as $fee_index => $cart_fee) {
                 if (sanitize_title($order_fee['name']) == $cart_fee->id) {
                     woocommerce_add_order_item_meta($item_id, '_recurring_line_total', wc_format_decimal($cart_fee->recurring_amount));
                     woocommerce_add_order_item_meta($item_id, '_recurring_line_tax', wc_format_decimal($cart_fee->recurring_tax));
                     unset($cart_fees[$fee_index]);
                     break;
                 }
             }
         }
         // Get recurring taxes into same format as _order_taxes
         $order_recurring_taxes = array();
         foreach (WC_Subscriptions_Cart::get_recurring_taxes() as $tax_key => $tax_amount) {
             $item_id = woocommerce_add_order_item($order_id, array('order_item_name' => WC_Tax::get_rate_code($tax_key), 'order_item_type' => 'recurring_tax'));
             if ($item_id) {
                 wc_add_order_item_meta($item_id, 'rate_id', $tax_key);
                 wc_add_order_item_meta($item_id, 'label', WC_Tax::get_rate_label($tax_key));
                 wc_add_order_item_meta($item_id, 'compound', absint(WC_Tax::is_compound($tax_key) ? 1 : 0));
                 wc_add_order_item_meta($item_id, 'tax_amount', wc_format_decimal(isset(WC()->cart->recurring_taxes[$tax_key]) ? WC()->cart->recurring_taxes[$tax_key] : 0));
                 wc_add_order_item_meta($item_id, 'shipping_tax_amount', wc_format_decimal(isset(WC()->cart->recurring_shipping_taxes[$tax_key]) ? WC()->cart->recurring_shipping_taxes[$tax_key] : 0));
             }
         }
         $payment_gateways = $woocommerce->payment_gateways->payment_gateways();
         if ('yes' == get_option(WC_Subscriptions_Admin::$option_prefix . '_turn_off_automatic_payments', 'no')) {
             update_post_meta($order_id, '_wcs_requires_manual_renewal', 'true');
         } elseif (isset($payment_gateways[$posted['payment_method']]) && !$payment_gateways[$posted['payment_method']]->supports('subscriptions')) {
             update_post_meta($order_id, '_wcs_requires_manual_renewal', 'true');
         }
         $cart_item = WC_Subscriptions_Cart::cart_contains_subscription_renewal();
         if (isset($cart_item['subscription_renewal']) && 'parent' == $cart_item['subscription_renewal']['role']) {
             update_post_meta($order_id, '_original_order', $cart_item['subscription_renewal']['original_order']);
         }
         // WC 2.1+
         if (!WC_Subscriptions::is_woocommerce_pre('2.1')) {
             // Recurring coupons
             if ($applied_coupons = $woocommerce->cart->get_coupons()) {
                 foreach ($applied_coupons as $code => $coupon) {
                     if (!isset($woocommerce->cart->recurring_coupon_discount_amounts[$code])) {
                         continue;
                     }
                     $item_id = woocommerce_add_order_item($order_id, array('order_item_name' => $code, 'order_item_type' => 'recurring_coupon'));
                     // Add line item meta
                     if ($item_id) {
                         woocommerce_add_order_item_meta($item_id, 'discount_amount', isset($woocommerce->cart->recurring_coupon_discount_amounts[$code]) ? $woocommerce->cart->recurring_coupon_discount_amounts[$code] : 0);
                     }
                 }
             }
             // Add recurring shipping order items
             if (WC_Subscriptions_Cart::cart_contains_subscriptions_needing_shipping()) {
                 $packages = $woocommerce->shipping->get_packages();
                 $checkout = $woocommerce->checkout();
                 foreach ($packages as $i => $package) {
                     if (isset($package['rates'][$checkout->shipping_methods[$i]])) {
                         $method = $package['rates'][$checkout->shipping_methods[$i]];
                         $item_id = woocommerce_add_order_item($order_id, array('order_item_name' => $method->label, 'order_item_type' => 'recurring_shipping'));
                         if ($item_id) {
                             woocommerce_add_order_item_meta($item_id, 'method_id', $method->id);
                             woocommerce_add_order_item_meta($item_id, 'cost', WC_Subscriptions::format_total($method->cost));
                             woocommerce_add_order_item_meta($item_id, 'taxes', array_map('wc_format_decimal', $method->taxes));
                             do_action('woocommerce_subscriptions_add_recurring_shipping_order_item', $order_id, $item_id, $i);
                         }
                     }
                 }
             }
             // Remove shipping on original order if it was added but is not required
             if (!WC_Subscriptions_Cart::charge_shipping_up_front()) {
                 foreach ($order->get_shipping_methods() as $order_item_id => $shipping_method) {
                     woocommerce_update_order_item_meta($order_item_id, 'cost', WC_Subscriptions::format_total(0));
                 }
             }
         } else {
             update_post_meta($order_id, '_recurring_shipping_method', get_post_meta($order_id, '_shipping_method', true), true);
             update_post_meta($order_id, '_recurring_shipping_method_title', get_post_meta($order_id, '_shipping_method_title', true), true);
         }
     }
 }
 /**
  * Override the default PayPal standard args in WooCommerce for subscription purchases.
  *
  * Based on the HTML Variables documented here: https://developer.paypal.com/webapps/developer/docs/classic/paypal-payments-standard/integration-guide/Appx_websitestandard_htmlvariables/#id08A6HI00JQU
  *
  * @since 1.0
  */
 public static function paypal_standard_subscription_args($paypal_args)
 {
     extract(self::get_order_id_and_key($paypal_args));
     if (WC_Subscriptions_Order::order_contains_subscription($order_id) && 'yes' !== get_option(WC_Subscriptions_Admin::$option_prefix . '_turn_off_automatic_payments', 'no')) {
         $order = new WC_Order($order_id);
         $order_items = $order->get_items();
         // Only one subscription allowed in the cart when PayPal Standard is active
         $product = $order->get_product_from_item(array_pop($order_items));
         // It's a subscription
         $paypal_args['cmd'] = '_xclick-subscriptions';
         if (count($order->get_items()) > 1) {
             foreach ($order->get_items() as $item) {
                 if ($item['qty'] > 1) {
                     $item_names[] = $item['qty'] . ' x ' . $item['name'];
                 } else {
                     if ($item['qty'] > 0) {
                         $item_names[] = $item['name'];
                     }
                 }
             }
             $paypal_args['item_name'] = sprintf(__('Order %s', WC_Subscriptions::$text_domain), $order->get_order_number());
         } else {
             $paypal_args['item_name'] = $product->get_title();
         }
         $unconverted_periods = array('billing_period' => WC_Subscriptions_Order::get_subscription_period($order), 'trial_period' => WC_Subscriptions_Order::get_subscription_trial_period($order));
         $converted_periods = array();
         // Convert period strings into PayPay's format
         foreach ($unconverted_periods as $key => $period) {
             switch (strtolower($period)) {
                 case 'day':
                     $converted_periods[$key] = 'D';
                     break;
                 case 'week':
                     $converted_periods[$key] = 'W';
                     break;
                 case 'year':
                     $converted_periods[$key] = 'Y';
                     break;
                 case 'month':
                 default:
                     $converted_periods[$key] = 'M';
                     break;
             }
         }
         $price_per_period = WC_Subscriptions_Order::get_recurring_total($order);
         $subscription_interval = WC_Subscriptions_Order::get_subscription_interval($order);
         $subscription_length = WC_Subscriptions_Order::get_subscription_length($order);
         $subscription_installments = $subscription_length / $subscription_interval;
         $is_payment_change = WC_Subscriptions_Change_Payment_Gateway::$is_request_to_change_payment;
         $is_switch_order = WC_Subscriptions_Switcher::order_contains_subscription_switch($order->id);
         $sign_up_fee = $is_payment_change ? 0 : WC_Subscriptions_Order::get_sign_up_fee($order);
         $initial_payment = $is_payment_change ? 0 : WC_Subscriptions_Order::get_total_initial_payment($order);
         if ($is_payment_change) {
             // Add a nonce to the order ID to avoid "This invoice has already been paid" error when changing payment method to PayPal when it was previously PayPal
             $paypal_args['invoice'] = $paypal_args['invoice'] . '-wcscpm-' . wp_create_nonce();
             // Set a flag on the order if changing from PayPal *to* PayPal to prevent incorrectly cancelling the subscription
             if ('paypal' == $order->recurring_payment_method) {
                 add_post_meta($order_id, '_wcs_changing_payment_from_paypal_to_paypal', 'true', true);
             }
         }
         // If we're changing the payment date or switching subs, we need to set the trial period to the next payment date & installments to be the number of installments left
         if ($is_payment_change || $is_switch_order) {
             $subscription_key = WC_Subscriptions_Manager::get_subscription_key($order_id, $product->id);
             // Give a free trial until the next payment date
             $next_payment_timestamp = WC_Subscriptions_Manager::get_next_payment_date($subscription_key, $order->user_id, 'timestamp');
             // When the subscription is on hold
             if ($next_payment_timestamp != false) {
                 $trial_until = self::calculate_trial_periods_until($next_payment_timestamp);
                 $subscription_trial_length = $trial_until['first_trial_length'];
                 $converted_periods['trial_period'] = $trial_until['first_trial_period'];
                 $second_trial_length = $trial_until['second_trial_length'];
                 $second_trial_period = $trial_until['second_trial_period'];
             }
             // If is a payment change, we need to account for completed payments on the number of installments owing
             if ($is_payment_change && $subscription_length > 0) {
                 $subscription_installments -= WC_Subscriptions_Manager::get_subscriptions_completed_payment_count($subscription_key);
             }
         } else {
             $subscription_trial_length = WC_Subscriptions_Order::get_subscription_trial_length($order);
         }
         if ($subscription_trial_length > 0) {
             // Specify a free trial period
             if ($is_switch_order) {
                 $paypal_args['a1'] = $initial_payment > 0 ? $initial_payment : 0;
             } else {
                 $paypal_args['a1'] = $sign_up_fee > 0 ? $sign_up_fee : 0;
             }
             // Maybe add the sign up fee to the free trial period
             // Trial period length
             $paypal_args['p1'] = $subscription_trial_length;
             // Trial period
             $paypal_args['t1'] = $converted_periods['trial_period'];
             // We need to use a second trial period before we have more than 90 days until the next payment
             if (WC_Subscriptions_Change_Payment_Gateway::$is_request_to_change_payment && $second_trial_length > 0) {
                 $paypal_args['a2'] = 0;
                 $paypal_args['p2'] = $second_trial_length;
                 $paypal_args['t2'] = $second_trial_period;
             }
         } elseif ($sign_up_fee > 0 || $initial_payment !== $price_per_period) {
             // No trial period, so charge sign up fee and per period price for the first period
             if ($subscription_installments == 1) {
                 $param_number = 3;
             } else {
                 $param_number = 1;
             }
             $paypal_args['a' . $param_number] = $initial_payment;
             // Sign Up interval
             $paypal_args['p' . $param_number] = $subscription_interval;
             // Sign Up unit of duration
             $paypal_args['t' . $param_number] = $converted_periods['billing_period'];
         }
         // We have a recurring payment
         if (!isset($param_number) || $param_number == 1) {
             // Subscription price
             $paypal_args['a3'] = $price_per_period;
             // Subscription duration
             $paypal_args['p3'] = $subscription_interval;
             // Subscription period
             $paypal_args['t3'] = $converted_periods['billing_period'];
         }
         // Recurring payments
         if ($subscription_installments == 1 || $sign_up_fee > 0 && $subscription_trial_length == 0 && $subscription_installments == 2) {
             // Non-recurring payments
             $paypal_args['src'] = 0;
         } else {
             $paypal_args['src'] = 1;
             if ($subscription_installments > 0) {
                 if ($sign_up_fee > 0 && $subscription_trial_length == 0) {
                     // An initial period is being used to charge a sign-up fee
                     $subscription_installments--;
                 }
                 $paypal_args['srt'] = $subscription_installments;
             }
         }
         // Don't reattempt failed payments, instead let Subscriptions handle the failed payment
         $paypal_args['sra'] = 0;
         // Force return URL so that order description & instructions display
         $paypal_args['rm'] = 2;
     }
     return $paypal_args;
 }
 /**
  * Adds subscriptions data to the order object
  *
  * @since 4.1.0
  * @see SV_WC_Payment_Gateway::get_order()
  * @param WC_Order $order the order
  * @return WC_Order the orders
  */
 public function get_order_1_5($order)
 {
     // bail if the order doesn't contain a subscription
     if (!WC_Subscriptions_Order::order_contains_subscription($order->id)) {
         return $order;
     }
     // subscriptions total, ensuring that we have a decimal point, even if it's 1.00
     $order->payment_total = SV_WC_Helper::number_format(WC_Subscriptions_Order::get_total_initial_payment($order));
     // load any required members that we might not have
     if (!isset($order->payment->token) || !$order->payment->token) {
         $order->payment->token = $this->get_gateway()->get_order_meta($order->id, 'payment_token');
     }
     if (!isset($order->customer_id) || !$order->customer_id) {
         $order->customer_id = $this->get_gateway()->get_order_meta($order->id, 'customer_id');
     }
     // ensure the payment token is still valid
     if (!$this->get_gateway()->has_payment_token($order->get_user_id(), $order->payment->token)) {
         $order->payment->token = null;
     } else {
         // get the token object
         $token = $this->get_gateway()->get_payment_token($order->get_user_id(), $order->payment->token);
         if (!isset($order->payment->account_number) || !$order->payment->account_number) {
             $order->payment->account_number = $token->get_last_four();
         }
         if ($this->get_gateway()->is_credit_card_gateway()) {
             // credit card token
             if (!isset($order->payment->card_type) || !$order->payment->card_type) {
                 $order->payment->card_type = $token->get_card_type();
             }
             if (!isset($order->payment->exp_month) || !$order->payment->exp_month) {
                 $order->payment->exp_month = $token->get_exp_month();
             }
             if (!isset($order->payment->exp_year) || !$order->payment->exp_year) {
                 $order->payment->exp_year = $token->get_exp_year();
             }
         } elseif ($this->get_gateway()->is_echeck_gateway()) {
             // check token
             if (!isset($order->payment->account_type) || !$order->payment->account_type) {
                 $order->payment->account_type = $token->get_account_type();
             }
         }
     }
     return $order;
 }
 /**
  * Override the default PayPal standard args in WooCommerce for subscription purchases.
  *
  * @since 1.0
  */
 public static function paypal_standard_subscription_args($paypal_args)
 {
     extract(self::get_order_id_and_key($paypal_args));
     if (WC_Subscriptions_Order::order_contains_subscription($order_id)) {
         $order = new WC_Order($order_id);
         $order_items = $order->get_items();
         // Only one subscription allowed in the cart when PayPal Standard is active
         $product = $order->get_product_from_item($order_items[0]);
         // It's a subscription
         $paypal_args['cmd'] = '_xclick-subscriptions';
         if (count($order->get_items()) > 1) {
             foreach ($order->get_items() as $item) {
                 if ($item['qty'] > 1) {
                     $item_names[] = $item['qty'] . ' x ' . $item['name'];
                 } else {
                     if ($item['qty'] > 0) {
                         $item_names[] = $item['name'];
                     }
                 }
             }
             $paypal_args['item_name'] = sprintf(__('Order %s', WC_Subscriptions::$text_domain), $order->get_order_number());
         } else {
             $paypal_args['item_name'] = $product->get_title();
         }
         // Subscription unit of duration
         switch (strtolower(WC_Subscriptions_Order::get_subscription_period($order))) {
             case 'day':
                 $subscription_period = 'D';
                 break;
             case 'week':
                 $subscription_period = 'W';
                 break;
             case 'year':
                 $subscription_period = 'Y';
                 break;
             case 'month':
             default:
                 $subscription_period = 'M';
                 break;
         }
         $sign_up_fee = WC_Subscriptions_Order::get_sign_up_fee($order);
         $price_per_period = WC_Subscriptions_Order::get_price_per_period($order);
         $subscription_interval = WC_Subscriptions_Order::get_subscription_interval($order);
         $subscription_length = WC_Subscriptions_Order::get_subscription_length($order);
         $subscription_trial_length = WC_Subscriptions_Order::get_subscription_trial_length($order);
         if ($subscription_trial_length > 0) {
             // Specify a free trial period
             $paypal_args['a1'] = $sign_up_fee > 0 ? $sign_up_fee : 0;
             // Add the sign up fee to the free trial period
             // Sign Up interval
             $paypal_args['p1'] = $subscription_trial_length;
             // Sign Up unit of duration
             $paypal_args['t1'] = $subscription_period;
         } elseif ($sign_up_fee > 0) {
             // No trial period, so charge sign up fee and per period price for the first period
             if ($subscription_length == 1) {
                 $param_number = 3;
             } else {
                 $param_number = 1;
             }
             $paypal_args['a' . $param_number] = $price_per_period + $sign_up_fee;
             // Sign Up interval
             $paypal_args['p' . $param_number] = $subscription_interval;
             // Sign Up unit of duration
             $paypal_args['t' . $param_number] = $subscription_period;
         }
         // We have a recurring payment
         if (!isset($param_number) || $param_number == 1) {
             // Subscription price
             $paypal_args['a3'] = $price_per_period;
             // Subscription duration
             $paypal_args['p3'] = $subscription_interval;
             // Subscription period
             $paypal_args['t3'] = $subscription_period;
         }
         // Recurring payments
         if ($subscription_length == 1 || $sign_up_fee > 0 && $subscription_trial_length == 0 && $subscription_length == 2) {
             // Non-recurring payments
             $paypal_args['src'] = 0;
         } else {
             $paypal_args['src'] = 1;
             if ($subscription_length > 0) {
                 if ($sign_up_fee > 0 && $subscription_trial_length == 0) {
                     // An initial period is being used to charge a sign-up fee
                     $subscription_length--;
                 }
                 $paypal_args['srt'] = $subscription_length / $subscription_interval;
             }
         }
         // Force return URL so that order description & instructions display
         $paypal_args['rm'] = 2;
     }
     return $paypal_args;
 }
Esempio n. 20
0
 /**
  * Outputs the contents of the "Renewal Orders" meta box.
  *
  * @param object $post Current post data.
  */
 public static function renewal_orders_meta_box($post)
 {
     $order = new WC_Order(absint($post->ID));
     if (WC_Subscriptions_Renewal_Order::is_renewal($order, array('order_role' => 'child'))) {
         $parent_id = WC_Subscriptions_Renewal_Order::get_parent_order_id($order);
     } else {
         if (WC_Subscriptions_Order::order_contains_subscription($order)) {
             $parent_id = $post->ID;
         }
     }
     //Find any renewal orders associated with this order.
     $items = get_posts(array('post_type' => $post->post_type, 'post_parent' => $parent_id, 'numberposts' => -1));
     if (WC_Subscriptions_Renewal_Order::is_renewal($order, array('order_role' => 'child'))) {
         $parent_order = new WC_Order($parent_id);
         printf('<p>%1$s <a href="%2$s">%3$s</a></p>', __('Initial Order:', WC_Subscriptions::$text_domain), get_edit_post_link($parent_id), $parent_order->get_order_number());
     }
     if (empty($items)) {
         printf(' <p class="renewal-subtitle">%s</p>', __('No renewal payments yet.', WC_Subscriptions::$text_domain));
     } else {
         printf('<p class="renewal-subtitle">%s</p>', __('Renewal Orders:', WC_Subscriptions::$text_domain));
         echo '<ul class="renewal-orders">';
         foreach ($items as $item) {
             $renewal_order = new WC_Order($item->ID);
             if ($item->ID == $post->ID) {
                 printf('<li><strong>%s</strong></li>', $renewal_order->get_order_number());
             } else {
                 printf('<li><a href="%1$s">%2$s</a></li>', get_edit_post_link($item->ID), $renewal_order->get_order_number());
             }
         }
         echo '</ul>';
     }
 }
        /**
         * Generate the epay button link
         **/
        public function generate_epay_form($order_id)
        {
            global $woocommerce;
            $order = new WC_Order($order_id);
            $epay_args = array('merchantnumber' => $this->merchant, 'windowid' => $this->windowid, 'windowstate' => $this->windowstate, 'instantcallback' => 1, 'instantcapture' => $this->yesnotoint($this->instantcapture), 'group' => $this->group, 'mailreceipt' => $this->authmail, 'ownreceipt' => $this->yesnotoint($this->ownreceipt), 'amount' => class_exists('WC_Subscriptions_Order') ? WC_Subscriptions_Order::order_contains_subscription($order) ? WC_Subscriptions_Order::get_total_initial_payment($order) * 100 : $order->order_total * 100 : $order->order_total * 100, 'orderid' => str_replace(_x('#', 'hash before order number', 'woocommerce'), "", $order->get_order_number()), 'currency' => get_woocommerce_currency(), 'callbackurl' => $this->fix_url(add_query_arg('wooorderid', $order_id, add_query_arg('wc-api', 'WC_Gateway_EPayDk', $this->get_return_url($order)))), 'accepturl' => $this->fix_url($this->get_return_url($order)), 'cancelurl' => $this->fix_url($order->get_cancel_order_url()), 'language' => $this->get_language_code(get_locale()), 'subscription' => class_exists('WC_Subscriptions_Order') ? WC_Subscriptions_Order::order_contains_subscription($order) ? 1 : 0 : 0);
            if ($this->settings["enableinvoice"] == "yes") {
                $invoice = array();
                $invoice["customer"] = array("emailaddress" => $order->billing_email, "firstname" => $this->jsonValueRemoveSpecialCharacters($order->billing_first_name), "lastname" => $this->jsonValueRemoveSpecialCharacters($order->billing_last_name), "address" => $this->jsonValueRemoveSpecialCharacters($order->billing_address_1 . ($order->billing_address_2 != null) ? ' ' . $order->billing_address_2 : ''), "zip" => $order->billing_postcode, "city" => $order->billing_city, "country" => $order->billing_country);
                $invoice["shippingaddress"] = array("firstname" => $this->jsonValueRemoveSpecialCharacters($order->shipping_first_name), "lastname" => $this->jsonValueRemoveSpecialCharacters($order->shipping_last_name), "address" => $this->jsonValueRemoveSpecialCharacters($order->shipping_address_1 . ($order->shipping_address_2 != null) ? ' ' . $order->shipping_address_2 : ''), "zip" => $order->shipping_postcode, "city" => $order->shipping_city, "country" => $order->shipping_country);
                $items = $order->get_items();
                foreach ($items as $item) {
                    $invoice["lines"][] = array("id" => $item["product_id"], "description" => $this->jsonValueRemoveSpecialCharacters($item["name"]), "quantity" => $item["qty"], "price" => round($item["line_subtotal"] / $item["qty"] * 100), "vat" => round($item["line_subtotal_tax"] / $item["line_subtotal"] * 100));
                }
                $discount = $order->get_total_discount();
                if ($discount > 0) {
                    $invoice["lines"][] = array("id" => "discount", "description" => "discount", "quantity" => 1, "price" => -round($discount * 100), "vat" => round($order->get_total_tax() / ($order->get_total() - $order->get_total_tax()) * 100));
                }
                $shipping = $order->get_total_shipping();
                if ($shipping > 0) {
                    $invoice["lines"][] = array("id" => "shipping", "description" => "shipping", "quantity" => 1, "price" => round($shipping * 100), "vat" => round($order->get_shipping_tax() / $shipping * 100));
                }
                $epay_args['invoice'] = $this->jsonRemoveUnicodeSequences($invoice);
            }
            if (strlen($this->md5key) > 0) {
                $hash = "";
                foreach ($epay_args as $key => $value) {
                    $hash .= $value;
                }
                $epay_args["hash"] = md5($hash . $this->md5key);
            }
            $epay_args_array = array();
            foreach ($epay_args as $key => $value) {
                $epay_args_array[] = '\'' . esc_attr($key) . '\': \'' . $value . '\'';
            }
            return '<script type="text/javascript">
			function PaymentWindowReady() {
				paymentwindow = new PaymentWindow({					
					' . implode(',', $epay_args_array) . '
				});
				paymentwindow.open();
			}
			</script>
			<script type="text/javascript" src="https://ssl.ditonlinebetalingssystem.dk/integration/ewindow/paymentwindow.js" charset="UTF-8"></script>
			<a class="button" onclick="javascript: paymentwindow.open();" id="submit_epay_payment_form" />' . __('Pay via ePay', 'woocommerce-gateway-epay-dk') . '</a>
			<a class="button cancel" href="' . esc_url($order->get_cancel_order_url()) . '">' . __('Cancel order &amp; restore cart', 'woocommerce-gateway-epay-dk') . '</a>';
        }
 /**
  * Override the default PayPal standard args in WooCommerce for subscription purchases when
  * automatic payments are enabled and when the recurring order totals is over $0.00 (because
  * PayPal doesn't support subscriptions with a $0 recurring total, we need to circumvent it and
  * manage it entirely ourselves.)
  *
  * Based on the HTML Variables documented here: https://developer.paypal.com/webapps/developer/docs/classic/paypal-payments-standard/integration-guide/Appx_websitestandard_htmlvariables/#id08A6HI00JQU
  *
  * @since 1.0
  */
 public static function paypal_standard_subscription_args($paypal_args)
 {
     extract(self::get_order_id_and_key($paypal_args));
     $order = new WC_Order($order_id);
     if ($cart_item = WC_Subscriptions_Cart::cart_contains_failed_renewal_order_payment() || false !== WC_Subscriptions_Renewal_Order::get_failed_order_replaced_by($order_id)) {
         $renewal_order = $order;
         $order = WC_Subscriptions_Renewal_Order::get_parent_order($renewal_order);
         $order_contains_failed_renewal = true;
     } else {
         $order_contains_failed_renewal = false;
     }
     if ($order_contains_failed_renewal || WC_Subscriptions_Order::order_contains_subscription($order) && WC_Subscriptions_Order::get_recurring_total($order) > 0 && 'yes' !== get_option(WC_Subscriptions_Admin::$option_prefix . '_turn_off_automatic_payments', 'no')) {
         // Only one subscription allowed in the cart when PayPal Standard is active
         $product = $order->get_product_from_item(array_pop(WC_Subscriptions_Order::get_recurring_items($order)));
         // It's a subscription
         $paypal_args['cmd'] = '_xclick-subscriptions';
         if (count($order->get_items()) > 1) {
             foreach ($order->get_items() as $item) {
                 if ($item['qty'] > 1) {
                     $item_names[] = $item['qty'] . ' x ' . self::paypal_item_name($item['name']);
                 } elseif ($item['qty'] > 0) {
                     $item_names[] = self::paypal_item_name($item['name']);
                 }
             }
             $paypal_args['item_name'] = self::paypal_item_name(sprintf(__('Order %s', 'woocommerce-subscriptions'), $order->get_order_number() . " - " . implode(', ', $item_names)));
         } else {
             $paypal_args['item_name'] = self::paypal_item_name($product->get_title());
         }
         $unconverted_periods = array('billing_period' => WC_Subscriptions_Order::get_subscription_period($order), 'trial_period' => WC_Subscriptions_Order::get_subscription_trial_period($order));
         $converted_periods = array();
         // Convert period strings into PayPay's format
         foreach ($unconverted_periods as $key => $period) {
             switch (strtolower($period)) {
                 case 'day':
                     $converted_periods[$key] = 'D';
                     break;
                 case 'week':
                     $converted_periods[$key] = 'W';
                     break;
                 case 'year':
                     $converted_periods[$key] = 'Y';
                     break;
                 case 'month':
                 default:
                     $converted_periods[$key] = 'M';
                     break;
             }
         }
         $price_per_period = WC_Subscriptions_Order::get_recurring_total($order);
         $subscription_interval = WC_Subscriptions_Order::get_subscription_interval($order);
         $subscription_length = WC_Subscriptions_Order::get_subscription_length($order);
         $subscription_installments = $subscription_length / $subscription_interval;
         $is_payment_change = WC_Subscriptions_Change_Payment_Gateway::$is_request_to_change_payment;
         $is_switch_order = WC_Subscriptions_Switcher::order_contains_subscription_switch($order->id);
         $is_synced_subscription = WC_Subscriptions_Synchroniser::order_contains_synced_subscription($order->id);
         $sign_up_fee = $is_payment_change ? 0 : WC_Subscriptions_Order::get_sign_up_fee($order);
         $initial_payment = $is_payment_change ? 0 : WC_Subscriptions_Order::get_total_initial_payment($order);
         if ($is_payment_change) {
             // Add a nonce to the order ID to avoid "This invoice has already been paid" error when changing payment method to PayPal when it was previously PayPal
             $paypal_args['invoice'] = $paypal_args['invoice'] . '-wcscpm-' . wp_create_nonce();
         } elseif ($order_contains_failed_renewal) {
             // Set the invoice details to the original order's invoice but also append a special string and this renewal orders ID so that we can match it up as a failed renewal order payment later
             $paypal_args['invoice'] = self::$invoice_prefix . ltrim($order->get_order_number(), '#') . '-wcsfrp-' . $renewal_order->id;
             $paypal_args['custom'] = serialize(array($order->id, $order->order_key));
         }
         if ($order_contains_failed_renewal) {
             $sign_up_fee = 0;
             $initial_payment = $renewal_order->get_total();
             // Initial payment can be left in case the customer is purchased other products with the payment
             $subscription_trial_length = 0;
             $subscription_installments = max($subscription_installments - WC_Subscriptions_Manager::get_subscriptions_completed_payment_count(WC_Subscriptions_Manager::get_subscription_key($order_id, $product->id)), 0);
             // If we're changing the payment date or switching subs, we need to set the trial period to the next payment date & installments to be the number of installments left
         } elseif ($is_payment_change || $is_switch_order || $is_synced_subscription) {
             $subscription_key = WC_Subscriptions_Manager::get_subscription_key($order_id, $product->id);
             // Give a free trial until the next payment date
             if ($is_switch_order) {
                 $next_payment_timestamp = get_post_meta($order->id, '_switched_subscription_first_payment_timestamp', true);
             } elseif ($is_synced_subscription) {
                 $next_payment_timestamp = WC_Subscriptions_Synchroniser::calculate_first_payment_date($product, 'timestamp');
             } else {
                 $next_payment_timestamp = WC_Subscriptions_Manager::get_next_payment_date($subscription_key, $order->user_id, 'timestamp');
             }
             // When the subscription is on hold
             if ($next_payment_timestamp != false && !empty($next_payment_timestamp)) {
                 $trial_until = self::calculate_trial_periods_until($next_payment_timestamp);
                 $subscription_trial_length = $trial_until['first_trial_length'];
                 $converted_periods['trial_period'] = $trial_until['first_trial_period'];
                 $second_trial_length = $trial_until['second_trial_length'];
                 $second_trial_period = $trial_until['second_trial_period'];
             } else {
                 $subscription_trial_length = 0;
             }
             // If is a payment change, we need to account for completed payments on the number of installments owing
             if ($is_payment_change && $subscription_length > 0) {
                 $subscription_installments -= WC_Subscriptions_Manager::get_subscriptions_completed_payment_count($subscription_key);
             }
         } else {
             $subscription_trial_length = WC_Subscriptions_Order::get_subscription_trial_length($order);
         }
         if ($subscription_trial_length > 0) {
             // Specify a free trial period
             if ($is_switch_order || $is_synced_subscription || $initial_payment != $sign_up_fee) {
                 $paypal_args['a1'] = $initial_payment > 0 ? $initial_payment : 0;
             } else {
                 $paypal_args['a1'] = $sign_up_fee > 0 ? $sign_up_fee : 0;
                 // Maybe add the sign up fee to the free trial period
             }
             // Trial period length
             $paypal_args['p1'] = $subscription_trial_length;
             // Trial period
             $paypal_args['t1'] = $converted_periods['trial_period'];
             // We need to use a second trial period before we have more than 90 days until the next payment
             if (isset($second_trial_length) && $second_trial_length > 0) {
                 $paypal_args['a2'] = 0.01;
                 // Alas, although it's undocumented, PayPal appears to require a non-zero value in order to allow a second trial period
                 $paypal_args['p2'] = $second_trial_length;
                 $paypal_args['t2'] = $second_trial_period;
             }
         } elseif ($sign_up_fee > 0 || $initial_payment != $price_per_period) {
             // No trial period, so charge sign up fee and per period price for the first period
             if ($subscription_installments == 1) {
                 $param_number = 3;
             } else {
                 $param_number = 1;
             }
             $paypal_args['a' . $param_number] = $initial_payment;
             // Sign Up interval
             $paypal_args['p' . $param_number] = $subscription_interval;
             // Sign Up unit of duration
             $paypal_args['t' . $param_number] = $converted_periods['billing_period'];
         }
         // We have a recurring payment
         if (!isset($param_number) || $param_number == 1) {
             // Subscription price
             $paypal_args['a3'] = $price_per_period;
             // Subscription duration
             $paypal_args['p3'] = $subscription_interval;
             // Subscription period
             $paypal_args['t3'] = $converted_periods['billing_period'];
         }
         // Recurring payments
         if ($subscription_installments == 1 || $sign_up_fee > 0 && $subscription_trial_length == 0 && $subscription_installments == 2) {
             // Non-recurring payments
             $paypal_args['src'] = 0;
         } else {
             $paypal_args['src'] = 1;
             if ($subscription_installments > 0) {
                 if ($sign_up_fee > 0 && $subscription_trial_length == 0) {
                     // An initial period is being used to charge a sign-up fee
                     $subscription_installments--;
                 }
                 $paypal_args['srt'] = $subscription_installments;
             }
         }
         // Don't reattempt failed payments, instead let Subscriptions handle the failed payment
         $paypal_args['sra'] = 0;
         // Force return URL so that order description & instructions display
         $paypal_args['rm'] = 2;
     }
     return $paypal_args;
 }
 /**
  * Process the payment and return the result
  **/
 function process_payment($order_id)
 {
     global $woocommerce;
     $order = new WC_Order($order_id);
     if (class_exists("WC_Subscriptions_Order") && WC_Subscriptions_Order::order_contains_subscription($order)) {
         // Charge sign up fee + first period here..
         // Periodic charging should happen via scheduled_subscription_payment_fatzebra
         $amount = (int) (WC_Subscriptions_Order::get_total_initial_payment($order) * 100);
     } else {
         $amount = (int) ($order->order_total * 100);
     }
     $page_url = $this->parent_settings["sandbox_mode"] == "yes" ? $this->sandbox_paynow_url : $this->live_paynow_url;
     $_SESSION['masterpass_order_id'] = $order_id;
     $username = $this->parent_settings["username"];
     $currency = $order->get_order_currency();
     $reference = (string) $order_id;
     $return_args = array('wc-api' => 'WC_FatZebra_MasterPass', "echo[order_id]" => $order_id);
     if ($amount === 0) {
         $return_args["echo[tokenize]"] = true;
     }
     $return_path = str_replace('https:', 'http:', add_query_arg($return_args, home_url('/')));
     $verification_string = implode(":", array($reference, $amount, $currency, $return_path));
     $verification_value = hash_hmac("md5", $verification_string, $this->settings["shared_secret"]);
     $redirect = "{$page_url}/{$username}/{$reference}/{$currency}/{$amount}/{$verification_value}?masterpass=true&iframe=true&return_path=" . urlencode($return_path);
     if ($amount === 0) {
         $redirect .= "&tokenize_only=true";
     }
     $result = array('result' => 'success', 'redirect' => $redirect);
     return $result;
 }
 /**
  * Adds a renewal orders section to the Related Orders meta box displayed on subscription orders.
  *
  * @since 1.4
  */
 public static function renewal_orders_meta_box_section($order, $post)
 {
     if (self::is_renewal($order, array('order_role' => 'child'))) {
         $parent_id = self::get_parent_order_id($order);
     } elseif (WC_Subscriptions_Order::order_contains_subscription($order)) {
         $parent_id = $order->id;
     }
     //Find any renewal orders associated with this order.
     $items = get_posts(array('post_type' => $post->post_type, 'post_parent' => $parent_id, 'numberposts' => -1));
     if (self::is_renewal($order, array('order_role' => 'child'))) {
         $parent_order = new WC_Order($parent_id);
         printf('<p>%1$s <a href="%2$s">%3$s</a></p>', __('Initial Order:', 'woocommerce-subscriptions'), get_edit_post_link($parent_id), $parent_order->get_order_number());
     } elseif (self::is_renewal($order, array('order_role' => 'parent'))) {
         $original_order_id = WC_Subscriptions_Order::get_meta($order, 'original_order', false);
         $original_order = new WC_Order($original_order_id);
         printf('<p>%1$s <a href="%2$s">%3$s</a></p>', __('Renewal of Subscription Purchased in Order:', 'woocommerce-subscriptions'), get_edit_post_link($original_order_id), $original_order->get_order_number());
     } else {
         $original_order_post = get_posts(array('meta_key' => '_original_order', 'meta_value' => $parent_id, 'post_parent' => 0, 'post_type' => 'shop_order'));
         if (!empty($original_order_post) && isset($original_order_post[0])) {
             $original_order = new WC_Order($original_order_post[0]->ID);
             printf('<p>%1$s <a href="%2$s">%3$s</a></p>', __('Superseeded by Subscription Purchased in Order:', 'woocommerce-subscriptions'), get_edit_post_link($original_order->id), $original_order->get_order_number());
         }
     }
     if (empty($items)) {
         printf(' <p class="renewal-subtitle">%s</p>', __('No renewal payments yet.', 'woocommerce-subscriptions'));
     } else {
         printf('<p class="renewal-subtitle">%s</p>', __('Renewal Orders:', 'woocommerce-subscriptions'));
         echo '<ul class="renewal-orders">';
         foreach ($items as $item) {
             $renewal_order = new WC_Order($item->ID);
             if ($item->ID == $post->ID) {
                 printf('<li><strong>%s</strong></li>', $renewal_order->get_order_number());
             } else {
                 printf('<li><a href="%1$s">%2$s</a></li>', get_edit_post_link($item->ID), $renewal_order->get_order_number());
             }
         }
         echo '</ul>';
     }
 }
 /**
  * Clear all subscriptions from a user's account for a given order.
  *
  * @param $order WC_Order The order for which subscriptions should be cleared.
  * @since 1.0
  */
 public static function maybe_trash_subscription($order)
 {
     if (!is_object($order)) {
         $order = new WC_Order($order);
     }
     if (WC_Subscriptions_Order::order_contains_subscription($order)) {
         foreach ($order->get_items() as $order_item) {
             if (WC_Subscriptions_Order::is_item_subscription($order, $order_item)) {
                 self::trash_subscription($order->customer_user, self::get_subscription_key($order->id, WC_Subscriptions_Order::get_items_product_id($order_item)));
             }
         }
     }
 }
 /**
  * Change the send date of the email for 'before_renewal' and 'before_expire' triggers
  * @param array $insert
  * @param FUE_Email $email
  * @return array
  */
 public function modify_insert_send_date($insert, $email)
 {
     if ($email->type != 'subscription') {
         return $insert;
     }
     $order_id = $insert['order_id'];
     $order = WC_FUE_Compatibility::wc_get_order($order_id);
     if (!WC_Subscriptions_Order::order_contains_subscription($order)) {
         return $insert;
     }
     $subs_key = WC_Subscriptions_Manager::get_subscription_key($order_id);
     if ($email->trigger == 'subs_before_renewal') {
         $renewal_date = WC_Subscriptions_Manager::get_next_payment_date($subs_key);
         if (!$renewal_date) {
             // return false to tell FUE to skip importing this email/order
             return false;
         }
         // convert to local time
         $local_renewal_date = get_date_from_gmt($renewal_date, 'U');
         $add = FUE_Sending_Scheduler::get_time_to_add($email->interval, $email->duration);
         $insert['send_on'] = $local_renewal_date - $add;
     } elseif ($email->trigger == 'subs_before_expire') {
         $expiry_date = WC_Subscriptions_Manager::get_subscription_expiration_date($subs_key);
         if (!$expiry_date) {
             return false;
         }
         // convert to local time
         $expiry_timestamp = get_date_from_gmt($expiry_date, 'U');
         $add = FUE_Sending_Scheduler::get_time_to_add($email->interval, $email->duration);
         $insert['send_on'] = $expiry_timestamp - $add;
     }
     // Add the subscription key if it is not present in the meta
     if (!isset($insert['meta']) || empty($insert['meta']['subs_key'])) {
         $insert['meta']['subs_key'] = $subs_key;
     }
     return $insert;
 }
 /**
  * Output a hidden element in the order status of the orders list table to provide information about whether
  * the order displayed in that row contains a subscription or not.
  * 
  * @param $column String The string of the current column.
  * @since 1.1
  */
 public static function contains_subscription_hidden_field($order_id)
 {
     $has_subscription = WC_Subscriptions_Order::order_contains_subscription($order_id) ? 'true' : 'false';
     echo '<input type="hidden" name="contains_subscription" value="' . $has_subscription . '">';
 }
 /**
  * Process the payment
  *
  * If order contains subscriptions, use this class's process_subscription. If not, use the main class's process_payment function
  *
  * @param  int $order_id
  *
  * @return array
  *
  * @since 0.6.0
  */
 public function process_payment($order_id)
 {
     // Processing subscription
     if (class_exists('WC_Subscriptions_Order') && WC_Subscriptions_Order::order_contains_subscription($order_id)) {
         return $this->process_subscription($order_id);
         // Processing regular product
     } else {
         return parent::process_payment($order_id);
     }
 }
 public function process_payment($order_id)
 {
     global $woocommerce, $wpdb;
     $this->client = $this->getCurrentClient();
     // retrieve client
     $this->order_id = $order_id;
     $this->order_desc = $_SERVER['HTTP_HOST'] . ': ' . __('Order #', 'paymill') . $this->order_id . __(', Customer-ID #', 'paymill') . get_current_user_id();
     $this->order = new WC_Order($this->order_id);
     // load subscription class
     $this->subscriptions = new paymill_subscriptions('woocommerce');
     $this->offers = $this->subscriptions->offerGetList();
     // get the totals for pre authorization
     $this->getTotals();
     /*
     				$GLOBALS['paymill_loader']->paymill_errors->setError($this->totalProducts,'paymill');
     				$GLOBALS['paymill_loader']->paymill_errors->setError($this->totalSub,'paymill');
     				if($GLOBALS['paymill_loader']->paymill_errors->status()){
     					$GLOBALS['paymill_loader']->paymill_errors->getErrors();
     					return false;
     				}
     				
     				die('end');
     */
     // create payment object and preauthorization
     require_once PAYMILL_DIR . 'lib/integration/payment.inc.php';
     $this->paymentClass = new paymill_payment($this->clientClass->getCurrentClientID(), $this->totalProducts + $this->totalSub, get_woocommerce_currency());
     // create payment object, as it should be used for next processing instead of the token.
     if ($GLOBALS['paymill_loader']->paymill_errors->status()) {
         $GLOBALS['paymill_loader']->paymill_errors->getErrors();
         return false;
     }
     // process subscriptions & products
     if ($this->processSubscriptions() && $this->processProducts()) {
         // success
         if (method_exists($this->order, 'payment_complete')) {
             // if order contains subscription, mark payment complete later when webhook triggers succeeded payment
             if (class_exists('WC_Subscriptions_Order') && WC_Subscriptions_Order::order_contains_subscription($this->order)) {
                 $this->order->update_status('on-hold', __('Awaiting payment confirmation from Paymill.', 'paymill'));
             } else {
                 $this->order->payment_complete();
             }
         }
         // Reduce stock levels
         /*if(method_exists($this->order, 'reduce_order_stock')){
         			$this->order->reduce_order_stock();
         		}*/
         // Remove cart
         $woocommerce->cart->empty_cart();
         // Return thankyou redirect
         return array('result' => 'success', 'redirect' => $this->get_return_url($this->order));
     } else {
         if ($GLOBALS['paymill_loader']->paymill_errors->status()) {
             $GLOBALS['paymill_loader']->paymill_errors->getErrors();
         }
         return false;
     }
 }
 /**
  * Check if order contains subscriptions.
  *
  * @param  int $order_id
  * @return bool
  */
 protected function order_contains_subscription($order_id)
 {
     return class_exists('WC_Subscriptions_Order') && (WC_Subscriptions_Order::order_contains_subscription($order_id) || WC_Subscriptions_Renewal_Order::is_renewal($order_id));
 }