Search code examples
phpwordpresswoocommercecartshipping-method

Progressive flat rate based on the cart's subtotal percentage in WooCommerce


In WooCommerce, I am trying to set a progressive shipping cost based on 10% of cart subtotal with $5 as minimum cost, up to $11 max cost.

Here is my code attempt:

add_filter( 'woocommerce_package_rates', 'woocommerce_package_rates', 10, 2 );
function woocommerce_package_rates( $rates, $package ) {
    // Make sure flat rate is available
    if ( isset( $rates['flat_rate:24'] ) ) {
        // Set the cost to $5
        $rates['flat_rate:24']->cost = 5;
    }
    $cart_subtotal = $WC()->cart->subtotal
    if ($cart_subtotal >50)

    $percentage = 0.10;  // Percentage (10%) in float
    $percentage_fee = ( WC()->cart->subtotal >+ WC()->cart->get_shipping_total()) * $percentage;
    }
 
    });
    return $rates;
}

This code gives a critical error on the website. I am quite new to Wordpress custom coding as you will probably tell from the code below.

Also I would like the displayed label to show "USPS" instead of "Flat rate".

For example, if the cart subtotal is $60, they would be charged $6 flat rate shipping cost (10% of subtotal).

What am I missing or doing wrong?


Solution

  • There are a lot of mistakes in your provided code… The following will allow you to set a shipping cost starting from 5$ to 11$ max, based on cart subtotal percentage.

    First you need to set a cost of 5 (and also "UPS" as label) in your Flat rate settings.

    enter image description here

    Then use this code:

    add_filter( 'woocommerce_package_rates', 'woocommerce_package_rates', 10, 2 );
    function woocommerce_package_rates( $rates, $package ) {
        $max_cost   = 11; // Here set the max cost for the shipping method
        $percentage = 10; // Percentage to apply on cart subtotal
        $subtotal   = WC()->cart->get_subtotal(); // Cart subtotal without taxes
    
        // Loop through shipping rates
        foreach ( $rates as $rate_key => $rate ) {
            // Targetting specific flate rate shipping method
            if ( 'flat_rate:14' === $rate_key ) {
                $has_taxes = false;
                $base_cost = $rate->cost; // 5$ from this shipping method cost setting
                $new_cost  = $subtotal * $percentage / 100; // Calculation
    
                if( $new_cost > $base_cost ) {
                    // 1. Rate cost
                    if ( $new_cost < $max_cost ) {
                        $rates[$rate_key]->cost = $new_cost;
                        $rate_operand = $new_cost / $base_cost; // (for taxes if enabled)
                    } else {
                        $rates[$rate_key]->cost = $max_cost;
                        $rate_operand = $max_cost / $base_cost; // (for taxes if enabled)
                    }
                    // 2. Taxes rate cost (if enabled)
                    foreach ($rates[$rate_key]->taxes as $key => $tax){
                        if( $tax > 0 ){
                            // New tax calculated cost
                            $taxes[$key] = $tax * $rate_operand;
                            $has_taxes = true;
                        }
                    }
                    // Set new taxes cost
                    if( $has_taxes ) {
                        $rates[$rate_key]->taxes = $taxes;
                    }
                }
            }
        }
        return $rates;
    }
    

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

    Refresh the shipping caches:

    1. This code is already saved on your functions.php file.
    2. In a shipping zone settings, disable / save any shipping method, then enable back / save.

      You are done and you can test it.