WooCommerce: Show Shipping Rates @ Single Product Page

In today’s “Watch me customize my WooCommerce marketplace website” episode (see previous customization re: external products) we’ll go printing shipping zones and rates on the single product page, so that users know how much they’ll end up spending once they reach the Cart/Checkout and there are no “hidden” fees. Not bad for some transparency = better sales conversion rate!

You can see the result on my own website, at this link for example: https://www.apieceofsicily.com/en/shop/sicilian-crafts/ciabattino/ – as you can see right below the “Add to Cart” button there is a shipping table with the data taken from the shipping zones.

I must say I use YITH WooCommerce Multi Vendor / Marketplace so that data is actually taken from each vendor’s shipping setup – so in this tutorial we will first see how to get the default “WooCommerce Shipping Zones Data” and in a second snippet we will instead see how to get the info for each vendor instead.

Either way, enjoy!

Here’s the new “Shipping” section on the WooCommerce Single Product Page that gathers data from each shipping zones.

PHP Snippet: Display Shipping Zones & Methods @ WooCommerce Single Product Page (WooCommerce Plugin)

/**
 * @snippet       Show Shipping Rates - WooCommerce Single Product
 * @how-to        Get CustomizeWoo.com FREE
 * @author        Rodolfo Melogli
 * @compatible    WooCommerce 6
 * @donate $9     https://businessbloomer.com/bloomer-armada/
 */

add_action( 'woocommerce_after_add_to_cart_form', 'bbloomer_shipping_rates_single_product' );

function bbloomer_shipping_rates_single_product() {
   global $product;
   if ( ! $product->needs_shipping() ) return;
	$zones = WC_Shipping_Zones::get_zones();
	echo '<div><i class="fas fa-truck"></i> ' . __( 'Shipping', 'woocommerce' );
	echo '<table>';
	foreach ( $zones as $zone_id => $zone ) {
		echo '<tr><td>';
		echo $zone['zone_name'] . '</td><td>';
		$zone_shipping_methods = $zone['shipping_methods'];
		foreach ( $zone_shipping_methods as $index => $method ) {
			$instance = $method->instance_settings;
			$cost = $instance['cost'] ? $instance['cost'] : $instance['min_amount'];
			echo $instance['title'] . ' ' . wc_price( $cost ) . '<br>';
		}
		echo '</td></tr>';
	}
	echo '</table></div>';
}

PHP Snippet: Display Vendor’s Shipping Zones & Methods @ WooCommerce Single Product Page (YITH WooCommerce Multi Vendor / Marketplace Plugin)

/**
 * @snippet       Show YITH Vendor Shipping Rates - WooCommerce Single Product
 * @how-to        Get CustomizeWoo.com FREE
 * @author        Rodolfo Melogli
 * @compatible    WooCommerce 6
 * @donate $9     https://businessbloomer.com/bloomer-armada/
 */

add_action( 'woocommerce_after_add_to_cart_form', 'bbloomer_yith_vendor_shipping' );

function bbloomer_yith_vendor_shipping() {
	global $product;
   if ( ! $product->needs_shipping() ) return;
	$product_id = $product->get_id();
	$vendor = yith_get_vendor( $product, 'product' );
		if ( $vendor->zone_data ) {
			echo '<div><i class="fas fa-truck"></i> ' . __( 'Shipping', 'woocommerce' );
			echo '<table>';
			foreach ( $vendor->zone_data as $key => $zone ) {
				echo '<tr><td><i>';
				echo $zone['zone_name'] . '</i></td><td>';
				$zone_shipping_methods = $zone['zone_shipping_methods'];
				foreach ( $zone_shipping_methods as $index => $method ) {
					$cost = $method['method_cost'] ? $method['method_cost'] : $method['min_amount'];
					echo $method['method_title'] . ' ' . wc_price( $cost ) . '<br>';
				}
				echo '</td></tr>';
			}
			echo '</table></div>';
	}
}

Where to add custom code?

You should place PHP snippets at the bottom of your child theme functions.php file and CSS at the bottom of its style.css file. Make sure you know what you are doing when editing such files - if you need more guidance, please take a look at my guide "Should I Add Custom Code Via WP Editor, FTP or Code Snippets?" and my video tutorial "Where to Place WooCommerce Customization?"

Does this snippet (still) work?

Please let me know in the comments if everything went as expected. I would be happy to revise the snippet if you report otherwise (please provide screenshots). I have tested this code with Storefront theme, the WooCommerce version listed above and a WordPress-friendly hosting.

If you think this code saved you time & money, feel free to join 17,000+ WooCommerce Weekly subscribers for blog post updates and 250+ Business Bloomer supporters for 365 days of WooCommerce benefits. Thank you in advance!

Need Help with WooCommerce?

Check out these free video tutorials. You can learn how to customize WooCommerce without unnecessary plugins, how to properly configure the WooCommerce plugin settings and even how to master WooCommerce troubleshooting in case of a bug!

Rodolfo Melogli

Business Bloomer Founder

Author, WooCommerce expert and WordCamp speaker, Rodolfo has worked as an independent WooCommerce freelancer since 2011. His goal is to help entrepreneurs and developers overcome their WooCommerce nightmares. Rodolfo loves travelling, chasing tennis & soccer balls and, of course, wood fired oven pizza.

22 thoughts on “WooCommerce: Show Shipping Rates @ Single Product Page

  1. Hi!

    Love your blog! I have been using several of your snippets on my projects.
    This snippet is awesome, but how can I get this to work if I have multiple shipping classes?

    Kind Regards,
    Andree

    1. Hello Andree, thanks so much for your comment! Yes, this is definitely possible, but I’m afraid it’s custom work. If you’d like to get a quote, feel free to contact me here. Thanks a lot for your understanding!

  2. Please tell me how to hide it on digital products? I’ve both physical and digital products. It is also visible on digital products.

    1. You’re 100% right! Check the new version please

  3. Rodolfo, thanks for the snippet.

    I’m using “WooCommerce Table Rate Shipping” from Bolder Elements.
    You code is printing shipping zones, title but all rates are being displayed as 0,00.

    Any chance to get the correct rates with your code?

    1. Hi Vinicius, thanks so much for your comment! Yes, this is definitely possible, but I’m afraid it’s custom work. If you’d like to get a quote, feel free to contact me here. Thanks a lot for your understanding!

  4. This is exactly what I was looking for. So excited to find your site and this snippet.

    I tried the first code and it does show Shipping and the table below. However it shows shipping only for in-country shipping (I have two zones set up – in-country and international). And it shows 0 in the cost field even though I have defined costs for the shipping class selected for the product. Could this be because I have Dokan marketplace? Any pointers to what I might check for to get this to work?

    Using your YITH code (replacing it with dokan) didn’t work at all as I guess Dokan probably has different variables.

    1. Thanks Manish, yes, I believe the code may need to be customized to make it compatible with Dokan

  5. Hello and thank you for this.
    I have an issue though. When I add the code to functions.php I get the following error.

    Notice: Undefined index: min_amount in /var/www/webroot/stage-sneakfreakscy/wp-content/themes/shoptimizer-child-theme/functions.php on line 275
    Home Delivery โ‚ฌ0,00

    Why is that please?

    1. Usually free shipping rates have a “min_amount” that trigger the method. If you don’t have this, the code won’t find it, and you have this “Notice” (which is nothing serious).

      If you want to fix this, you could change

      $cost = $instance['cost'] ? $instance['cost'] : $instance['min_amount'];

      to

      $cost = $instance['cost'] ? $instance['cost'] : ( $instance['min_amount'] ? $instance['min_amount'] : 0 );
  6. Hi Rodolfo,
    I placed the php snippet at the bottom of my child themes functions.php file.
    But there’s nothing showing up at my product pages ๐Ÿ™

    P.s. it’s not the website which I put in my info but another website I’m working on.

    1. You don’t even see the “Shipping” title? If yes, then it’s because you’re on a custom theme and default WooCommerce hooks won’t work out of the box. Let me know

      1. Hey Rodolfo,

        I ran into this issue as well. I just did a quick copy/paste and nothing showed up. Double checked the code for the “PHP Snippet: Display Shipping Zones & Methods @ WooCommerce Single Product Page (WooCommerce Plugin)” version and there’s no “add_action” included.

        Once I added that your snippet worked just fine. It might be helpful to update the snippet to include that so that people don’t get confused as to why it’s not working. ๐Ÿ™‚

        1. Sorry about that. Fixed

  7. Hi Rodolfo

    long time subscriber first time commenting.

    is there any chance you could adapt this snippet so that it works with another marketplace plugin called WC vendors.

    I tried swapping yith_get_vendor for WCV_Vendors::is_vendor and WCV_Vendors::get_vendor_id but just gets a critical error. obviously, my cutting and pasting technique is being exposed here ๐Ÿ˜€

    thanks in advance
    mark

    1. Hey Mark, thanks so much for your comment! Yes, this is definitely possible, but I’m afraid it’s custom work. If you’d like to get a quote, feel free to contact me here. Thanks a lot for your understanding!

  8. It shows for flat rate: โ‚ฌ 0,00 instead of the right rate of โ‚ฌ 8,00

    1. Not sure, works on my site. Can you try disable all plugins but Woo and test again?

  9. Hi Rodolfo!

    Love your blog, has helped me tremendously over the years.
    I work with geolocation for an even better conversion – customers in Italy have no need to see shipping rates/eta for Sweden for example. It will only confuse them.

    Tip: by adding a custom ETA field to the shipping methods you can specify the ETA per shipping method/zone. Any idea how we can present this custom field on the product page as well?

    1. Hey Wolf, thanks so much for your comment! Yes, this is definitely possible, but I’m afraid it’s custom work. If you’d like to get a quote, feel free to contact me here. Thanks a lot for your understanding!

  10. Nice feature but it also shows “Free Shipping EURO 200” where it should rather say Free shipping above EURO 200 spend.

    1. Yep, you can totally add that (untested):

      $cost = $instance['cost'] ? $instance['cost'] : $instance['min_amount'];
      $above = $instance['min_amount'] ? 'above ' : '';
      echo $instance['title'] . ' ' . $above . wc_price( $cost ) . '<br>';
      
Questions? Feedback? Support? Leave your Comment Now!
_____

If you are writing code, please wrap it between shortcodes: [php]code_here[/php]. Failure to complying with this (as well as going off topic, not writing in English, etc.) will result in comment deletion. You should expect a reply in about 2 weeks - this is a popular blog but I need to get paid work done first. Please consider joining BloomerArmada to get blog comment reply priority, ask me 1-to-1 WooCommerce questions and enjoy many more perks. Thank you :)

Your email address will not be published. Required fields are marked *