I'm trying to increase shipping cost based on number of categories in cart (count). So far I have this:
add_filter( 'woocommerce_package_rates', 'vh_wc_shipping_costs', 20 );
function vh_wc_shipping_costs( $rates ) {
$increase_cost = 50;
$cat_ids = array();
$count = 0;
foreach ( wc()->cart->get_cart() as $cart_item_key => $cart_item ) {
$cat_ids = array_merge(
$cat_ids,
(array) $cart_item['data']->get_category_ids()
);
$count = count( $cat_ids );
}
$i=0;
if ( $count >= 1 ) {
foreach ( $rates as $rate_key => $rate ) {
$i++; $i <= $count;
// Excluding free shipping methods
if ( 'free_shipping' !== $rate->method_id ) {
// Get old cost
$old_cost = $rates[ $rate_key ]->cost;
// Set rate cost
$rates[ $rate_key ]->cost = $old_cost + $increase_cost;
}
}
}
return $rates;
}
But it doesn't increment the shipping cost for every extra category for some reason. Also, I would like to add a note to the extra cost. Any Suggestion is appreciated.
As the rule on StackOverFlow is one question at the time, I will only answer the first question related to your code.
The following code will add an extra shipping cost for each additional product category found in cart (so not for the first one):
add_filter( 'woocommerce_package_rates', 'filter_shipping_rates_costs', 10, 2 );
function filter_shipping_rates_costs( $rates, $package ) {
$step_cost = 50;
$term_ids = array();
// Loop through cart items for the current shipping package
foreach( $package['contents'] as $cart_item ){
$term_ids = array_merge(
$term_ids,
(array) $cart_item['data']->get_category_ids()
);
}
$terms_count = count( $term_ids );
// Loop through shipping rates
foreach ( $rates as $rate_key => $rate ) {
// Excluding free shipping methods
if ( 'free_shipping' !== $rate->method_id && $terms_count > 1 ) {
// Set rate cost
$rates[$rate_key]->cost = $rate->cost + ($step_cost * ($terms_count - 1));
}
}
return $rates;
}
Now if you want to add an extra shipping cost for each category found in cart, use the following:
add_filter( 'woocommerce_package_rates', 'filter_shipping_rates_costs', 10, 2 );
function filter_shipping_rates_costs( $rates, $package ) {
$step_cost = 50;
$term_ids = array();
// Loop through cart items for the current shipping package
foreach( $package['contents'] as $cart_item ){
$term_ids = array_merge(
$term_ids,
(array) $cart_item['data']->get_category_ids()
);
}
$terms_count = count( $term_ids );
// Loop through shipping rates
foreach ( $rates as $rate_key => $rate ) {
// Excluding free shipping methods
if ( 'free_shipping' !== $rate->method_id && $terms_count > 0 ) {
// Set rate cost
$rates[$rate_key]->cost = $rate->cost + ($step_cost * $terms_count);
}
}
return $rates;
}
Code goes in functions.php file of your active child theme (or active theme). Tested and works.
Refresh the shipping caches:
- This code is already saved on your functions.php file.
- In a shipping zone settings, disable / save any shipping method, then enable back / save.
You are done and you can test it.