WordPress snippet – WooCommerce free shipping by role

April 30th, 2014 by Sean Barton Leave a reply »

I have just been working on a WooCommerce site were the client needed to allow free shipping for certain levels of user. This seemed like a simple requirement but the WooCommerce line was to use Table Rate Shipping which would be fine if it wasn’t $200 (cmon guys it’s an essential plugin.. it really should be $59 or $79 like other essentials). So the other snippet that was conveniently listed here was to allow free shipping by location.

Using the following code your users with the role ‘charity’ will get free shipping. You can obviously extend it but it’s a nice basic example to work with. Put this code in your functions.php file in your theme or into a new plugin.. whatever works.

The code

add_filter( 'woocommerce_package_rates', 'sb_woocommerce_set_free_shipping_for_certain_users', 10, 2);

function sb_woocommerce_set_free_shipping_for_certain_users( $rates, $package ) {
	get_currentuserinfo();
	global $current_user;
	
	if ($current_user->ID) {
		$user_roles = $current_user->roles;
		$user_role = array_shift($user_roles);
		
		if ($user_role == 'charity') {
			$freeshipping = $rates['free_shipping'];
	 
			$rates = array();
			$rates[] = $freeshipping;
		} else {
			unset($rates['free_shipping']);
		}
	}
    
	return $rates;
}

3 comments

  1. Ian Sayers says:

    Seriously… where have you been over the past few months… why am i only finding you now… after so many headaches and costly plugins…

    I think in future for sites that need some specific code we could happily do business together and the client would be happy to pay for your services.

    Thanks for the code above.

  2. Chris Hatton says:

    I think I know what is breaking the cart. What do I do if the shipping rule does not seem to apply. This is what I am currently doing – I notice if I take away the lines of code that relate to international shipping, it is fine…

    $current_user = wp_get_current_user();

    if ($current_user->ID) {
    $user_roles = $current_user->roles;
    $user_role = array_shift($user_roles);

    if ($user_role == ‘administrator’) {
    $freeshipping = $rates['free_shipping'];
    $intershipping= $rates['international_delivery'];

    $rates = array();
    $rates[] = $freeshipping;
    $rates[] = $intershipping;
    } else {
    //unset($rates['free_shipping']);
    }
    }

    return $rates;

    Should I instead do this, to see if $freeshipping or $intershipping has been declared…

    $current_user = wp_get_current_user();

    if ($current_user->ID) {
    $user_roles = $current_user->roles;
    $user_role = array_shift($user_roles);

    if ($user_role == ‘administrator’) {
    $freeshipping = $rates['free_shipping'];
    $intershipping= $rates['international_delivery'];

    $rates = array();
    if ($freeshipping) { $rates[] = $freeshipping; }
    if ($intershipping) {$rates[] = $intershipping;}
    } else {
    //unset($rates['free_shipping']);
    }
    }

    return $rates;

  3. Hi Sean,

    Nice code, on thing I might remove from it: the else unset; when there are other options available (e.g. free shipping > 50) for free shipping this might remove them.

    I’ve also made an plugin which you could have used ;), yes it allows setting by user role :)

    ‘WooCommerce Advanced Free Shipping’
    http://wordpress.org/plugins/woocommerce-advanced-free-shipping/

Leave a Reply