WooCommerce Tiered Shipping Rates
Today, I'm going to show you how to set up a WooCommerce shipping function, allowing you to charge the cost of shipping based on the total price of items in your shopping cart. Seems like a simple calculation. It's not.
For those of you looking to customize their experience with the industry standard eCommerce store, WooCommerce, I’m here to help. I recently had a client looking to charge varying prices for shipping, based on the total price of items in the cart. On the surface, this seemed like a simple request. We could set up flat rate shipping; however, the functions would only apply to one pricing threshold. Being a photographer with a wide product offering, it wouldn’t make sense to charge the shipping cost for sending a tube with a poster print vs. a box full of heavy portraits with upwards of 4-pound frames.
In order to make this request work, we realized we’d need to set up a function with pricing thresholds to determine the total cost of shipping. As WooCommerce expands their product offering, they’ve shifted towards a subscription-based model. Sure they’ll reap insane profits over time with this model; however we have a simple request with a low budget & can’t afford the $99 subscription fee PER YEAR for such a simple request. So instead of rolling with the punches, we decided to take matters into our own hands.
Before we go any further, I’d like to mention that I am, by no means, a traditional web developer. But chances are, if you’re reading this article, neither are you, and that’s okay! The reason I’m actually writing this article is to help people like myself, looking for a quick fix in a pinch. Cool, so let’s get started!
I’ll admit this does require a teensy bit of knowledge in .php, the backbone for the WordPress CMS, but it’s not complicated, I swear!
To break down this problem, we need to identify the issue. So the main issue at hand, is the lack of flexibility in WooCommerce, in the sense that we can only structure flat rates for a single tier. This means that if you want $5 flat rate shipping, everything will be a $5 flat rate. In my case, this rigidity simply wouldn’t suffice. Our particular case required that we would need to break up this flat rate in three preset tiers, based on the total cost of items in the cart.
For structuring purposes, we identified our tiers into 3 total flat rates. For any purchases under $65, we would charge a $6 flat rate. For purchases between $65 and $120, the flat rate would be $11. Finally, for purchases over $120 (no maximum), we’d charge a $15 flat rate.
Flat Rate – Tier I: cart subtotal < $65 = $6 shipping
Flat Rate – Tier II: $65 < cart subtotal < $120 = $11 shipping
Flat Rate – Tier III: $120 < cart subtotal = $15 shipping
So to turn these statements into a formula, we need to identify the threshold to trigger the proper shipping tier, based on cart subtotal. The two threshold in this instance would be $65 and $120. If the total cost is below the initial threshold, we charge for Tier II. If shipping is between the two thresholds, we charge Tier II. If the subtotal is above both thresholds, we charge Tier III. This is the basic function describing our solution.
So now that we’ve identified the problem & laid out our basic solution, we need to author a plug-in to communicate with WooCommerce to reach our solution. I’ll admit, the idea of writing a custom plug-in is rather daunting, but again, you DON’T need to be a web developer of speak in .php to reach our end goal.
First we list out thresholds:
“$threshold1” = 65
“$threshold2” = 120
Now we identify our flat rates i.e. tiers:
“flat_rate:1” = Tier I
“flat_rate:2” = Tier II
“flat_rate:3” = Tier III
Cool, easy enough. Now we need to take our previous arithmetic & make it readable by WooCommerce. In order to do this, we start out by making the statement, basically saying, if the WooCommerce cart total is less than threshold #1, we remove (unset) the rates for the higher tiers, flat rates 2 & 3. In .php it’ll look something like this:
“if ( WC()->cart-> cart_contents_total < $threshold1 ) {unset( $rates[‘flat_rate:2’], $rates[‘flat_rate:3’] );”
So, if the cart subtotal is less than threshold #1, we remove the higher tiers, flat rates 2 & 3.
Cool so we have Tier I set-up, let’s move onto what happens if the cart subtotal falls between the thresholds, indicating the need for Tier II. The basic argument is as follows:
“} elseif ( WC()->cart-> cart_contents_total < $threshold2 ) { unset( $rates[‘flat_rate:1’], $rates[‘flat_rate:3’] );”
Again, this is basically saying, if it’s greater than “$threshold1” and less than “$threshold2”, then we signal the need for Tier II shipping costs. Finally, we need to set the final tier, Tier III. This function indicated that if the cart subtotal is greater than both thresholds, we’ll signal the maximum shipping cost i.e. Tier III, which looks something like this:
“} else { unset( $rates[‘flat_rate:1’], $rates[‘flat_rate:2’] );”
This final function says, for simplicity, if the other two functions aren’t applicable, then use the final flat rate, indicating Tier III shipping costs. The overall bit of code will look something like this:
/* Change shipping based on total cost purchased. */
add_filter( ‘woocommerce_package_rates’, ‘bbloomer_woocommerce_tiered_shipping’, 10, 2 );
function bbloomer_woocommerce_tiered_shipping( $rates, $package ) {
$threshold1 = 65;
$threshold2 = 120;
if ( WC()->cart-> cart_contents_total < $threshold1 ) {
unset( $rates[‘flat_rate:3’], $rates[‘flat_rate:4’] );
} elseif ( WC()->cart-> cart_contents_total < $threshold2 ) {
unset( $rates[‘flat_rate:2’], $rates[‘flat_rate:4’] );
} else {
unset( $rates[‘flat_rate:2’], $rates[‘flat_rate:3’] );
}
return $rates;
}
That’s all for now! Please reach out & let me know if you have any questions. Woocommerce has been a thorn in my side for years, so I hope this helped spare someone else from the same experience!
Thomas Decker
Part-time digital marketing specialist and web designer for small businesses across the US. Experience with graphic design, coding & general web fun :)