I currently have WooCommerce setup to allow free shipping on orders over a certain amount. However, I also have local pickup available and would like to allow BOTH if over a certain amount.
I have the following code to remove the other rates, however it also doesn’t keep the local pickup option.
function fd_shipping_rates( $rates, $package ) {
$all_free_rates = array();
foreach ( $rates as $rate_id => $rate ) {
if ( 'free_shipping' === $rate->method_id ) {
$all_free_rates[ $rate_id ] = $rate;
break;
}
}
if ( empty( $all_free_rates )) {
return $rates;
} else {
return $all_free_rates;
}
}
add_filter( 'woocommerce_package_rates', 'fd_shipping_rates', 10, 2 );
Any help regarding this is much appreciated! I am looking for a code solution only as I am looking to minimise unneeded plugins.
EDIT: I recently found this article on WooCommerce Docs website regarding this exact issue.
Answers:
Thank you for visiting the Q&A section on Magenaut. Please note that all the answers may not help you solve the issue immediately. So please treat them as advisements. If you found the post helpful (or not), leave a comment & I’ll get back to you as soon as possible.
Method 1
The following code will disable other shipping methods excluding “Local Pickup” when “Free shipping” shipping method is available.
Required: Free shipping method need to be set with a minimal order amount.
add_filter( 'woocommerce_package_rates', 'show_hide_shipping_methods', 100 );
function show_hide_shipping_methods( $rates ) {
$free_rate_id = '';
$other_rates_ids = [];
// Loop through available shipping rates
foreach ( $rates as $rate_id => $rate ) {
if ( 'free_shipping' === $rate->method_id ) {
$free_rate_id = $rate_id; // grab "Free shipping" rate ID
}
// Get all other rates Ids (excluding "Free shipping" and "Local pickup" methods)
if ( ! in_array( $rate->method_id, ['free_shipping', 'local_pickup'] ) ) {
$other_rates_ids[] = $rate_id;
}
}
// Disable All other rates Ids when "Free shipping" is available (excl. "Local pickup")
if ( ! empty($free_rate_id) && isset($rates[$free_rate_id]) && sizeof($other_rates_ids) > 0 ) {
foreach ( $other_rates_ids as $rate_id ) {
unset($rates[$rate_id]);
}
}
return $rates;
}
Code goes in functions.php file of your active child theme (or active theme). Tested and work.
Refresh the shipping caches: (required)
- This code is already saved on your active theme’s function.php file.
- The cart is empty
- In a shipping zone settings, disable / save any shipping method, then enable back / save.
All methods was sourced from stackoverflow.com or stackexchange.com, is licensed under cc by-sa 2.5, cc by-sa 3.0 and cc by-sa 4.0