How to apply a shipping surcharge to a specific state in WooCommerce

Due to damage to a rail line connecting Western Australia to the eastern parts of the country, freight costs into WA are currently significantly more expensive than usual. Our delivery providers immediately imposed surcharges that were too substantial to absorb, so we needed to quickly pass this along to customers.

I didn’t really want to update the (rather complex) shipping rate table for each affected website, only to then undo those changes when the surcharge is eventually lifted. Instead, I used a bit of code to automatically add a fee to the checkout whenever “Western Australia” was chosen as the state.

Installing the code

Just copy and paste the snippet to your theme’s functions.php file or to a MU Plugin. You can also use the Code Snippets plugin to install the code, which is handy if you don’t have access to the filesystem.

add_action( 'woocommerce_cart_calculate_fees', 'sg_woocommerce_state_surcharge' );
function sg_woocommerce_state_surcharge() {
  global $woocommerce;
	if ( is_admin() && ! defined( 'DOING_AJAX' ) ) {

 	$state 	= array('WA');
	$percentage 	= 0.175;

	if ( in_array( $woocommerce->customer->get_shipping_state(), $state ) ) {
		$surcharge = ($woocommerce->cart->shipping_total ) * $percentage;
		$woocommerce->cart->add_fee( 'Western Australia Temporary Disaster Levy', $surcharge, true, '' );

Customising the code

Replace the value in $state to whichever state you want to surcharge. If you don’t know the WooCommerce state code for the region you’re trying to surcharge, take a look at this page. You can also surcharge multiple states by separating values with a comma; for example array(‘WA’, ‘SA’, ‘NT’);

The $percentage value is the percentage of the shipping cost that should be charged as a surcharge. 0.2, for example, will produce a fee of 20% of the shipping cost.

Finally, you can customise the message shown on the checkout next to the fee.

Leave a Reply