Do not sell or share my personal information Skip to content

Free Shipping Customizations

Free Shipping: Advanced Settings/Customization

Overview

By default, WooCommerce shows all shipping methods that match the customer and the cart contents. This means Free Shipping also shows along with Flat Rate and other Shipping Methods.

The functionality to hide all other methods, and only show Free Shipping, requires either custom PHP code or a plugin/extension.

Adding code

Before adding snippets, clear your WooCommerce cache. Go to WooCommerce > System Status > Tools > WooCommerce Transients > Clear transients.

Add this code to your child theme’s functions.php, or via a plugin that allows custom functions to be added. Please don’t add custom code directly to a parent theme’s functions.php as changes are entirely erased when a parent theme updates.

Code Snippets

Enabling or Disabling Free Shipping via Hooks

You can hook into the is_available function of the free shipping method.

		return apply_filters( 'woocommerce_shipping_' . $this->id . '_is_available', $is_available );

	

This means you can use add_filter() on woocommerce_shipping_free_shipping_is_available and return true or false.

How do I only show Free Shipping?

The following snippet hides everything but free_shipping, if it’s available and the customer’s cart qualifies.

		/**
 * Hide shipping rates when free shipping is available.
 * Updated to support WooCommerce 2.6 Shipping Zones.
 *
 * @param array $rates Array of rates found for the package.
 * @return array
 */
function my_hide_shipping_when_free_is_available( $rates ) {
	$free = array();
	foreach ( $rates as $rate_id => $rate ) {
		if ( 'free_shipping' === $rate->method_id ) {
			$free[ $rate_id ] = $rate;
			break;
		}
	}
	return ! empty( $free ) ? $free : $rates;
}
add_filter( 'woocommerce_package_rates', 'my_hide_shipping_when_free_is_available', 100 );

	

How do I only show Local Pickup and Free Shipping?

The snippet below hides everything but free_shipping and local_pickup, if it’s available and the customer’s cart qualifies.

		
/**
 * Hide shipping rates when free shipping is available, but keep "Local pickup" 
 * Updated to support WooCommerce 2.6 Shipping Zones
 */

function hide_shipping_when_free_is_available( $rates, $package ) {
	$new_rates = array();
	foreach ( $rates as $rate_id => $rate ) {
		// Only modify rates if free_shipping is present.
		if ( 'free_shipping' === $rate->method_id ) {
			$new_rates[ $rate_id ] = $rate;
			break;
		}
	}

	if ( ! empty( $new_rates ) ) {
		//Save local pickup if it's present.
		foreach ( $rates as $rate_id => $rate ) {
			if ('local_pickup' === $rate->method_id ) {
				$new_rates[ $rate_id ] = $rate;
				break;
			}
		}
		return $new_rates;
	}

	return $rates;
}

add_filter( 'woocommerce_package_rates', 'hide_shipping_when_free_is_available', 10, 2 );

	

Only show free shipping in all states except…

This snippet results in showing only free shipping in all states except the exclusion list. It hides free shipping if the customer is in one of the states listed:

		/**
 * Hide ALL shipping options when free shipping is available and customer is NOT in certain states
 *
 * Change $excluded_states = array( 'AK','HI','GU','PR' ); to include all the states that DO NOT have free shipping
 */
add_filter( 'woocommerce_package_rates', 'hide_all_shipping_when_free_is_available' , 10, 2 );

/**
 * Hide ALL Shipping option when free shipping is available
 *
 * @param array $available_methods
 */
function hide_all_shipping_when_free_is_available( $rates, $package ) {
 
	$excluded_states = array( 'AK','HI','GU','PR' );
	if( isset( $rates['free_shipping'] ) AND !in_array( WC()->customer->shipping_state, $excluded_states ) ) :
		// Get Free Shipping array into a new array
		$freeshipping = array();
		$freeshipping = $rates['free_shipping'];
 
		// Empty the $available_methods array
		unset( $rates );
 
		// Add Free Shipping back into $avaialble_methods
		$rates = array();
		$rates[] = $freeshipping;
 
	endif;
 
	if( isset( $rates['free_shipping'] ) AND in_array( WC()->customer->shipping_state, $excluded_states ) ) {
 
		// remove free shipping option
		unset( $rates['free_shipping'] );
 
	}

	return $rates;
}

	

Enable Shipping Methods on a per Class / Product Basis, split orders, or other scenarios?

Need more flexibility? Take a look at our premium Shipping Method extensions.

Last updated: August 21, 2024