Changing WooCommerce cart price after applied coupon code Changing WooCommerce cart price after applied coupon code wordpress wordpress

Changing WooCommerce cart price after applied coupon code


This is not really possible … Why? … Because (the logic):

  1. You have the product price
  2. Then the coupon discount is applied to that price (afterwards)
    ==> if you change the product price, the coupon is will be applied to that changed price

What you can do instead:

  1. You don't change product price
  2. if entered the coupon is applied and …
  3. If "option2" product is added to cart:
  4. Apply a custom discount (a negative fee) based on the product price added after using WC_cart add_fee() method…

For this last case you will have to fine tune your additional discount.
If the coupon has not been applied or it's removed there is no additional discount.

Your custom function will be hooked in woocommerce_cart_calculate_fees action hook instead:

add_action( 'woocommerce_cart_calculate_fees', 'option2_additional_discount', 10, 1 );function option2_additional_discount( $cart_obj ) {    if ( is_admin() && ! defined( 'DOING_AJAX' ) )        return;    $discount = 0;    $applied_coupons = $cart_obj->get_applied_coupons();    foreach ( $cart_obj->get_cart() as $item_values ) {        if( 'option2' == $item_values['custom_options'] && !empty($applied_coupons) ){            $product_id = $item_values['product_id'];            $percentage = get_post_meta( $product_id , 'percentage', true );            $quantity = $item_values['quantity'];            $product_reg_price = $item_values['data']->regular_price;            $line_total = $item_values['line_total'];            $line_subtotal = $item_values['line_subtotal'];            $percentage = 90;            ## ----- CALCULATIONS (To Fine tune) ----- ##            $item_discounted_price = ($percentage / 100) *  $product_reg_price * $item_values['quantity'];            // Or Besed on line item subtotal            $discounted_price = ($percentage / 100) * $line_subtotal;            $discount += $product_reg_price - $item_discounted_price;        }    }    if($discount != 0)        $cart_obj->add_fee( __( 'Option2 discount', 'woocommerce' ) , - $discount );}

Code goes in function.php file of your active child theme (or theme) or also in any plugin file.

This code is tested and works.


Adding a negative fee using the WC_Cart->add_fee() method wasn't working for me. When i check the WC Cart class, it even states you are not allowed to use a negative ammount.

See the docs.

I did the following:

  • create a placeholder coupon with a 'secure' code, e.g. custom_discount_fjgndfl28. Set a discount ammount of 0, so when somebody (somehow) uses this coupon outside your program the discount is still 0.
  • Use filter woocommerce_get_shop_coupon_data, and set all the coupon data you want for that coupon/session.
  • Hook into woocommerce_before_calculate_totals and set your custom coupon to the cart.
  • At this point the Cart should calculate everything correctly. And when it becomes an order, it also has the correct discount ammount.
  • Note: the coupon code is also used as a label in some templates. Use filter woocommerce_cart_totals_coupon_label to change it.

Example functions:

/** * NOTE: All the hooks and filters below have to be called from your own * does_it_need_custom_discount() function. I used the 'wp' hook for mine. * Do not copy/paste this to your functions.php.**/add_filter('woocommerce_get_shop_coupon_data', 'addVirtualCoupon', 10, 2);function addVirtualCoupon($unknown_param, $curr_coupon_code) {    if($curr_coupon_code == 'custom_discount_fjgndfl28') {      // possible types are: 'fixed_cart', 'percent', 'fixed_product' or 'percent_product.      $discount_type = 'fixed_cart';       // how you calculate the ammount and where you get the data from is totally up to you.      $amount = $get_or_calculate_the_coupon_ammount;      if(!$discount_type || !$amount) return false;        $coupon = array(            'id' => 9999999999 . rand(2,9),            'amount' => $amount,            'individual_use' => false,            'product_ids' => array(),            'exclude_product_ids' => array(),            'usage_limit' => '',            'usage_limit_per_user' => '',            'limit_usage_to_x_items' => '',            'usage_count' => '',            'expiry_date' => '',            'apply_before_tax' => 'yes',            'free_shipping' => false,            'product_categories' => array(),            'exclude_product_categories' => array(),            'exclude_sale_items' => false,            'minimum_amount' => '',            'maximum_amount' => '',            'customer_email' => '',            'discount_type' => $discount_type,        );        return $coupon;    }}add_action('woocommerce_before_calculate_totals', 'applyFakeCoupons');function applyFakeCoupons() {  global $woocommerce;  // $woocommerce->cart->remove_coupons(); remove existing coupons if needed.  $woocommerce->cart->applied_coupons[] = $this->coupon_code; }add_filter( 'woocommerce_cart_totals_coupon_label', 'cart_totals_coupon_label', 100, 2 );function cart_totals_coupon_label($label, $coupon) {    if($coupon) {      $code = $coupon->get_code();      if($code == 'custom_discount_fjgndfl28') {        return 'Your custom coupon label';      }    }    return $label;}

Please Note: i copied these functions out of a class that handles much more, it's only to help you get going.