Based on Set custom shipping rates programmatically in Woocommerce 3 answer code, I modified it in order to add a discount on shipping rates for each seller.
add_filter( 'woocommerce_package_rates', 'custom_shipping_methods', 10, 2 );
function custom_shipping_methods( $rates, $package ) {
$reduction_cost_percentage = 30; // Discount percentage
foreach( WC()->cart->get_cart() as $cart_item ){
$in_cart_product_id = $cart_item['product_id'];
$cart_seller_id = get_post_field('post_author', $in_cart_product_id);
$cart_seller_meta = get_userdata($cart_seller_id);
$cart_seller_roles = $cart_seller_meta->roles;
if($cart_seller_roles[0] == 'seller'){
foreach( $rates as $rate_key => $rate ){
if( $rate->method_id != 'free_shipping'){
$rates[$rate_key]->cost = $rates[$rate_key]->cost * ((100-$reduction_cost_percentage) / 100);
return $rates;
}
}
}
}
}
Now I want to exclude this discount from a certain role for example seller_2
. How can I do this?
There are some mistakes and oversights in your code, try the following instead:
add_filter( 'woocommerce_package_rates', 'custom_shipping_methods', 10, 2 );
function custom_shipping_methods( $rates, $package ) {
// Loop through cart items for the current package
foreach( $package['contents'] as $cart_item ){
$seller_id = get_post_field('post_author', $cart_item['product_id']);
$seller_data = get_userdata($seller_id);
// Excluding product 'seller' user role
if ( ! empty($seller_data) && is_array($seller_data->roles) && in_array('seller', $seller_data->roles) ) {
return $rates; // stop the loop and return normally the shipping rates
}
}
$percentage = 30; // <== Set your discount percentage
$discount_rate = $percentage / 100;
// Loop through shipping rates for the current package when seller user role is not found
foreach( $rates as $rate_key => $rate ){
// Not for free shipping
if( $rate->method_id != 'free_shipping' ){
// Change rate cost
$rates[$rate_key]->cost = $rate->cost * $discount_rate;
$taxes = array(); // Initializing
// change taxes rate cost (if enabled)
foreach ($rate->taxes as $key => $tax){
if( $tax > 0 ){
$taxes[$key] = $tax * $discount_rate;
$has_taxes = true;
}
}
// Change taxes cost
if( $has_taxes ) {
$rates[$rate_key]->taxes = $taxes;
}
}
}
return $rates;
}
Code goes in function.php file of your active child theme (active theme). It should works.
Clearing shipping caches:
- You will need to empty your cart, to clear cached shipping data
- Or In shipping settings, you can disable / save any shipping method, then enable back / save.