X

Custom Shipping Calculation Using Flat Rate Shipping

I just wanted to jump on here and post about a nifty – less known – feature for setting up shipping rates. I get a lot of requests about how to properly setup shipping rates. Every system is different and recently I saw a request roll by on Facebook WooCommerce Help & Share Group about a custom shipping calculation using flat rate shipping.

Is there a plugin to set a custom shipping calculation using flat rate shipping?

Well, I can’t say for sure – but more than likely. If you want to take a moment, possibly save a little money, there is a way to set a custom formula for flat rate shipping in WooCommerce out of the box. You see that little question mark next to the cost field of your flat rate shipping setting? There’s your sign. Since I had some decent experience with getting these setup, I figured I would chime in with my 2 cents. Part of what they were looking for was a way to have a flat rate for a single product, then increase by a smaller amount based on the quantity of the product.

Little more complex than [qty] * $5!

So I quickly was intrigued, with my fingers crossed I performed a quick test, debugged and had perfect results! The answer? 5 + ( [qty] – 1 )

As you can tell, that is a little abnormal, that is why I debugged to solve this mystery. While I was debugging others were posting suggestions on paid plugins – NOT ME!

Here is the breakdown…

First step was to add / update my flat rate shipping settings under WooCommerce > Settings > Shipping > MY ZONE > Flat Rate (fancy in my example)

Second – since I decided to go above and beyond to learn something new, I wanted to see the guts of the functionality. It boiled down to the WC_Shipping_Flat_Rate class in the core of WooCommerce.

The function that runs is this:

/**
 * Evaluate a cost from a sum/string.
 * @param  string $sum
 * @param  array  $args
 * @return string
 */
protected function evaluate_cost( $sum, $args = array() ) {
	include_once( WC()->plugin_path() . '/includes/libraries/class-wc-eval-math.php' );

	// Allow 3rd parties to process shipping cost arguments
	$args           = apply_filters( 'woocommerce_evaluate_shipping_cost_args', $args, $sum, $this );
	$locale         = localeconv();
	$decimals       = array( wc_get_price_decimal_separator(), $locale['decimal_point'], $locale['mon_decimal_point'], ',' );
	$this->fee_cost = $args['cost'];

	// Expand shortcodes
	add_shortcode( 'fee', array( $this, 'fee' ) );

	$sum = do_shortcode( str_replace(
		array(
			'[qty]',
			'[cost]',
		),
		array(
			$args['qty'],
			$args['cost'],
		),
		$sum
	) );

	remove_shortcode( 'fee', array( $this, 'fee' ) );

	// Remove whitespace from string
	$sum = preg_replace( '/\s+/', '', $sum );

	// Remove locale from string
	$sum = str_replace( $decimals, '.', $sum );

	// Trim invalid start/end characters
	$sum = rtrim( ltrim( $sum, "\t\n\r\0\x0B+*/" ), "\t\n\r\0\x0B+-*/" );

	// Do the math
	return $sum ? WC_Eval_Math::evaluate( $sum ) : 0;
}

Now for those of you who do not know what is going on here, the first argument of the function is the formula ($sum) we setup for the new fancy rate.

Little bit of a education in here..

Line #19 (first highlighted line) replaces the QTY and COST arguments in the formula with the actual values.

  • [qty] = Quantity of product
  • [cost] = Cost of Product

After the arguments are replaced, the $sum = 5 + ( 2 ) in a scenario where I have 3 of the item in my cart. If I only have 1 of the item, $sum = 5 + ( 0 ). See what I did there?

Line #43 (second highlighted line) is evaluating the result of line #19 (plus some extra cleanup and fee if applicable) and giving that shipping option to the customer.

For your viewing pleasure, I created a short video clip of me going in and updating my cart a few times for verification on how to get custom shipping calculation using flat rate shipping.

Have a wonderful Memorial Day Weekend!

James Tedrow :Originally born in Florida, moved to Arizona and started programming at 13, now 29. Enjoying life with computers, sports, skateboarding and my family. I enjoy short walks on the beach (I get tired fast), loud music (hit me with that bass) and to help others succeed.