Filters the calculation of shipping rates for a package. Calculates each shipping methods cost. Rates are stored in the session based on the package hash to avoid re-calculation every page load.
Available Parameters
array $package['rates'] - available rates
array $package - Package of cart items
Source code: woocommerce_package_rates
Code Example 1
Following code works in association with Woocommerce Pickup Locations plugin. If pickup location is activated and any of the products in cart is from a certain defined category (or categories), we will only show pickup location as the only shipping method, hiding all other shipping methods.
function careless_local_pickup_for_pickup_only_category( $rates, $package ) {
//lets define our categories - we are using category slug
$our_categories = array ( 'pickup-only', 'quick-pickup' );//MODIFY as needed
$found = false;
//check all cart items, if any of them are from our above defined categories or not
//finding only one will be enough
foreach ( $package['contents'] as $item ) {
if ( has_term( $our_categories, 'product_cat', $item['product_id'] ) ) {
$found = true;
break;
}
}
$rates_arr = array();
if ( !$found ) {
return $rates;
}
foreach ( $rates as $rate_id => $rate ) {
//pickup-location-method = name/id of the local pickup shipping method via "Woocommerce Pickup Location"s plugin
if ( 'pickup-location-method' === $rate->method_id ) {
$rates_arr [ $rate_id ] = $rate;
}
}
if ( !empty( $rates_arr ) ) {
return $rates_arr;
}
return $rates;
}
add_filter( 'woocommerce_package_rates', 'careless_local_pickup_for_pickup_only_category', 100, 2 );
Code Example 2
Unset flat rate
shipping if cart has any product from a specific shipping class and shipping zone is a specific shipping zone.
function careless_shipping_zone_and_class_delivery_options( $rates, $package ) {
//lets define our shipping zone id
$our_shipping_zone_id = 1;//MODIFY as needed
//our shipping class id
$our_shipping_class_id = 75;//MODIFY as needed
//get shipping zone of the package
$shipping_zone = wc_get_shipping_zone( $package );
//get shipping zone id from shipping zone
$zone_id = $shipping_zone->get_id();
//let's see if package has our defined shipping zone
if ( $zone_id !== $our_shipping_zone_id ) {
return $rates;
}
//now we go through cart items and check for our shipping class
foreach( WC()->cart->get_cart() as $cart_item ) {
$product = $cart_item[ 'data' ];//WC_Product object
$shipping_class_id = $product->get_shipping_class_id();
if( isset($rates['flat_rate:3']) && $shipping_class_id === $our_shipping_class_id ) {
unset( $rates['flat_rate:3'] );//remove flat rate shipping
break;
}
}
return $rates;
}
add_filter( 'woocommerce_package_rates', 'careless_shipping_zone_and_class_delivery_options', 10, 2 );
Code Example 3
Hide other shipping options/rates if free shipping is available.
function careless_hide_shipping_when_free_is_available( $rates ) {
$rates_arr = array();
foreach ( $rates as $rate_id => $rate ) {
if ( 'free_shipping' === $rate->method_id ) {
$rates_arr[ $rate_id ] = $rate;
break;
}
}
if ( !empty( $rates_arr ) ) {
return $rates_arr;
}
return $rates;
}
add_filter( 'woocommerce_package_rates', 'careless_hide_shipping_when_free_is_available', 100 );
Code Example 4
Only show local pickup and free shipping, and hide other shipping options/rates, if both of them are available.
function careless_free_and_local_shipping( $rates ) {
$rates_arr = array();
foreach ( $rates as $rate_id => $rate ) {
//only free_shipping and local_pickup
if ( 'free_shipping' === $rate->method_id || 'local_pickup' === $rate->method_id ) {
$rates_arr[ $rate_id ] = $rate;
}
}
if ( ! empty( $rates_arr ) ) {
return $rates_arr;
}
return $rates;
}
add_filter( 'woocommerce_package_rates', 'careless_free_and_local_shipping', 100 );
All example code goes in the functions.php
file of your active theme.