With the following code, I have got the correct displayed shipping method cost based on a subsidy (see this thread):
add_filter( 'woocommerce_cart_shipping_method_full_label', 'custom_shipping_method_full_label', 10, 2 );
function custom_shipping_method_full_label( $label, $method ) {
if ( !in_array( $method->get_method_id(), array( 'free_shipping', 'local_pickup' ), true ) && 0 < $method->cost ) {
$label = $method->get_label(); // Get shipping label without cost
$new_cost = $method->cost - get_total_subsidies( WC()->cart->get_cart() );
if ( $new_cost > 0 ) {
$method->cost = $new_cost;
$label .= ': ' . wc_price( $new_cost );
} else {
$method->cost = 0;
$label .= ': ' .' <span class="free-cost">' . __('Free!', 'woocommerce').'</span>';
}
}
return $label;
}
But it doesn't get extended to the totals calculations, taking into account the original shipping method cost.
I need the new cost to be the current cost for totals calculations from cart and checkout pages.
To handle the shipping costs and totals recalculations (+ handle those shipping methods display), you need to replace your current code with the following:
// Utility function: Reset shipping taxes
function zero_taxes( $tax ) {
return 0;
}
// Set new shipping rate costs
add_filter('woocommerce_package_rates', 'custom_shipping_rates_cost', 10, 2);
function custom_shipping_rates_cost( $rates, $package ) {
$total_subsidies = get_total_subsidies( $package['contents'] );
if ( ! $total_subsidies ) {
return $rates;
}
// Loop through shipping rates
foreach ($rates as $rate_key => $rate) {
if( ! in_array( $rate->method_id, array( 'free_shipping', 'local_pickup' ), true ) && $rate->cost > 0 ) {
$new_cost = $rate->cost - $total_subsidies;
if ( $new_cost > 0 ) {
$rates[$rate_key]->cost = $new_cost; // Set the new cost
} else {
$rates[$rate_key]->cost = 0; // Null the cost
$rates[$rate_key]->taxes = array_map('zero_taxes', $rate->taxes); // Null shipping costs taxes
$rates[$rate_key]->label .= ': <span class="free-cost">' . __('Free!', 'woocommerce') . '</span>'; // Custom displayed label
}
}
}
return $rates;
}
Code goes in functions.php file of your child theme (or in a plugin). It should work.
Important: Empty your cart to refresh the shipping methods cached data.
Related:
Display total subsidy amount based on WooCommerce cart items shipping class and quantity