You can setup multiple shipping methods including Free Shipping, Flat Rate and Local Pickup in WooCommerce.
It's reasonable to hide other paid shipping options if Free Shipping is available. WooCommerce shows by default all shipping rates which match a given shipping zone. You can hide all other shipping rates when Free Shipping available by using the following code:
add_filter( 'woocommerce_package_rates', 'bbloomer_unset_shipping_when_free_is_available_in_zone', 10, 2 );
function bbloomer_unset_shipping_when_free_is_available_in_zone( $rates, $package ) {
// Only unset rates if free_shipping is available
if ( isset( $rates['free_shipping:8'] ) ) {
unset( $rates['flat_rate:1'] );
}
return $rates;
}
// Source: https://businessbloomer.com/?p=260
This code still works well. However, the problem occurs when you set Local Pickup as well. If you use the above code, the Local Pickup method will be also removed and users can choose only Free Shipping.
In this situation, you might want to hide specific shipping method only (in this case, "Flat Rate") if Free Shipping is available. For this, you need to modify the above code to exclude paid shipping options. If you set three Shipping Methods: Flat Rate, Free Shipping and Local Pickup and you want to show Free Shipping and Local Pickup in case that Free Shipping is available, you can use the following code:
function woo_hide_shipping_when_free_is_available($rates) {
$free = array();
foreach ($rates as $rate_id => $rate) {
if ('free_shipping' === $rate->method_id) {
foreach($rates as $rate_id => $rate) {
if ('flat_rate' === $rate->method_id )
unset($rates[ $rate_id ]);
}
break;
}
}
return !empty( $free ) ? $free : $rates;
}
add_filter('woocommerce_package_rates', 'woo_hide_shipping_when_free_is_available', 100);
If you want to show Local Pickup with hiding paid shipping options when Free Shipping is available, you can try the above code. Of course, I recommend that you install a child theme and put the code into the function file (functions.php) of the child theme.