Search code examples
phpwordpresswoocommerce

Customize Tax amount in "woocommerce_package_rates" hook


I recently tried to modify all my shipping rates with hook to apply discount.

Here's my code :

add_filter( 'woocommerce_package_rates', 'woocommerce_package_rates' );
function woocommerce_package_rates( $rates ) {
    $user_id = get_current_user_id();
    if ( ! wc_memberships_is_user_active_member( $user_id, 'silver' ) ) { return $rates; }
    $discount_amount = 30; // 30%

    foreach($rates as $key => $rate ) {
        $rates[$key]->cost = $rates[$key]->cost - ( $rates[$key]->cost * ( $discount_amount/100 ) );
    }

    return $rates;
}

But one more step is the tax ! I got wrong tax.
For example I have my shipping rate who cost 3$. With the discount, it's now 2,10$.

I buy one item for 2$ and the shipping 2.10$. I got 1$ for the tax (as the 3$ shipping cost. look like he doesn't take the changes) and normally it's 0.82$.

What do I need to get the correct tax calculation?


Solution

  • Updated: add tax cost calculation, and removed some typos.

    There is some little errors on your code and you have missed the tax calculation discount. I have revisited your code a bit, you should try this:

    add_filter( 'woocommerce_package_rates', 'conditional_shipping_discount', 10, 2 );
    function conditional_shipping_discount( $rates, $packages ) {
    
        $user_id = get_current_user_id();
        if ( ! wc_memberships_is_user_active_member( $user_id, 'silver' ) ) return $rates;
    
        $percent = 30; // 30%
        $discount = 1 - ($percent / 100);
    
        foreach($rates as $rate_key => $rate ) {
            // Get original cost
            $original_cost = $rates[$rate_id]->cost;
            // Calculate the discounted rate cost
            $new_cost = $original_cost * $discount;
            // Set the discounted rate cost
            $rates[$rate_key]->cost = number_format($new_cost, 2);
            // calculate the conversion rate (for taxes)
            $conversion_rate = $new_cost / $original_cost;
    
            // Taxes rate cost (if enabled)
            $taxes = array();
            foreach ($rate->taxes as $key => $tax){
                if( $tax > 0 ){ // set the new tax cost
                    // set the new line tax cost in the taxes array
                    $taxes[$key] = number_format( $tax * $conversion_rate, 2 );
                }
            }
            // Set the new taxes costs
            $rates[$rate_key]->taxes = $taxes
        }
        return $rates;
    }
    

    Code goes in function.php file of your active child theme (or theme) or also in any plugin file.

    This code is tested and works.

    You should need to refresh the shipping caches:

    1. First this code is already saved on your function.php file.
    2. In Shipping settings, enter in a Shipping Zone and disable a Shipping Method and "save". Then re-enable that Shipping Method and "save". You are done.