Customize WooCommerce Shipping Rates

A vintage truck that could be used for shipping and transporting items

24 thoughts on “Customize WooCommerce Shipping Rates

  1. Hi Caleb, I am trying to achieve something similar but I want to be able to customize my shipping rates inside my custom function in function.php. Since I can’t put add_filter( ‘woocommerce_package_rates’) inside my function I was wondering how can I update the rates so that it persists. In my case the change to rate seems to be just local.

    add_action( 'woocommerce_review_order_before_order_total', 'my_woocommerce_review_order_before_order_total' );
    function my_woocommerce_review_order_before_order_total( ) {
    global $woocommerce;
    $shipping_method = $_POST['shipping_method'][0];
    $packages = WC()->shipping->get_packages();
    $rates = $packages[0]['rates'];
    $rates[$shipping_method]->cost = 18;
    print WC()->shipping->shipping_total; // 0 and not 18

    1. Hi Tripty,

      I’m not sure what you mean by “In my case the change to rate seems to be just local”.

      I do see that you aren’t hooking your function onto the right hook though. You need to use `woocommerce_package_rates` hook, the one your are using will not work for changing the rates.

  2. You absolutely rock my world, Caleb! After weeks and weeks of trying to figure this out myself, I found your post. Thank you so much!

  3. Very nice snippets – thank you very much!

  4. Hi Caleb,

    I have a new role setup for customer_wholesale and I’m trying to customize the checkout calculations for this role. Regular customers pay table rate shipping and tax if from WI. However, we want to use a flat rate of 5% shipping for wholesale customers AND wholesale customers should never be charged tax no matter which state they are from. Can your snippet be modified to achieve this? Of course we want the checkout page to reflect only table rate and applicable tax if regular customer and only special shipping for wholesale customer. Thanks in advance for your expertise!

    1. OK, I’ve added a function to correctly calculate the tax and shipping, BUT still displaying both shipping methods to both user roles. Can anyone help me with a function to display only the correct shipping based on user? So…

      If wholesale, show only flat rate
      else show only table rate

      The rates display on both the cart and checkout pages, but I am hoping to accomplish this in the functions file, without touching the template files.

      Thanks so much!

      1. Hey Wendy,

        You can use the current_user_can() function in a conditional statement to unset flat rate conditionally. Something like this:

        1. Hello Caleb and thank you for your response. Unfortunately, my attempts result in either flat rate only or radio buttons for both flat rate and table rate. I tried to add an elseif statement into the function, but not exactly sure of the syntax for PHP. The two users I am concerned with are customer and customer_wholesale. Can you provide an example that will turn off table rate for wholesale_customer and turn off flat rate for customer? Thank you so much!

        2. Hello Caleb,

          I tried again with this function but do not understand why it won’t work. If one logs in and is not a wholesale customer, they will be presented with both options (flat rate and table rate).

          1. Oops! That didn’t work out very well. Let’s try again:

            Sorry about that!

        3. Got it working. Thank you Caleb!

          1. Awesome, nice job 🙂

            My snippet only hide flat rate for non wholesale members. Just needed to be duplicated to hide table rate for wholesale members.

  5. Thank you very much, you saved me a lot of time!

  6. Hi Caleb

    This is exactly what i am looking for but nothing seems to change when i add the snippets into functions.php in the theme file.

    Is it the right code m inserting or anything updated in woocommerce since then.

  7. Does this work for Woocommerce 3.0?

    1. You’ll need to add in the instance ID now with WC 3.0+. I updated some of the snipped in the article.

  8. Does this method still work?

    I am using the woocommerce_package_rates and I am trying to unset the Free Shipping if an item contains the shipping Class ‘Too Heavy’. The Id for Too Heavy is 92.

    When I hook in here, it doesn’t seem to remove Free Shipping anywhere. Not in the Cart, not in the checkout.

    I am also using the plugin for my mailing rates.

  9. Caleb,
    you made my day with this tutorial! I was looking for a way to have shipping cost go up every 4 products added to the cart….I can use your examples above to implement that!

  10. Thanks for posting this! Always a bonus when a few lines of code can replace a premium WooCommerce add-on.

  11. Thank you!

  12. thanks, This is what I’am looking for

  13. I have no words to thank you, because i didn’t know how to use the ‘packages’ variable, i was wasting too much time crating functions to get country, vendor_id, and so on.

Leave a Reply

Your email address will not be published.

Please note that I cannot help with customization requests. Your comment will not be approved if asking for code help. Visit this page if you need assistance with code.