/**
  * Improve message displayed on checkout when a subscription is in the cart but not gateways support subscriptions.
  *
  * @since 1.5.2
  */
 public static function no_available_payment_methods_message($no_gateways_message)
 {
     global $woocommerce;
     if (WC_Subscriptions_Cart::cart_contains_subscription() && 'no' == get_option(WC_Subscriptions_Admin::$option_prefix . '_accept_manual_renewals', 'no')) {
         $no_gateways_message = __('Sorry, it seems there are no available payment methods which support subscriptions. Please contact us if you require assistance or wish to make alternate arrangements.', 'woocommerce-subscriptions');
     }
     return $no_gateways_message;
 }
 /**
  * Add subscription details next to subtotal of per-item-priced bundle-type container cart items.
  *
  * @param  string $subtotal
  * @param  array  $cart_item
  * @param  string $cart_item_key
  * @return string
  */
 public static function show_ppp_bundle_subtotal_details($subtotal, $cart_item, $cart_item_key)
 {
     foreach (self::$child_keys_names as $child_keys_name) {
         if (!empty($cart_item[$child_keys_name])) {
             if (self::overrides_child_schemes($cart_item)) {
                 $subtotal = WC_Subscriptions_Cart::get_formatted_product_subtotal($subtotal, $cart_item['data'], $cart_item['quantity'], WC()->cart);
             }
         }
     }
     return $subtotal;
 }
 /**
  * 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;
 }
 /**
  * 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;
 }
 /**
  * Helper to scan the cart for subscriptions (since we do not want to show a Checkout with PayPal
  * button in the cart view if there are any)
  *
  * @since 1.0.0
  */
 public function does_cart_contain_any_subscriptions()
 {
     if (!$this->subscription_support_enabled) {
         return false;
     }
     if (!class_exists('WC_Subscriptions_Cart')) {
         return false;
     }
     return WC_Subscriptions_Cart::cart_contains_subscription();
 }
 /**
  * Override the WooCommerce "Place Order" text with "Sign Up Now"
  *
  * @since 1.0
  */
 public static function order_button_text($button_text)
 {
     global $product;
     if (WC_Subscriptions_Cart::cart_contains_subscription()) {
         $button_text = get_option(WC_Subscriptions_Admin::$option_prefix . '_order_button_text', __('Sign Up Now', 'woocommerce-subscriptions'));
     }
     return $button_text;
 }
 /**
  * Init gateway
  */
 public function init_gateway()
 {
     global $woocommerce;
     if (!class_exists('WC_Payment_Gateway')) {
         return;
     }
     load_plugin_textdomain('woocommerce-gateway-amazon-payments-advanced', false, dirname(plugin_basename(__FILE__)) . '/languages/');
     switch ($woocommerce->countries->get_base_country()) {
         case 'GB':
             define('WC_AMAZON_PA_WIDGETS_URL', 'https://static-eu.payments-amazon.com/OffAmazonPayments/uk/' . ($this->settings['sandbox'] == 'yes' ? 'sandbox/' : '') . 'js/Widgets.js?sellerId=' . $this->settings['seller_id']);
             define('WC_AMAZON_WIDGET_ENDPOINT', 'https://payments' . ($this->settings['sandbox'] == 'yes' ? '-sandbox' : '') . '.amazon.co.uk');
             define('WC_AMAZON_REGISTER_URL', 'https://sellercentral-europe.amazon.com/gp/on-board/workflow/Registration/login.html?passthrough%2Fsource=internal-landing-select&passthrough%2F*entries*=0&passthrough%2FmarketplaceID=A2WQPBGJ59HSXT&passthrough%2FsuperSource=OAR&passthrough%2F*Version*=1&passthrough%2Fld=APRPWOOCOMMERCE&passthrough%2Faccount=cba&passthrough%2FwaiveFee=1');
             break;
         case 'DE':
             define('WC_AMAZON_PA_WIDGETS_URL', 'https://static-eu.payments-amazon.com/OffAmazonPayments/de/' . ($this->settings['sandbox'] == 'yes' ? 'sandbox/' : '') . 'js/Widgets.js?sellerId=' . $this->settings['seller_id']);
             define('WC_AMAZON_WIDGET_ENDPOINT', 'https://payments' . ($this->settings['sandbox'] == 'yes' ? '-sandbox' : '') . '.amazon.de');
             define('WC_AMAZON_REGISTER_URL', 'https://sellercentral-europe.amazon.com/gp/on-board/workflow/Registration/login.html?passthrough%2Fsource=internal-landing-select&passthrough%2F*entries*=0&passthrough%2FmarketplaceID=A1OCY9REWJOCW5&passthrough%2FsuperSource=OAR&passthrough%2F*Version*=1&passthrough%2Fld=APRPWOOCOMMERCE&passthrough%2Faccount=cba&passthrough%2FwaiveFee=1');
             break;
         default:
             define('WC_AMAZON_PA_WIDGETS_URL', 'https://static-na.payments-amazon.com/OffAmazonPayments/us/' . ($this->settings['sandbox'] == 'yes' ? 'sandbox/' : '') . 'js/Widgets.js?sellerId=' . $this->settings['seller_id']);
             define('WC_AMAZON_WIDGET_ENDPOINT', 'https://payments' . ($this->settings['sandbox'] == 'yes' ? '-sandbox' : '') . '.amazon.com');
             define('WC_AMAZON_REGISTER_URL', 'https://sellercentral.amazon.com/hz/me/sp/signup?solutionProviderOptions=mws-acc%3B&marketplaceId=AGWSWK15IEJJ7&solutionProviderToken=AAAAAQAAAAEAAAAQ1XU19m0BwtKDkfLZx%2B03RwAAAHBZVsoAgz2yhE7DemKr0y26Mce%2F9Q64kptY6CRih871XhB7neN0zoPX6c1wsW3QThdY6g1Re7CwxJkhvczwVfvZ9BvjG1V%2F%2FHrRgbIf47cTrdo5nNT8jmYSIEJvFbSm85nWxpvHjSC4CMsVL9s%2FPsZt&solutionProviderId=A1BVJDFFHQ7US4');
             break;
     }
     include_once 'includes/class-wc-gateway-amazon-payments-advanced.php';
     add_filter('woocommerce_payment_gateways', array($this, 'add_gateway'));
     if (empty($this->settings['seller_id']) || $this->settings['enabled'] == 'no') {
         return;
     }
     // Disable for subscriptions until supported
     if (!is_admin() && class_exists('WC_Subscriptions_Cart') && WC_Subscriptions_Cart::cart_contains_subscription() && 'no' === get_option(WC_Subscriptions_Admin::$option_prefix . '_accept_manual_renewals', 'no')) {
         return;
     }
     include_once 'includes/class-wc-amazon-payments-advanced-order-handler.php';
     add_action('wp_enqueue_scripts', array($this, 'scripts'));
     if ($this->settings['cart_button_display_mode'] == 'button') {
         add_action('woocommerce_proceed_to_checkout', array($this, 'checkout_button'), 12);
     } elseif ($this->settings['cart_button_display_mode'] == 'banner') {
         add_action('woocommerce_before_cart', array($this, 'checkout_message'), 5);
     }
     add_action('woocommerce_before_checkout_form', array($this, 'checkout_message'), 5);
     add_action('before_woocommerce_pay', array($this, 'checkout_message'), 5);
     if (empty($this->reference_id)) {
         return;
     }
     add_action('woocommerce_checkout_before_customer_details', array($this, 'payment_widget'), 20);
     add_action('woocommerce_checkout_before_customer_details', array($this, 'address_widget'), 10);
     add_action('woocommerce_checkout_init', array($this, 'remove_checkout_fields'));
     add_filter('woocommerce_available_payment_gateways', array($this, 'remove_gateways'));
     add_action('woocommerce_checkout_update_order_review', array($this, 'get_customer_details'));
 }
 /**
  * For subscription renewal via cart, use original order discount
  *
  * @since 1.3
  */
 public static function before_calculate_totals($cart)
 {
     $cart_item = WC_Subscriptions_Cart::cart_contains_subscription_renewal();
     if ($cart_item) {
         $original_order_id = $cart_item['subscription_renewal']['original_order'];
         $cart->discount_cart = WC_Subscriptions_Order::get_meta($original_order_id, '_order_recurring_discount_cart', 0);
         $cart->discount_total = WC_Subscriptions_Order::get_meta($original_order_id, '_order_recurring_discount_total', 0);
     }
 }
 /**
  * Apply sign up fee or recurring fee discount
  *
  * @since 1.2
  */
 public static function apply_subscription_discount($original_price, $cart_item, $cart)
 {
     _deprecated_function(__METHOD__, '2.0.10', 'Have moved to filtering on "woocommerce_coupon_get_discount_amount" to return discount amount. See: ' . __CLASS__ . '::get_discount_amount()');
     $product_id = $cart_item['data']->is_type(array('subscription_variation')) ? $cart_item['data']->variation_id : $cart_item['data']->id;
     if (!WC_Subscriptions_Product::is_subscription($product_id)) {
         return $original_price;
     }
     $price = $calculation_price = $original_price;
     $calculation_type = WC_Subscriptions_Cart::get_calculation_type();
     if (!empty($cart->applied_coupons)) {
         foreach ($cart->applied_coupons as $code) {
             $coupon = new WC_Coupon($code);
             // Pre 2.5 is_valid_for_product() does not use wc_get_product_coupon_types()
             if (WC_Subscriptions::is_woocommerce_pre('2.5')) {
                 $is_valid_for_product = true;
             } else {
                 $is_valid_for_product = $coupon->is_valid_for_product(wc_get_product($product_id), $cart_item);
             }
             if ($coupon->apply_before_tax() && $coupon->is_valid() && $is_valid_for_product) {
                 $apply_recurring_coupon = $apply_recurring_percent_coupon = $apply_initial_coupon = $apply_initial_percent_coupon = false;
                 // Apply recurring fee discounts to recurring total calculations
                 if ('recurring_total' == $calculation_type) {
                     $apply_recurring_coupon = 'recurring_fee' == $coupon->type ? true : false;
                     $apply_recurring_percent_coupon = 'recurring_percent' == $coupon->type ? true : false;
                 }
                 if ('none' == $calculation_type) {
                     // If all items have a free trial we don't need to apply recurring coupons to the initial total
                     if (!WC_Subscriptions_Cart::all_cart_items_have_free_trial()) {
                         if ('recurring_fee' == $coupon->type) {
                             $apply_initial_coupon = true;
                         }
                         if ('recurring_percent' == $coupon->type) {
                             $apply_initial_percent_coupon = true;
                         }
                     }
                     // Apply sign-up discounts to initial total
                     if (!empty($cart_item['data']->subscription_sign_up_fee)) {
                         if ('sign_up_fee' == $coupon->type) {
                             $apply_initial_coupon = true;
                         }
                         if ('sign_up_fee_percent' == $coupon->type) {
                             $apply_initial_percent_coupon = true;
                         }
                         $calculation_price = $cart_item['data']->subscription_sign_up_fee;
                     }
                 }
                 if ($apply_recurring_coupon || $apply_initial_coupon) {
                     $discount_amount = $calculation_price < $coupon->amount ? $calculation_price : $coupon->amount;
                     // Recurring coupons only apply when there is no free trial (carts can have a mix of free trial and non free trial items)
                     if ($apply_initial_coupon && 'recurring_fee' == $coupon->type && !empty($cart_item['data']->subscription_trial_length)) {
                         $discount_amount = 0;
                     }
                     $cart->discount_cart = $cart->discount_cart + $discount_amount * $cart_item['quantity'];
                     $cart = self::increase_coupon_discount_amount($cart, $coupon->code, $discount_amount * $cart_item['quantity']);
                     $price = $price - $discount_amount;
                 } elseif ($apply_recurring_percent_coupon) {
                     $discount_amount = round($calculation_price / 100 * $coupon->amount, WC()->cart->dp);
                     $cart->discount_cart = $cart->discount_cart + $discount_amount * $cart_item['quantity'];
                     $cart = self::increase_coupon_discount_amount($cart, $coupon->code, $discount_amount * $cart_item['quantity']);
                     $price = $price - $discount_amount;
                 } elseif ($apply_initial_percent_coupon) {
                     // Recurring coupons only apply when there is no free trial (carts can have a mix of free trial and non free trial items)
                     if ('recurring_percent' == $coupon->type && empty($cart_item['data']->subscription_trial_length)) {
                         $amount_to_discount = $cart_item['data']->subscription_price;
                     } else {
                         $amount_to_discount = 0;
                     }
                     // Sign up fee coupons only apply to sign up fees
                     if ('sign_up_fee_percent' == $coupon->type) {
                         $amount_to_discount = $cart_item['data']->subscription_sign_up_fee;
                     }
                     $discount_amount = round($amount_to_discount / 100 * $coupon->amount, WC()->cart->dp);
                     $cart->discount_cart = $cart->discount_cart + $discount_amount * $cart_item['quantity'];
                     $cart = self::increase_coupon_discount_amount($cart, $coupon->code, $discount_amount * $cart_item['quantity']);
                     $price = $price - $discount_amount;
                 }
             }
         }
         if ($price < 0) {
             $price = 0;
         }
     }
     return $price;
 }
 /**
  * Uses the a subscription's combined price total calculated by WooCommerce to determine the 
  * total price that should be charged per period.
  *
  * @since 1.2
  */
 public static function set_calculated_total($total)
 {
     global $woocommerce;
     if ('none' == self::$calculation_type || !self::cart_contains_subscription() && !self::cart_contains_subscription_renewal('parent')) {
         return $total;
     }
     // We've requested totals be recalculated with sign up fee only or free trial, we need to remove anything shipping related from the totals if there are no other items in the cart that require shipping
     if ('sign_up_fee_total' == self::$calculation_type || 'free_trial_total' == self::$calculation_type) {
         if (!self::charge_shipping_up_front()) {
             $total = $total - $woocommerce->cart->shipping_tax_total - $woocommerce->cart->shipping_total;
             $woocommerce->cart->shipping_taxes = array();
             $woocommerce->cart->shipping_tax_total = 0;
             $woocommerce->cart->shipping_total = 0;
         }
     }
     self::$calculation_type = 'none';
     return $total;
 }
示例#11
0
        echo '</div>';
    }
}
if ($klarna_order['status'] == 'checkout_incomplete') {
    wp_redirect($this->klarna_checkout_url);
    exit;
}
// Display Klarna iframe
if ($this->is_rest()) {
    $snippet = '<div>' . $klarna_order['html_snippet'] . '</div>';
} else {
    $snippet = '<div class="klarna-thank-you-snippet">' . $klarna_order['gui']['snippet'] . '</div>';
}
do_action('klarna_before_kco_confirmation', intval($_GET['sid']));
// WC Subscriptions 2.0 needs this
if (class_exists('WC_Subscriptions_Cart') && WC_Subscriptions_Cart::cart_contains_subscription()) {
    sleep(5);
    $parent_order = new WC_Order(intval($_GET['sid']));
    $subscriptions = array();
    // First clear out any subscriptions created for a failed payment to give us a clean slate for creating new subscriptions
    $subscriptions = wcs_get_subscriptions_for_order($parent_order->id, array('order_type' => 'parent'));
    if (!empty($subscriptions)) {
        foreach ($subscriptions as $subscription) {
            wp_delete_post($subscription->id);
        }
    }
    WC()->cart->calculate_totals();
    // Create new subscriptions for each group of subscription products in the cart (that is not a renewal)
    foreach (WC()->cart->recurring_carts as $recurring_cart) {
        $subscription = WC_Subscriptions_Checkout::create_subscription($parent_order, $recurring_cart);
        // Exceptions are caught by WooCommerce
 /**
  * Uses the a subscription's combined price total calculated by WooCommerce to determine the 
  * total price that should be charged per period.
  *
  * @since 1.2
  */
 public static function calculate_subscription_totals($total)
 {
     global $woocommerce;
     if (!self::cart_contains_subscription()) {
         return $total;
     } elseif ('sign_up_fee' == self::$recalculation_type) {
         // We've requested totals be recalculated with sign up fee only, we need to remove anything shipping related from the sign-up fee totals
         $total = $total - $woocommerce->cart->shipping_tax_total - $woocommerce->cart->shipping_total;
         $woocommerce->cart->shipping_taxes = array();
         $woocommerce->cart->shipping_tax_total = 0;
         self::$recalculation_type = 'none';
         return $total;
     }
     $base_sign_up_fee = self::get_cart_subscription_sign_up_fee();
     if ($base_sign_up_fee == 0 || self::$recalculation_type == 'base_recurring_fee') {
         // Nothing to fudge here, but we still need to keep a record of recurring totals
         foreach ($woocommerce->cart->get_cart() as $cart_item_key => $values) {
             $woocommerce->cart->recurring_cart_contents[$values['product_id']]['recurring_line_total'] = $values['line_total'];
             $woocommerce->cart->recurring_cart_contents[$values['product_id']]['recurring_line_tax'] = $values['line_tax'];
             $woocommerce->cart->recurring_cart_contents[$values['product_id']]['recurring_line_subtotal'] = $values['line_subtotal'];
             $woocommerce->cart->recurring_cart_contents[$values['product_id']]['recurring_line_subtotal_tax'] = $values['line_subtotal_tax'];
         }
         $woocommerce->cart->recurring_cart_contents_total = $woocommerce->cart->cart_contents_total;
         $woocommerce->cart->recurring_discount_cart = $woocommerce->cart->discount_cart;
         $woocommerce->cart->recurring_discount_total = $woocommerce->cart->discount_total;
         $woocommerce->cart->recurring_subtotal = $woocommerce->cart->subtotal;
         $woocommerce->cart->recurring_subtotal_ex_tax = $woocommerce->cart->subtotal_ex_tax;
         $woocommerce->cart->recurring_taxes = $woocommerce->cart->get_taxes();
         $woocommerce->cart->recurring_tax_total = $woocommerce->cart->tax_total;
         $woocommerce->cart->recurring_total = $total;
         // after calculating the recurring fee with discount, reset flag
         if (self::$recalculation_type == 'base_recurring_fee') {
             self::$recalculation_type = 'none';
             return $total;
         }
     } else {
         // The $total = price per period + sign up fee, so lets derive each one individually
         $sign_up_fee_proportion = $base_sign_up_fee / ($base_sign_up_fee + self::$base_product_price);
         // self::$base_product_price as set in set_subscription_prices_for_calculation()
         $recurring_proportion = 1 - $sign_up_fee_proportion;
         foreach ($woocommerce->cart->get_cart() as $cart_item_key => $values) {
             $woocommerce->cart->recurring_cart_contents[$values['product_id']]['recurring_line_total'] = WC_Subscriptions_Manager::get_amount_from_proportion($values['line_total'], $recurring_proportion);
             $woocommerce->cart->recurring_cart_contents[$values['product_id']]['recurring_line_tax'] = WC_Subscriptions_Manager::get_amount_from_proportion($values['line_tax'], $recurring_proportion);
             $woocommerce->cart->recurring_cart_contents[$values['product_id']]['recurring_line_subtotal'] = WC_Subscriptions_Manager::get_amount_from_proportion($values['line_subtotal'], $recurring_proportion);
             $woocommerce->cart->recurring_cart_contents[$values['product_id']]['recurring_line_subtotal_tax'] = WC_Subscriptions_Manager::get_amount_from_proportion($values['line_subtotal_tax'], $recurring_proportion);
         }
         // Calculate recurring totals, required for totals display correctly on cart and order page
         $woocommerce->cart->recurring_cart_contents_total = WC_Subscriptions_Manager::get_amount_from_proportion($woocommerce->cart->cart_contents_total, $recurring_proportion);
         $woocommerce->cart->recurring_discount_cart = WC_Subscriptions_Manager::get_amount_from_proportion($woocommerce->cart->discount_cart, $recurring_proportion);
         $woocommerce->cart->recurring_discount_total = WC_Subscriptions_Manager::get_amount_from_proportion($woocommerce->cart->discount_total, $recurring_proportion);
         $woocommerce->cart->recurring_subtotal = WC_Subscriptions_Manager::get_amount_from_proportion($woocommerce->cart->subtotal, $recurring_proportion);
         $woocommerce->cart->recurring_subtotal_ex_tax = WC_Subscriptions_Manager::get_amount_from_proportion($woocommerce->cart->subtotal_ex_tax, $recurring_proportion);
         $woocommerce->cart->recurring_taxes = array();
         // Add non-shipping taxes
         foreach ($woocommerce->cart->taxes as $tax_id => $tax_amount) {
             $woocommerce->cart->recurring_taxes[$tax_id] = WC_Subscriptions_Manager::get_amount_from_proportion($tax_amount, $recurring_proportion);
         }
         // And shipping taxes
         foreach ($woocommerce->cart->shipping_taxes as $tax_id => $tax_amount) {
             $woocommerce->cart->recurring_taxes[$tax_id] = $tax_amount;
         }
         // Shipping only applies to recurring payments
         // Shipping only applies to recurring amounts, not the sign-up fee, so we'll add it in its entirety to the recurring amount later
         $total_sans_shipping = $total - $woocommerce->cart->shipping_tax_total - $woocommerce->cart->shipping_total;
         $total_ex_tax = $total_sans_shipping - $woocommerce->cart->tax_total;
         $recurring_total_ex_tax = WC_Subscriptions_Manager::get_amount_from_proportion($total_ex_tax, $recurring_proportion) + $woocommerce->cart->shipping_total;
         $woocommerce->cart->recurring_total = WC_Subscriptions_Manager::get_amount_from_proportion($total_sans_shipping, $recurring_proportion) + $woocommerce->cart->shipping_tax_total + $woocommerce->cart->shipping_total;
         $woocommerce->cart->recurring_tax_total = $woocommerce->cart->recurring_total - $recurring_total_ex_tax;
         /** Handle pricing adjustments - Recurring / Sign up fee discounts / trial periods */
         // Recurring discount
         if (WC_Subscriptions_Coupon::cart_contains_recurring_discount()) {
             // save cart with combined totals
             $original_cart = clone $woocommerce->cart;
             // calculate total with sign up fee only first
             self::$recalculation_type = 'sign_up_fee';
             $woocommerce->cart->calculate_totals();
             // save cart with just sign up fee
             $sign_up_fee_cart = clone $woocommerce->cart;
             // now calculate base recurring fee with discount included
             self::$recalculation_type = 'base_recurring_fee';
             $woocommerce->cart->calculate_totals();
             if (self::cart_contains_free_trial()) {
                 // restore sign up fee cart contents & total
                 $woocommerce->cart->cart_contents = $sign_up_fee_cart->cart_contents;
                 $woocommerce->cart->cart_contents_total = $sign_up_fee_cart->cart_contents_total;
                 // restore sign up fee cart sub-totals
                 $woocommerce->cart->subtotal = $sign_up_fee_cart->subtotal;
                 $woocommerce->cart->subtotal_ex_tax = $sign_up_fee_cart->subtotal_ex_tax;
                 // restore sign up fee cart taxes
                 $woocommerce->cart->taxes = $sign_up_fee_cart->taxes;
                 $woocommerce->cart->tax_total = $sign_up_fee_cart->tax_total;
                 // final total is sign up fee cart total only
                 $total = $sign_up_fee_cart->total;
                 // Add sign up fee discounts to cart/total discounts (which already include recurring discounts)
                 $woocommerce->cart->discount_cart = $sign_up_fee_cart->discount_cart > 0 ? $sign_up_fee_cart->discount_cart : 0;
                 $woocommerce->cart->discount_total = $sign_up_fee_cart->discount_total > 0 ? $sign_up_fee_cart->discount_total : 0;
             } else {
                 // restore combined cart contents & total
                 $woocommerce->cart->cart_contents = $original_cart->cart_contents;
                 $woocommerce->cart->cart_contents_total = $original_cart->cart_contents_total;
                 // restore combined cart sub-totals
                 $woocommerce->cart->subtotal = $original_cart->subtotal;
                 $woocommerce->cart->subtotal_ex_tax = $original_cart->subtotal_ex_tax;
                 // combine and total any taxes on sign up fees to the cart total (which already includes taxes on recurring fees)
                 foreach ($woocommerce->cart->taxes as $tax_key => $tax_amount) {
                     $woocommerce->cart->taxes[$tax_key] += $sign_up_fee_cart->taxes[$tax_key];
                 }
                 $woocommerce->cart->tax_total += $sign_up_fee_cart->tax_total;
                 // Add sign up fee discounts to cart/total discounts (which already include recurring discounts)
                 $woocommerce->cart->discount_cart += $sign_up_fee_cart->discount_cart > 0 ? $sign_up_fee_cart->discount_cart : 0;
                 $woocommerce->cart->discount_total += $sign_up_fee_cart->discount_total > 0 ? $sign_up_fee_cart->discount_total : 0;
                 // Final total is sign up fee cart total + recurring fee cart total
                 $total = $sign_up_fee_cart->total + $woocommerce->cart->recurring_total;
             }
             // Sign up fee discount
         } elseif (WC_Subscriptions_Coupon::cart_contains_sign_up_discount()) {
             // save cart with combined totals
             $original_cart = clone $woocommerce->cart;
             // calculate totals with sign up fee only first
             self::$recalculation_type = 'sign_up_fee';
             $woocommerce->cart->calculate_totals();
             if (self::cart_contains_free_trial()) {
                 // only need sign up total for the initial payment
                 $total = $woocommerce->cart->total;
             } else {
                 // restore combined cart contents & total
                 $woocommerce->cart->cart_contents = $original_cart->cart_contents;
                 $woocommerce->cart->cart_contents_total = $original_cart->cart_contents_total;
                 // restore combined cart sub-totals
                 $woocommerce->cart->subtotal = $original_cart->subtotal;
                 $woocommerce->cart->subtotal_ex_tax = $original_cart->subtotal_ex_tax;
                 $total = $woocommerce->cart->total + $woocommerce->cart->recurring_total;
             }
             // Free trial with no discounts - recalculate all the initial payment amounts just for the sign-up fee
         } elseif (self::cart_contains_free_trial()) {
             // only pass sign up fee thru get_price filters
             self::$recalculation_type = 'sign_up_fee';
             $woocommerce->cart->calculate_totals();
             // Make the sign up fee only total persist
             $total = $woocommerce->cart->total;
         }
     }
     return $total;
 }
            unset($_SESSION[$field]);
        }
        if ($woocommerce->cart->sign_up_fee_taxes == 0) {
            // There's always one exception
            $woocommerce->cart->sign_up_fee_taxes = array();
        }
    }
    /**
     * Get tax row amounts with or without compound taxes includes
     *
     * @return float price
     */
    public static function get_sign_up_taxes_total($compound = true)
    {
        global $woocommerce;
        $sign_up_taxes_total = 0;
        foreach ($woocommerce->cart->sign_up_fee_taxes as $key => $tax) {
            if (!$compound && $woocommerce->cart->tax->is_compound($key)) {
                continue;
            }
            $sign_up_taxes_total += $tax;
        }
        return $sign_up_taxes_total;
    }
    public static function get_sign_up_fee_fields()
    {
        return array('cart_contents_sign_up_fee_total', 'cart_contents_sign_up_fee_count', 'sign_up_fee_total', 'sign_up_fee_subtotal', 'sign_up_fee_subtotal_ex_tax', 'sign_up_fee_tax_total', 'sign_up_fee_taxes', 'sign_up_fee_discount_cart', 'sign_up_fee_discount_total');
    }
}
WC_Subscriptions_Cart::init();
 /**
  * Calculate subscriptions price html component by breaking up bundled subs into recurring scheme groups and adding up all prices in each group.
  *
  * @return string
  */
 public function apply_subs_price_html($price)
 {
     if (!empty($this->bundled_items)) {
         $subs_details = array();
         $subs_details_html = array();
         $non_optional_subs_exist = false;
         foreach ($this->bundled_items as $bundled_item_id => $bundled_item) {
             if ($bundled_item->is_sub()) {
                 $bundled_product = $bundled_item->product;
                 if ($bundled_item->is_variable_sub()) {
                     $product_id = get_post_meta($bundled_product->id, '_min_price_variation_id', true);
                     $product = $bundled_product->get_child($product_id);
                 } else {
                     $product = $bundled_product;
                 }
                 $sub_string = str_replace('_synced', '', WC_Subscriptions_Cart::get_recurring_cart_key(array('data' => $product), ' '));
                 if (!isset($subs_details[$sub_string]['bundled_items'])) {
                     $subs_details[$sub_string]['bundled_items'] = array();
                 }
                 if (!isset($subs_details[$sub_string]['price'])) {
                     $subs_details[$sub_string]['price'] = 0;
                     $subs_details[$sub_string]['regular_price'] = 0;
                     $subs_details[$sub_string]['is_range'] = false;
                 }
                 $subs_details[$sub_string]['bundled_items'][] = $bundled_item_id;
                 $subs_details[$sub_string]['price'] += $this->bundled_quantities_index['min'][$bundled_item_id] * WC_PB_Helpers::get_product_display_price($product, $bundled_item->min_recurring_price);
                 $subs_details[$sub_string]['regular_price'] += $this->bundled_quantities_index['min'][$bundled_item_id] * WC_PB_Helpers::get_product_display_price($product, $bundled_item->min_regular_recurring_price);
                 if ($bundled_item->is_variable_sub()) {
                     if ($bundled_product->min_variation_price !== $bundled_product->max_variation_price || $bundled_product->subscription_period !== $bundled_product->max_variation_period || $bundled_product->subscription_period_interval !== $bundled_product->max_variation_period_interval) {
                         $subs_details[$sub_string]['is_range'] = true;
                     }
                 }
                 if (!isset($subs_details[$sub_string]['price_html'])) {
                     $subs_details[$sub_string]['price_html'] = WC_PB_Helpers::get_recurring_price_html_component($product);
                 }
             }
         }
         if (!empty($subs_details)) {
             foreach ($subs_details as $sub_details) {
                 if ($sub_details['price'] > 0) {
                     $sub_price_html = wc_price($sub_details['price']);
                     if ($sub_details['price'] !== $sub_details['regular_price']) {
                         $sub_regular_price_html = wc_price($sub_details['regular_price']);
                         if ($sub_details['is_range']) {
                             $sub_price_html = sprintf(_x('%1$s%2$s', 'Price range: from', 'woocommerce-product-bundles'), _x('<span class="from">from </span>', 'min-price', 'woocommerce-product-bundles'), $this->get_price_html_from_to($sub_regular_price_html, $sub_price_html));
                         } else {
                             $sub_price_html = $this->get_price_html_from_to($sub_regular_price_html, $sub_price_html);
                         }
                     } elseif ($sub_details['price'] == 0 && !$sub_details['is_range']) {
                         $sub_price_html = __('Free!', 'woocommerce');
                     } else {
                         if ($sub_details['is_range']) {
                             $sub_price_html = sprintf(_x('%1$s%2$s', 'Price range: from', 'woocommerce-product-bundles'), _x('<span class="from">from </span>', 'min-price', 'woocommerce-product-bundles'), $sub_price_html);
                         }
                     }
                     $sub_price_html = sprintf($sub_details['price_html'], $sub_price_html);
                     $subs_details_html[] = '<span class="bundled_sub_price_html">' . $sub_price_html . '</span>';
                 }
             }
             $price_html = implode('<span class="plus"> + </span>', $subs_details_html);
             if ($this->min_bundle_regular_price != 0) {
                 $price = sprintf(_x('%1$s<span class="bundled_subscriptions_price_html" %2$s> now,</br>then %3$s</span>', 'subscription price html suffix', 'woocommerce-product-bundles'), $price, !empty($subs_details_html) ? '' : 'style="display:none"', $price_html);
             } else {
                 $price = '<span class="bundled_subscriptions_price_html">' . $price_html . '</span>';
             }
         }
     }
     return $price;
 }
 /**
  *  Change Checkout URL
  *
  *  Triggered from the 'woocommerce_get_checkout_url' action.
  *  Alter the checkout url to the custom Klarna Checkout Checkout page.
  *
  **/
 function change_checkout_url($url)
 {
     global $woocommerce;
     global $klarna_checkout_url;
     $checkout_settings = get_option('woocommerce_klarna_checkout_settings');
     $enabled = $checkout_settings['enabled'];
     $modify_standard_checkout_url = $checkout_settings['modify_standard_checkout_url'];
     $klarna_country = WC()->session->get('klarna_country');
     $available_countries = $this->get_authorized_countries();
     // Change the Checkout URL if this is enabled in the settings
     if ($modify_standard_checkout_url == 'yes' && $enabled == 'yes' && !empty($klarna_checkout_url) && in_array(strtoupper($klarna_country), $available_countries) && array_key_exists(strtoupper($klarna_country), WC()->countries->get_allowed_countries())) {
         if (class_exists('WC_Subscriptions_Cart') && WC_Subscriptions_Cart::cart_contains_subscription()) {
             if (in_array(strtoupper($klarna_country), array('SE', 'FI', 'NO'))) {
                 $url = $klarna_checkout_url;
             } else {
                 return $url;
             }
         } else {
             $url = $klarna_checkout_url;
         }
     }
     return $url;
 }
 /**
  * Make sure that a switch items cart key is based on it's first renewal date, not the date calculated for the product.
  *
  * @since 2.0
  */
 public static function get_recurring_cart_key($cart_key, $cart_item)
 {
     if (isset($cart_item['subscription_switch']['first_payment_timestamp'])) {
         remove_filter('woocommerce_subscriptions_recurring_cart_key', __METHOD__, 10, 2);
         $cart_key = WC_Subscriptions_Cart::get_recurring_cart_key($cart_item, $cart_item['subscription_switch']['first_payment_timestamp']);
         add_filter('woocommerce_subscriptions_recurring_cart_key', __METHOD__, 10, 2);
     }
     return $cart_key;
 }
/**
 * Get recurring shipping methods.
 *
 * @access public
 */
function wcs_cart_totals_shipping_html()
{
    $initial_packages = WC()->shipping->get_packages();
    $show_package_details = count(WC()->cart->recurring_carts) > 1 ? true : false;
    $show_package_name = true;
    // Create new subscriptions for each subscription product in the cart (that is not a renewal)
    foreach (WC()->cart->recurring_carts as $recurring_cart_key => $recurring_cart) {
        // Create shipping packages for each subscription item
        if (WC_Subscriptions_Cart::cart_contains_subscriptions_needing_shipping() && 0 !== $recurring_cart->next_payment_date) {
            // This will get a package with the 'recurring_cart_key' set to 'none' (because WC_Subscriptions_Cart::display_recurring_totals() set WC_Subscriptions_Cart::$calculation_type to 'recurring_total', but WC_Subscriptions_Cart::$recurring_cart_key has not been set), which ensures that it's a unique package, which we need in order to get all the available packages, not just the package for the recurring cart calculation we completed previously where WC_Subscriptions_Cart::filter_package_rates() removed all unchosen rates and which WC then cached
            $packages = $recurring_cart->get_shipping_packages();
            foreach ($packages as $i => $base_package) {
                $product_names = array();
                $package = WC_Subscriptions_Cart::get_calculated_shipping_for_package($base_package);
                $index = sprintf('%1$s_%2$d', $recurring_cart_key, $i);
                if ($show_package_details) {
                    foreach ($package['contents'] as $item_id => $values) {
                        $product_names[] = $values['data']->get_title() . ' &times;' . $values['quantity'];
                    }
                    $package_details = implode(', ', $product_names);
                } else {
                    $package_details = '';
                }
                $chosen_initial_method = isset(WC()->session->chosen_shipping_methods[$i]) ? WC()->session->chosen_shipping_methods[$i] : '';
                $chosen_recurring_method = isset(WC()->session->chosen_shipping_methods[$recurring_cart_key . '_' . $i]) ? WC()->session->chosen_shipping_methods[$recurring_cart_key . '_' . $i] : $chosen_initial_method;
                if (1 === count($package['rates']) || isset($package['rates'][$chosen_initial_method]) && isset($initial_packages[$i]) && $package['rates'] == $initial_packages[$i]['rates'] && apply_filters('wcs_cart_totals_shipping_html_price_only', true, $package, $recurring_cart)) {
                    $shipping_method = 1 === count($package['rates']) ? current($package['rates']) : $package['rates'][$chosen_initial_method];
                    // packages match, display shipping amounts only
                    ?>
					<tr class="shipping recurring-total <?php 
                    echo esc_attr($recurring_cart_key);
                    ?>
">
						<th><?php 
                    echo esc_html(sprintf(__('Shipping via %s', 'woocommerce-subscriptions'), $shipping_method->label));
                    ?>
</th>
						<td>
							<?php 
                    echo wp_kses_post(wcs_cart_totals_shipping_method_price_label($shipping_method, $recurring_cart));
                    ?>
							<?php 
                    if (1 === count($package['rates'])) {
                        ?>
								<?php 
                        wcs_cart_print_shipping_input($index, $shipping_method);
                        ?>
								<?php 
                        do_action('woocommerce_after_shipping_rate', $shipping_method, $index);
                        ?>
							<?php 
                    }
                    ?>
							<?php 
                    if (!empty($show_package_details)) {
                        ?>
								<?php 
                        echo '<p class="woocommerce-shipping-contents"><small>' . esc_html($package_details) . '</small></p>';
                        ?>
							<?php 
                    }
                    ?>
						</td>
					</tr>
					<?php 
                } else {
                    // Display the options
                    $product_names = array();
                    if ($show_package_name) {
                        $package_name = apply_filters('woocommerce_shipping_package_name', sprintf(_n('Shipping', 'Shipping %d', $i + 1, 'woocommerce-subscriptions'), $i + 1), $i, $package);
                    } else {
                        $package_name = '';
                    }
                    wc_get_template('cart/cart-recurring-shipping.php', array('package' => $package, 'available_methods' => $package['rates'], 'show_package_details' => $show_package_details, 'package_details' => $package_details, 'package_name' => $package_name, 'index' => $index, 'chosen_method' => $chosen_recurring_method, 'recurring_cart_key' => $recurring_cart_key, 'recurring_cart' => $recurring_cart), '', plugin_dir_path(WC_Subscriptions::$plugin_file) . 'templates/');
                    $show_package_name = false;
                }
                do_action('woocommerce_subscriptions_after_recurring_shipping_rates', $index, $base_package, $recurring_cart, $chosen_recurring_method);
            }
        }
    }
}
 /**
  * Gets the authorization message displayed at checkout.
  *
  * @since 2.4.0
  * @return string
  */
 public function get_authorization_message()
 {
     if ($this->supports_subscriptions() && (WC_Subscriptions_Cart::cart_contains_subscription() || WC_Subscriptions_Change_Payment_Gateway::$is_request_to_change_payment)) {
         if ($this->recurring_authorization_message) {
             $raw_message = $this->recurring_authorization_message;
         } else {
             $raw_message = $this->get_default_recurring_authorization_message();
         }
     } else {
         if ($this->authorization_message) {
             $raw_message = $this->authorization_message;
         } else {
             $raw_message = $this->get_default_authorization_message();
         }
     }
     /**
      * Filters the authorization message displayed at checkout, before replacing the placeholders.
      *
      * @since 2.4.0
      * @param string $message the raw authorization message text
      * @param \WC_Gateway_Authorize_Net_CIM_eCheck $gateway the gateway object
      */
     $raw_message = apply_filters('wc_' . $this->get_id() . '_raw_authorization_message', $raw_message, $this);
     $order_total = ($order = wc_get_order($this->get_checkout_pay_page_order_id())) ? $order->get_total() : WC()->cart->total;
     /**
      * Filters the authorization message placeholders.
      *
      * @since 2.4.0
      * @param array $placeholders the authorization message placeholders
      * @param \WC_Gateway_Authorize_Net_CIM_eCheck $gateway the gateway object
      */
     $placeholders = apply_filters('wc_' . $this->get_id() . '_authorization_message_placeholders', array('{merchant_name}' => get_bloginfo('name'), '{order_total}' => wc_price($order_total), '{order_date}' => date_i18n(wc_date_format())), $this);
     $message = str_replace(array_keys($placeholders), $placeholders, $raw_message);
     /**
      * Filters the authorization message displayed at checkout.
      *
      * @since 2.4.0
      * @param string $message the authorization message text
      * @param \WC_Gateway_Authorize_Net_CIM_eCheck $gateway the gateway object
      */
     return apply_filters('wc_' . $this->get_id() . '_authorization_message', $message, $this);
 }
 /**
  * Payment fields.
  */
 public function payment_fields()
 {
     $contains_subscription = false;
     if (defined('WC_VERSION') && version_compare(WC_VERSION, '2.1', '>=')) {
         $order_id = absint(get_query_var('order-pay'));
     } else {
         $order_id = isset($_GET['order_id']) ? absint($_GET['order_id']) : 0;
     }
     // Check from "pay for order" page.
     if (0 < $order_id) {
         $contains_subscription = $this->api->order_contains_subscription($order_id);
     } elseif (class_exists('WC_Subscriptions_Cart')) {
         $contains_subscription = WC_Subscriptions_Cart::cart_contains_subscription();
     }
     if ($contains_subscription) {
         wp_enqueue_script('wc-credit-card-form');
         if ($description = $this->get_description()) {
             echo wpautop(wptexturize($description));
         }
         woocommerce_get_template('credit-card/payment-form.php', array('order_total' => 0, 'installments' => 0, 'free_interest' => 0, 'transaction_rate' => 0, 'rates' => array()), 'woocommerce/iugu/', WC_Iugu::get_templates_path());
     } else {
         parent::payment_fields();
     }
 }
 /**
  * Calculate the initial and recurring totals for all subscription products in the cart.
  *
  * We need to group subscriptions by billing schedule to make the display and creation of recurring totals sane,
  * when there are multiple subscriptions in the cart. To do that, we use an array with keys of the form:
  * '{billing_interval}_{billing_period}_{trial_interval}_{trial_period}_{length}_{billing_period}'. This key
  * is used to reference WC_Cart objects for each recurring billing schedule and these are stored in the master
  * cart with the billing schedule key.
  *
  * After we have calculated and grouped all recurring totals, we need to checks the structure of the subscription
  * product prices to see whether they include sign-up fees and/or free trial periods and then recalculates the
  * appropriate totals by using the @see self::$calculation_type flag and cloning the cart to run @see WC_Cart::calculate_totals()
  *
  * @since 1.3.5
  * @version 2.0
  */
 public static function calculate_subscription_totals($total, $cart)
 {
     if (!self::cart_contains_subscription() && !wcs_cart_contains_resubscribe()) {
         // cart doesn't contain subscription
         return $total;
     } elseif ('none' != self::$calculation_type) {
         // We're in the middle of a recalculation, let it run
         return $total;
     }
     // Save the original cart values/totals, as we'll use this when there is no sign-up fee
     WC()->cart->total = $total < 0 ? 0 : $total;
     do_action('woocommerce_subscription_cart_before_grouping');
     $subscription_groups = array();
     // Group the subscription items by their cart item key based on billing schedule
     foreach (WC()->cart->get_cart() as $cart_item_key => $cart_item) {
         if (WC_Subscriptions_Product::is_subscription($cart_item['data'])) {
             $subscription_groups[self::get_recurring_cart_key($cart_item)][] = $cart_item_key;
         }
     }
     do_action('woocommerce_subscription_cart_after_grouping');
     $recurring_carts = array();
     // Now let's calculate the totals for each group of subscriptions
     self::$calculation_type = 'recurring_total';
     foreach ($subscription_groups as $recurring_cart_key => $subscription_group) {
         // Create a clone cart to calculate and store totals for this group of subscriptions
         $recurring_cart = clone WC()->cart;
         $product = null;
         // Remove any items not in this subscription group
         foreach ($recurring_cart->get_cart() as $cart_item_key => $cart_item) {
             if (!in_array($cart_item_key, $subscription_group)) {
                 unset($recurring_cart->cart_contents[$cart_item_key]);
                 continue;
             }
             if (null === $product) {
                 $product = $cart_item['data'];
             }
         }
         $recurring_cart->start_date = apply_filters('wcs_recurring_cart_start_date', gmdate('Y-m-d H:i:s'), $recurring_cart);
         $recurring_cart->trial_end_date = apply_filters('wcs_recurring_cart_trial_end_date', WC_Subscriptions_Product::get_trial_expiration_date($product, $recurring_cart->start_date), $recurring_cart, $product);
         $recurring_cart->next_payment_date = apply_filters('wcs_recurring_cart_next_payment_date', WC_Subscriptions_Product::get_first_renewal_payment_date($product, $recurring_cart->start_date), $recurring_cart, $product);
         $recurring_cart->end_date = apply_filters('wcs_recurring_cart_end_date', WC_Subscriptions_Product::get_expiration_date($product, $recurring_cart->start_date), $recurring_cart, $product);
         // No fees recur (yet)
         $recurring_cart->fees = array();
         $recurring_cart->fee_total = 0;
         self::maybe_recalculate_shipping();
         $recurring_cart->calculate_totals();
         // Store this groups cart details
         $recurring_carts[$recurring_cart_key] = clone $recurring_cart;
         // And remove some other floatsam
         $recurring_carts[$recurring_cart_key]->removed_cart_contents = array();
         $recurring_carts[$recurring_cart_key]->cart_session_data = array();
     }
     self::$calculation_type = 'none';
     // We need to reset the packages and totals stored in WC()->shipping too
     self::maybe_recalculate_shipping();
     WC()->cart->calculate_shipping();
     // If there is no sign-up fee and a free trial, and no products being purchased with the subscription, we need to zero the fees for the first billing period
     if (0 == self::get_cart_subscription_sign_up_fee() && self::all_cart_items_have_free_trial()) {
         foreach (WC()->cart->get_fees() as $fee_index => $fee) {
             WC()->cart->fees[$fee_index]->amount = 0;
             WC()->cart->fees[$fee_index]->tax = 0;
         }
         WC()->cart->fee_total = 0;
     }
     WC()->cart->recurring_carts = $recurring_carts;
     $total = max(0, round(WC()->cart->cart_contents_total + WC()->cart->tax_total + WC()->cart->shipping_tax_total + WC()->cart->shipping_total + WC()->cart->fee_total, WC()->cart->dp));
     if (isset(WC()->cart->discount_total) && 0 !== WC()->cart->discount_total) {
         // WC < 2.3, deduct deprecated after tax discount total
         $total = max(0, round($total - WC()->cart->discount_total, WC()->cart->dp));
     }
     if (!self::charge_shipping_up_front()) {
         $total = max(0, $total - WC()->cart->shipping_tax_total - WC()->cart->shipping_total);
         WC()->cart->shipping_taxes = array();
         WC()->cart->shipping_tax_total = 0;
         WC()->cart->shipping_total = 0;
     }
     return apply_filters('woocommerce_subscriptions_calculated_total', $total);
 }
 /**
  * Sets which coupons should be applied for this calculation.
  *
  * This function is hooked to "woocommerce_before_calculate_totals" so that WC will calculate a subscription
  * product's total based on the total of it's price per period and sign up fee (if any).
  *
  * @since 1.3.5
  */
 public static function remove_coupons($cart)
 {
     global $woocommerce;
     $calculation_type = WC_Subscriptions_Cart::get_calculation_type();
     // Only hook when totals are being calculated completely (on cart & checkout pages)
     if ('none' == $calculation_type || !WC_Subscriptions_Cart::cart_contains_subscription() || !is_checkout() && !is_cart() && !defined('WOOCOMMERCE_CHECKOUT') && !defined('WOOCOMMERCE_CART')) {
         return;
     }
     $applied_coupons = $cart->get_applied_coupons();
     // If we're calculating a sign-up fee or recurring fee only amount, remove irrelevant coupons
     if (!empty($applied_coupons)) {
         // Keep track of which coupons, if any, need to be reapplied immediately
         $coupons_to_reapply = array();
         if (in_array($calculation_type, array('combined_total', 'sign_up_fee_total', 'recurring_total'))) {
             foreach ($applied_coupons as $coupon_code) {
                 $coupon = new WC_Coupon($coupon_code);
                 if (in_array($coupon->type, array('recurring_fee', 'recurring_percent'))) {
                     // always apply coupons to their specific calculation case
                     if ('recurring_total' == $calculation_type) {
                         $coupons_to_reapply[] = $coupon_code;
                     } elseif ('combined_total' == $calculation_type && !WC_Subscriptions_Cart::cart_contains_free_trial()) {
                         // sometimes apply recurring coupons to initial total
                         $coupons_to_reapply[] = $coupon_code;
                     } else {
                         self::$removed_coupons[] = $coupon_code;
                     }
                 } elseif (in_array($calculation_type, array('combined_total', 'sign_up_fee_total', 'none')) && !in_array($coupon->type, array('recurring_fee', 'recurring_percent'))) {
                     // apply all coupons to the first payment
                     $coupons_to_reapply[] = $coupon_code;
                 } else {
                     self::$removed_coupons[] = $coupon_code;
                 }
             }
             // Now remove all coupons (WC only provides a function to remove all coupons)
             $cart->remove_coupons();
             // And re-apply those which relate to this calculation
             $woocommerce->cart->applied_coupons = $coupons_to_reapply;
         }
     }
 }
 /**
  * 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;
 }
 /**
  * Removes the "set_subscription_prices_for_calculation" filter from the WC Product's woocommerce_get_price hook once
  *
  * @since 1.5.10
  */
 public static function set_prorated_price_for_calculation($price, $product)
 {
     if (WC_Subscriptions_Product::is_subscription($product) && self::is_product_prorated($product) && in_array(WC_Subscriptions_Cart::get_calculation_type(), array('combined_total', 'none'))) {
         $next_payment_date = self::calculate_first_payment_date($product, 'timestamp');
         if (self::is_today($next_payment_date)) {
             return $price;
         }
         switch ($product->subscription_period) {
             case 'week':
                 $days_in_cycle = 7 * $product->subscription_period_interval;
                 break;
             case 'month':
                 $days_in_cycle = date('t') * $product->subscription_period_interval;
                 break;
             case 'year':
                 $days_in_cycle = (365 + date('L')) * $product->subscription_period_interval;
                 break;
         }
         $days_until_next_payment = ceil(($next_payment_date - gmdate('U')) / (60 * 60 * 24));
         if ('combined_total' == WC_Subscriptions_Cart::get_calculation_type()) {
             $sign_up_fee = WC_Subscriptions_Product::get_sign_up_fee($product);
             if ($sign_up_fee > 0 && 0 == WC_Subscriptions_Product::get_trial_length($product)) {
                 $price = $sign_up_fee + $days_until_next_payment * (($price - $sign_up_fee) / $days_in_cycle);
             }
         } elseif ('none' == WC_Subscriptions_Cart::get_calculation_type()) {
             $price = $days_until_next_payment * ($price / $days_in_cycle);
         }
     }
     return $price;
 }
 /**
  * Force tokenization for subscriptions, this can be forced either during checkout
  * or when the payment method for a subscription is being changed
  *
  * @since 4.1.0
  * @see SV_WC_Payment_Gateway::tokenization_forced()
  * @param bool $force_tokenization whether tokenization should be forced
  * @return bool true if tokenization should be forced, false otherwise
  */
 public function maybe_force_tokenization_1_5($force_tokenization)
 {
     // pay page with subscription?
     $pay_page_subscription = false;
     if ($this->get_gateway()->is_pay_page_gateway()) {
         $order_id = $this->get_gateway()->get_checkout_pay_page_order_id();
         if ($order_id) {
             $pay_page_subscription = WC_Subscriptions_Order::order_contains_subscription($order_id);
         }
     }
     if (WC_Subscriptions_Cart::cart_contains_subscription() || WC_Subscriptions_Change_Payment_Gateway::$is_request_to_change_payment || $pay_page_subscription) {
         $force_tokenization = true;
     }
     return $force_tokenization;
 }
 /**
  * Only display gateways which support changing payment method when paying for a failed renewal order or
  * when requesting to change the payment method.
  *
  * @param array $available_gateways The payment gateways which are currently being allowed.
  * @since 1.4
  */
 public static function get_available_payment_gateways($available_gateways)
 {
     if (isset($_GET['change_payment_method']) || WC_Subscriptions_Cart::cart_contains_failed_renewal_order_payment()) {
         foreach ($available_gateways as $gateway_id => $gateway) {
             if (!method_exists($gateway, 'supports') || true !== $gateway->supports('subscription_payment_method_change')) {
                 unset($available_gateways[$gateway_id]);
             }
         }
     }
     return $available_gateways;
 }
 /**
  * Display the recurring totals for items in the cart
  *
  * @since 2.0
  */
 public static function display_recurring_totals()
 {
     if (self::cart_contains_subscription()) {
         // We only want shipping for recurring amounts, and they need to be calculated again here
         self::$calculation_type = 'recurring_total';
         $shipping_methods = array();
         $carts_with_multiple_payments = 0;
         // Create new subscriptions for each subscription product in the cart (that is not a renewal)
         foreach (WC()->cart->recurring_carts as $recurring_cart_key => $recurring_cart) {
             // Cart contains more than one payment
             if (0 != $recurring_cart->next_payment_date) {
                 $carts_with_multiple_payments++;
                 // Create shipping packages for each subscription item
                 if (self::cart_contains_subscriptions_needing_shipping()) {
                     $chosen_shipping_methods = WC()->session->get('chosen_shipping_methods', array());
                     // Don't remove any subscriptions with a free trial from the shipping packages
                     foreach ($recurring_cart->get_shipping_packages() as $base_package) {
                         $package = WC()->shipping->calculate_shipping_for_package($base_package);
                         // Only display the costs for the chosen shipping method
                         foreach ($chosen_shipping_methods as $package_key) {
                             if (isset($package['rates'][$package_key])) {
                                 $shipping_methods[$recurring_cart_key] = $package['rates'][$package_key];
                             }
                         }
                     }
                 }
             }
         }
         if ($carts_with_multiple_payments >= 1) {
             wc_get_template('checkout/recurring-totals.php', array('shipping_methods' => $shipping_methods, 'recurring_carts' => WC()->cart->recurring_carts, 'carts_with_multiple_payments' => $carts_with_multiple_payments), '', plugin_dir_path(WC_Subscriptions::$plugin_file) . 'templates/');
         }
         self::$calculation_type = 'none';
     }
 }
 /**
  * Load handlers for cart and orders after WC Cart is loaded.
  */
 public function init_handlers()
 {
     // Disable if no seller ID
     if (empty($this->settings['seller_id']) || $this->settings['enabled'] == 'no') {
         return;
     }
     // Disable for subscriptions until supported
     if (!is_admin() && class_exists('WC_Subscriptions_Cart') && WC_Subscriptions_Cart::cart_contains_subscription() && 'no' === get_option(WC_Subscriptions_Admin::$option_prefix . '_accept_manual_renewals', 'no')) {
         return;
     }
     add_action('wp_enqueue_scripts', array($this, 'scripts'));
     if ($this->settings['cart_button_display_mode'] == 'button') {
         add_action('woocommerce_proceed_to_checkout', array($this, 'checkout_button'), 12);
     } elseif ($this->settings['cart_button_display_mode'] == 'banner') {
         add_action('woocommerce_before_cart', array($this, 'checkout_message'), 5);
     }
     add_action('woocommerce_before_checkout_form', array($this, 'checkout_message'), 5);
     add_action('before_woocommerce_pay', array($this, 'checkout_message'), 5);
     if (empty($this->reference_id)) {
         return;
     }
     //add_filter( 'woocommerce_cart_needs_payment', '__return_true' );
     add_action('woocommerce_checkout_before_customer_details', array($this, 'payment_widget'), 20);
     add_action('woocommerce_checkout_before_customer_details', array($this, 'address_widget'), 10);
     add_action('woocommerce_checkout_init', array($this, 'remove_checkout_fields'));
     add_filter('woocommerce_available_payment_gateways', array($this, 'remove_gateways'));
     add_action('woocommerce_checkout_update_order_review', array($this, 'get_customer_details'));
 }
 /**
  * During the checkout process, force registration when the cart contains a subscription.
  *
  * @since 1.1
  */
 public static function force_registration_during_checkout($woocommerce_params)
 {
     if (WC_Subscriptions_Cart::cart_contains_subscription() && !is_user_logged_in()) {
         $_POST['createaccount'] = 1;
     }
 }
 /**
  * Function to apply Gift Certificate's credit to cart
  */
 public function apply_smart_coupon_to_cart()
 {
     $this->global_wc()->cart->smart_coupon_credit_used = array();
     $cart_contains_subscription = false;
     if (class_exists('WC_Subscriptions_Cart') && WC_Subscriptions_Cart::cart_contains_subscription()) {
         $cart_contains_subscription = true;
     }
     if ($cart_contains_subscription) {
         $calculation_type = WC_Subscriptions_Cart::get_calculation_type();
         if ($calculation_type == 'recurring_total') {
             return;
         }
     }
     if ($this->global_wc()->cart->applied_coupons) {
         foreach ($this->global_wc()->cart->applied_coupons as $code) {
             $smart_coupon = new WC_Coupon($code);
             if ($smart_coupon->is_valid() && $smart_coupon->discount_type == 'smart_coupon') {
                 $order_total = $this->global_wc()->cart->cart_contents_total + $this->global_wc()->cart->tax_total + $this->global_wc()->cart->shipping_tax_total + $this->global_wc()->cart->shipping_total;
                 if ($this->global_wc()->cart->discount_total != 0 && $this->global_wc()->cart->discount_total + $smart_coupon->amount > $order_total) {
                     $smart_coupon->amount = $order_total - $this->global_wc()->cart->discount_total;
                 } elseif ($smart_coupon->amount > $order_total) {
                     $smart_coupon->amount = $order_total;
                 }
                 $this->global_wc()->cart->discount_total = $this->global_wc()->cart->discount_total + $smart_coupon->amount;
                 if ($cart_contains_subscription) {
                     WC_Subscriptions_Cart::increase_coupon_discount_amount($code, $smart_coupon->amount);
                 }
                 $this->global_wc()->cart->smart_coupon_credit_used[$code] = $smart_coupon->amount;
                 //Code for displaying the price label for the store credit coupons
                 if (empty($this->global_wc()->cart->coupon_discount_amounts)) {
                     $this->global_wc()->cart->coupon_discount_amounts = array();
                 }
                 $this->global_wc()->cart->coupon_discount_amounts[$code] = $smart_coupon->amount;
             }
         }
     }
 }
 /**
  * Hid the trial period for a synchronised subscription unless the related product actually has a trial period (because
  * we use a trial period to set the original order totals to 0).
  *
  * Deprecated because free trials are no longer displayed on cart totals, only the first renewal date is displayed.
  *
  * @since 1.5
  * @deprecated 2.0
  */
 public static function maybe_hide_free_trial($subscription_details)
 {
     _deprecated_function(__METHOD__, '2.0');
     $cart_item = self::cart_contains_synced_subscription();
     if (false !== $cart_item && !self::is_product_prorated($cart_item['data'])) {
         // cart contains a sync
         $product_id = WC_Subscriptions_Cart::get_items_product_id($cart_item);
         if (wc_price(0) == $subscription_details['initial_amount'] && 0 == $subscription_details['trial_length']) {
             $subscription_details['initial_amount'] = '';
         }
     }
     return $subscription_details;
 }