2

I am trying to get it so that if a customer were to add a coupon code (Any of them) the Free Shipping option would go away and the flat rate fee would be implemented. - You would think this would be an easy thing to implement, there would be 100's of plugins and ways described to do this, but I have not found any. I do not want to pay $89 for the plugin to do this one thing

A side bonus would be if they are using a coupon but are spending over $249 they can still qualify for Free shipping. I read some where how to do this, but it requires me to get the POST ID, which with the latest WooCommerce is not possible like it was before, I do not know the shipping ID so I am at a lost Here is the code

add_filter( 'woocommerce_shipping_packages', function( $packages ) {
$applied_coupons = WC()->session->get( 'applied_coupons', array() );
if ( ! empty( $applied_coupons ) ) {
$free_shipping_id = 'free_shipping:2';
unset($packages[0]['rates'][ $free_shipping_id ]);
}
return $packages;
} );

Thanks

Edited

add_filter( 'woocommerce_package_rates', 'coupons_removes_free_shipping', 
10, 2 );
function coupons_removes_free_shipping( $rates, $package ){
if ( is_admin() && ! defined( 'DOING_AJAX' ) )
    return $rates;

$min_total      = 250; // Minimal subtotal allowing free shipping

// Get needed cart totals
$total_excl_tax = WC()->cart->get_total();
$discount_excl_tax = WC()->cart->get_discount_total();


// Calculating the discounted subtotal including taxes
$discounted_subtotal_incl_taxes = $total_excl_tax - $discount_excl_tax;

$applied_coupons   = WC()->cart->get_applied_coupons();

if( sizeof($applied_coupons) > 0 &&  $discounted_subtotal_incl_taxes < $min_total ) {
    foreach ( $rates as $rate_key => $rate ){
        // Targeting "Free shipping"
        if( 'free_shipping' === $rate->method_id  ){
            unset($rates[$rate_key]);
        }
    }
}
return $rates;

}

KangOnRails
  • 143
  • 1
  • 11

2 Answers2

3

The below code will enable "Free shipping" for applied coupons only if cart subtotal reaches a minimal amount (discounted including taxes):

add_filter( 'woocommerce_package_rates', 'coupons_removes_free_shipping', 10, 2 );
function coupons_removes_free_shipping( $rates, $package ){
    if ( is_admin() && ! defined( 'DOING_AJAX' ) )
        return $rates;

    $min_subtotal      = 250; // Minimal subtotal allowing free shipping
    
    // Get needed cart subtotals
    $subtotal_excl_tax = WC()->cart->get_subtotal();
    $subtotal_incl_tax = $subtotal_excl_tax + WC()->cart->get_subtotal_tax();
    $discount_excl_tax = WC()->cart->get_discount_total();
    $discount_incl_tax = $discount_excl_tax + WC()->cart->get_discount_tax();
    
    // Calculating the discounted subtotal including taxes
    $discounted_subtotal_incl_taxes = $subtotal_incl_tax - $discount_incl_tax;
    
    $applied_coupons   = WC()->cart->get_applied_coupons();

    if( sizeof($applied_coupons) > 0 && $discounted_subtotal_incl_taxes < $min_subtotal ){
        foreach ( $rates as $rate_key => $rate ){
            // Targeting "Free shipping"
            if( 'free_shipping' === $rate->method_id  ){
                unset($rates[$rate_key]);
            }
        }
    }
    return $rates;
}

Code goes in function.php file of your active child theme (or active theme). Tested and work.


Original answer:

The below code will remove "Free shipping" shipping methods when any coupon is applied without any settings need. There is some mistakes in your actual code. Try the following:

add_filter( 'woocommerce_package_rates', 'coupons_removes_free_shipping', 10, 2 );
function coupons_removes_free_shipping( $rates, $package ){
    if ( is_admin() && ! defined( 'DOING_AJAX' ) )
        return $rates;

    $applied_coupons = WC()->cart->get_applied_coupons();

    if( sizeof($applied_coupons) > 0 ){
        // Loop through shipping rates
        foreach ( $rates as $rate_key => $rate ){
            // Targeting "Free shipping" only
            if( 'free_shipping' === $rate->method_id  ){
                unset($rates[$rate_key]); // Removing current method
            }
        }
    }
    return $rates;
}

Code goes in function.php file of your active child theme (or active theme). Tested and works.

LoicTheAztec
  • 229,944
  • 23
  • 356
  • 399
  • Awesome, Thanks so much.. Would you also know how to go about making it so that if coupon is applied but the After discount total is over 249 to have free shipping. - I am still learning all the hooks for woocommerce – KangOnRails Oct 21 '18 at 11:42
  • @KangOnRails I have updated my answer where free shipping will be enabled for a minimal subtotal amount… – LoicTheAztec Oct 21 '18 at 12:54
  • This is why I love the programming community. Thanks so much for the help. – KangOnRails Oct 22 '18 at 05:54
  • So that work flawlessly, but for subtotals, I need the Total to be 250 minimum.. I tried to do this (edited in original post) - but it is not working.,.. – KangOnRails Oct 22 '18 at 08:57
  • @KangOnRails You can not make calculations on total… only on subtotals – LoicTheAztec Oct 22 '18 at 09:03
  • This code should work taken the subtotal and minus the discount as long as that is 250 or more the coupon should disappear, but it didn't. Also the () on the second if statement between the && I had to remove to get the code to work. – KangOnRails Oct 22 '18 at 13:12
  • @KangOnRails Oh yes… sorry I have removed that too… But the idea is there. You can make it as needed taking the right subtotals. All WC_Cart methods are available on [this documentation](https://docs.woocommerce.com/wc-apidocs/class-WC_Cart.html) – LoicTheAztec Oct 22 '18 at 13:40
  • Thanks, now that you got it started I'll figure out the rest. Or just use the other code, either way... Thanks. I def need to go over that documentation – KangOnRails Oct 22 '18 at 18:03
  • @LoicTheAztec Edit this line please: $discount_incl_tax = ````$discount_total + WC()->cart->get_discount_tax();``` to ```$discount_incl_tax = $discount_excl_tax + WC()->cart->get_discount_tax();``` – jMike Aug 12 '23 at 08:13
  • @jMike Done… You may remove this very useful comment as it is not any more needed. Thank you. – LoicTheAztec Aug 12 '23 at 09:29
0

By default WooCommerce will still allow a free shipping method to be selected if the coupon code is filled in and active in the shopping cart. The following code can be added to your child’s functions.php page to hook in and hide any free shipping option if a coupon code is used.

add_filter( 'woocommerce_shipping_packages', function( $packages ) {
$applied_coupons = WC()->session->get( 'applied_coupons', array() );
if ( ! empty( $applied_coupons ) ) {
$free_shipping_id = 'free_shipping:2';
unset($packages[0]['rates'][ $free_shipping_id ]);
}
return $packages;
} );

Simply change the $free_shipping_id in the above code to the ID of your free shipping option. You may find your ID by going to WooCommerce > Settings > Shipping Options and then click on your Free Shipping option. The post ID will be in the URL of the page that displays the Free Shipping details/settings.

i.e www.yourdomain.com/wp-admin/post.php?post=40107&action=edit

Where 40107 is the shipping ID in this example. Your shipping ID will be different.

devterm
  • 32
  • 7
  • This is where I got the above code from, when I go into Woo > Settings > Shipping Options, I do not see any Post ID.. That is why I came here – KangOnRails Oct 21 '18 at 11:32