-1

How can i use different different shipping prices based on cart subtotal in Woocommerce?

For example:

  • If subtotal is less than 5000 the flat rate cost is 250.
  • If subtotal is less than 2000 the flat rate cost is 150.
  • If subtotal is getter than 5000 no shipping charge.

And If possible I want to charge a specific product for 500.

LoicTheAztec
  • 229,944
  • 23
  • 356
  • 399

1 Answers1

1

Try the following function which "Flat Rate" cost will be changed based on cart subtotal as defined in your question.

If cart subtotal is up to 5000, we will hide "Flat Rate". You will need to enable free shipping method with "A minimum order amount" option of 5000.

enter image description here

Using "Flate rate" shipping method, you will need to set a reference shipping cost with a simple initial cost instead of any formula. It can be for example 1. This cost will be replaced by my answer code, dynamically based on cart total weight.

enter image description here

It will handle also a specific product ID and will set the cost to 500 if is in cart.

You may have to "Enable debug mode" in general shipping settings under "Shipping options" tab, to disable temporarily shipping caches.

The code:

add_filter('woocommerce_package_rates', 'shipping_cost_based_on_price', 12, 2);
function shipping_cost_based_on_price( $rates, $package ){
    if ( is_admin() && ! defined( 'DOING_AJAX' ) )
        return $rates;

    // HERE define the differents costs
    $cost1 = 150; // Below 2000
    $cost2 = 250; // Below 5000
    $cost3 = 500; // Cost for our specific product ID

    $step1_subtotal = 2000;
    $max_subtotal   = 5000;


    // HERE DEFINE the specific product ID to be charged at 500
    $targeted_product_id = 37;

    // The cart subtotal
    $subtotal = WC()->cart->get_subtotal();

    // Loop through cart items and checking for the specific product
    $found = false;
    foreach( $package['contents'] as $item ) {
        if( $item['product_id'] == $targeted_product_id || $item['variation_id'] == $targeted_product_id ){
            $found = true;
            break;
        }
    }

    // Loop through the shipping taxes array
    foreach ( $rates as $rate_key => $rate ){
        $has_taxes = false;

        // If subtotal is up to 5000 we enable free shipping only
        if( 'free_shipping' !== $rate->method_id && $subtotal >= $max_subtotal ){
            unset($rates[$rate_key]);
        }
        // Targetting "flat rate" only for subtotal below 5000
        else if( 'flat_rate' === $rate->method_id && $subtotal < $max_subtotal ){
            // Get the initial cost
            $initial_cost = $new_cost = $rates[$rate_key]->cost;

            // Calculate new cost
            if( $subtotal < $step1_subtotal ) { // Below 2000
                $new_cost = $cost1;
            }
            elseif( $subtotal >= $step1_subtotal && $subtotal < $max_subtotal ) { // Between 2000 and below 5000
                $new_cost = $cost2;
            }

            // For the specific product ID (if found in cart items)
            if( $found ){
                $new_cost = $cost2;
            }

            // Set the new cost
            $rates[$rate_key]->cost = $new_cost;

            // Taxes rate cost (if enabled)
            $taxes = [];
            // Loop through the shipping taxes array (as they can be many)
            foreach ($rates[$rate_key]->taxes as $key => $tax){
                if( $rates[$rate_key]->taxes[$key] > 0 ){
                    // Get the initial tax cost
                    $initial_tax_cost = $new_tax_cost = $rates[$rate_key]->taxes[$key];
                    // Get the tax rate conversion
                    $tax_rate    = $initial_tax_cost / $initial_cost;
                    // Set the new tax cost
                    $taxes[$key] = $new_cost * $tax_rate;
                    $has_taxes   = true; // Enabling tax
                }
            }
            if( $has_taxes )
                $rates[$rate_key]->taxes = $taxes;
        }
    }
    return $rates;
}

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

Once tested, don't forget to disable "Enable debug mode" option in shipping settings.

LoicTheAztec
  • 229,944
  • 23
  • 356
  • 399