Kevin
Kevin

Reputation: 157

Enable free shipping for products on sale in WooCommerce

In WooCommerce, is it possible to automatically apply free shipping to any product that is on sale?

Every month we have different products on sale, and all sale products automatically qualify for free shipping. For sale products I currently have to manually change the shipping class to "free shipping" and then back to "standard shipping" when the sale is over. I would like to automate this so any product that is on sale automatically qualifies the order for free shipping.

I can apply free shipping per product ID, but I have not been able to figure out applying this to sale products.

function wcs_my_free_shipping( $is_available ) {
    global $woocommerce;
 
    // set the product ids that are eligible
    $eligible = array( '360' );
 
    // get cart contents
    $cart_items = $woocommerce->cart->get_cart();

    // loop through the items looking for one in the eligible array
    foreach ( $cart_items as $key => $item ) {
        if( in_array( $item['product_id'], $eligible ) ) {
            return true;
        }
    }
 
    // nothing found return the default value
    return $is_available;
}
add_filter( 'woocommerce_shipping_free_shipping_is_available', 'wcs_my_free_shipping', 20 );

Upvotes: 3

Views: 959

Answers (1)

7uc1f3r
7uc1f3r

Reputation: 29614

To make free shipping available, you could use is_on_sale();

function filter_woocommerce_shipping_free_shipping_is_available( $is_available, $package, $shipping_method ) {  
    // Loop through cart items
    foreach( $package['contents'] as $cart_item ) {
        // On sale
        if ( $cart_item['data']->is_on_sale() ) {
            // True
            $is_available = true;
            
            // Notice
            $notice = __( 'free shipping', 'woocommerce' );
            
            // Break loop
            break;
        }
    }
    
    // Display notice
    if ( isset( $notice ) ) {
        wc_add_notice( $notice, 'notice' );
    }
 
    // Return
    return $is_available;
}
add_filter( 'woocommerce_shipping_free_shipping_is_available', 'filter_woocommerce_shipping_free_shipping_is_available', 10, 3 );

Optional: Hide other shipping methods when free shipping is available

function filter_woocommerce_package_rates( $rates, $package ) {
    // Empty array
    $free = array();

    // Loop trough
    foreach ( $rates as $rate_id => $rate ) {
        if ( $rate->method_id === 'free_shipping' ) {
            $free[ $rate_id ] = $rate;
            
            // Break loop
            break;
        }
    }
    
    return ! empty( $free ) ? $free : $rates;
}
add_filter( 'woocommerce_package_rates', 'filter_woocommerce_package_rates', 10, 2 );

Upvotes: 3

Related Questions