skip to Main Content

I have the code following placed in functions.php

function shipping_weight_fee( $cart ) {
    if ( is_admin() && ! defined( 'DOING_AJAX' ) )
        return;
    
    $extraFee  = 0;
    $total_weight = 0;

    // Loop though each cart item
    foreach ( $cart->get_cart() as $cart_item ) {
        // Get product id
        $product_id = $cart_item['product_id'];

        // Get weight
        $product_weight = $cart_item['data']->get_weight();

        // NOT empty 
        if ( ! empty( $product_weight )  ) {
            // Quantity
            $product_quantity = $cart_item['quantity'];

            // Add to total
            $total_weight += $product_weight * $product_quantity;
        }
    }

    if ( $total_weight > 10 ) {          
        $extraFee = 20;
    }
}
add_action( 'woocommerce_cart_calculate_fees', 'shipping_weight_fee', 10, 1 );

How can I get $extraFee from first code snippet to work in following code:
I tried with global but it does not work. I believe the second code runs first but I am not sure.

add_filter( 'woocommerce_package_rates', 'custom_shipping_costs', 20, 2 );
function custom_shipping_costs( $rates, $package ) {
    
    foreach( $rates as $rate_key => $rate ){
        // Excluding free shipping methods
        if( $rate->method_id != 'free_shipping'){

            // Set rate cost
            $rates[$rate_key]->cost +=  $extraFee + 3;

        }
    }
    return $rates;
}

Please help, thank You!

2

Answers


  1. If you don’t want to add a fee to the cart you can avoid using the woocommerce_cart_calculate_fees hook and create a single function with the woocommerce_package_rates hook (combining the two functions):

    // set custom shipping cost by weight
    add_filter( 'woocommerce_package_rates', 'custom_shipping_costs', 20, 2 );
    function custom_shipping_costs( $rates, $package ) {
    
        $extraFee  = 0;
        $total_weight = 0;
    
        // Loop though each cart item
        foreach ( WC()->cart->get_cart() as $cart_item ) {
            // Get weight
            $product_weight = $cart_item['data']->get_weight();
            // NOT empty 
            if ( ! empty( $product_weight )  ) {
                // Quantity
                $product_quantity = $cart_item['quantity'];
                // Add to total
                $total_weight += $product_weight * $product_quantity;
            }
        }
    
        if ( $total_weight > 10 ) {          
            $extraFee = 20;
        }
        
        foreach( $rates as $rate_key => $rate ){
            // Excluding free shipping methods
            if( $rate->method_id != 'free_shipping'){
                // Set rate cost
                $rates[$rate_key]->cost += $extraFee + 3;
            }
        }
        return $rates;
    }
    

    The code has been tested and works. Add it to your active theme’s functions.php.

    Login or Signup to reply.
  2. You can use the WC_Cart method get_cart_contents_weight() to get the cart total weight instead simplifying the code.

    This will work if cart is not split in multiple shipping packages (see the other code below).

    The following code handle also the shipping taxes calculations:

    add_filter( 'woocommerce_package_rates', 'additional_shipping_weight_costs', 10, 2 );
    function additional_shipping_weight_costs( $rates, $package ) {
        $extra_cost   = (20 + 3); // Here define your extra shipping fee
        $total_weight = WC()->cart->get_cart_contents_weight(); // Get total weight
    
        if ( $total_weight > 10 ) {
            // Loop through available shipping rates
            foreach( $rates as $rate_key => $rate ){
                // Excluding free shipping methods
                if( 'free_shipping' !== $rate->method_id ){
                    $has_taxes    = false; // Initializing
                    $taxes        = array(); // Initializing
    
                    $initial_cost = $rate->cost;
                    $new_cost     = $rate->cost + $extra_cost;
                
                    $rates[$rate_key]->cost = $new_cost;
    
                    // Loop through taxes array (change taxes rate cost if enabled)
                    foreach ($rates[$rate_key]->taxes as $key => $tax){
                        if( $tax > 0 ){
                            // Get the tax rate conversion
                            $tax_rate    = $tax / $initial_cost;
    
                            // Set the new tax cost in the array
                            $taxes[$key] = $new_cost * $tax_rate;
                            $has_taxes   = true; // Enabling tax changes
                        }
                    }
                    // set array of shipping tax cost
                    if( $has_taxes ) {
                        $rates[$rate_key]->taxes = $taxes;
                    }
                }
            }
        }
        return $rates;
    }
    

    Code goes in functions.php file of the active child theme (or active theme). Tested and works.

    Don’t forget to empty your cart to refresh shipping rates caches.


    Handling multiple shipping packages

    As cart items can be split into multiple shipping packages by some plugins or custom code, in that case, you will use the following code that handle also shipping taxes calculations:

    add_filter( 'woocommerce_package_rates', 'additional_shipping_weight_costs', 10, 2 );
    function additional_shipping_weight_costs( $rates, $package ) {
        $extra_cost   = (20 + 3); // Here define your extra shipping fee
        $total_weight = 0; // Initializing
    
        // Get cart items for the current shipping package (to calculate package weight)
        foreach( $package['contents'] as $item ) {
            $total_weight += floatval( $item['data']->get_weight() ) * $item['quantity'];
        }
    
        if ( $total_weight > 10 ) {
            // Loop through available shipping rates
            foreach( $rates as $rate_key => $rate ){
                // Excluding free shipping methods
                if( 'free_shipping' !== $rate->method_id ){
                    $has_taxes = false; // Initializing
                    $taxes     = array(); // Initializing
    
                    $initial_cost = $rate->cost;
                    $new_cost     = $initial_cost + $extra_cost;
    
                    $rates[$rate_key]->cost = $new_cost; // Set new rate cost
    
                    // Loop through taxes array (change taxes rate cost if enabled)
                    foreach ($rates[$rate_key]->taxes as $key => $tax){
                        if( $tax > 0 ){
                            // Get the tax rate conversion
                            $tax_rate    = $tax / $initial_cost;
    
                            // Set the new tax cost in the array
                            $taxes[$key] = $new_cost * $tax_rate;
                            $has_taxes   = true; // Enabling tax changes
                        }
                    }
                    // set array of shipping tax cost
                    if( $has_taxes ) {
                        $rates[$rate_key]->taxes = $taxes;
                    }
                }
            }
        }
        return $rates;
    }
    

    Code goes in functions.php file of the active child theme (or active theme). Tested and works.

    Don’t forget to empty your cart to refresh shipping rates caches.

    Related: Filter "woocommerce_cart_contents_weight" not applied for shipping weight

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search