Set specific Products to be shipped only in specific countries in WooCommerce











up vote
2
down vote

favorite
2












How can I set certain products to be shippable to only certain countries in Woocommerce?



For example, during checkout, if Country is not USA, I want to show the message "We cannot deliver to your country."










share|improve this question




























    up vote
    2
    down vote

    favorite
    2












    How can I set certain products to be shippable to only certain countries in Woocommerce?



    For example, during checkout, if Country is not USA, I want to show the message "We cannot deliver to your country."










    share|improve this question


























      up vote
      2
      down vote

      favorite
      2









      up vote
      2
      down vote

      favorite
      2






      2





      How can I set certain products to be shippable to only certain countries in Woocommerce?



      For example, during checkout, if Country is not USA, I want to show the message "We cannot deliver to your country."










      share|improve this question















      How can I set certain products to be shippable to only certain countries in Woocommerce?



      For example, during checkout, if Country is not USA, I want to show the message "We cannot deliver to your country."







      php wordpress woocommerce checkout shipping






      share|improve this question















      share|improve this question













      share|improve this question




      share|improve this question








      edited Feb 13 at 13:10









      LoicTheAztec

      82.2k125993




      82.2k125993










      asked Feb 12 at 22:23









      user3036214

      112




      112
























          1 Answer
          1






          active

          oldest

          votes

















          up vote
          0
          down vote



          accepted










          This can be done mainly with a custom function hooked in woocommerce_package_rates filter hook.



          The code below, will allow you to disable shipping, for specific products IDs or specific product categories (you can choose) based on defined country codes.



          You will have to add your settings in the first function.



          The code:



          // HERE your settings - Utility function
          function your_country_shipping_settings(){
          $results = array();
          // Can be based on "Product IDs" (or "Product categories" ==> false)
          $results['type'] = true; // or false

          // Allowed countries (Only compatible country codes - 2 digits)
          $results['countries'] = array( 'US', 'CA' );

          if( $results['type'] ){
          // Restricted product IDs
          $results['matching'] = array( 37, 38 );
          } else {
          // Restricted product categories (IDs, Slugs or Names)
          $results['matching'] = array('t-shirts', 'sweet-shirts' );
          }
          // Message
          $results['message'] = __( "can not be delivered to your country.", "woocommerce" );

          return $results;
          }

          // Utility function that check cart items
          function get_items_names( $matching, $package, $type ){
          $product_names = array();

          // Search in cart items
          foreach( $package['contents'] as $item ){
          if( $type ){
          if( in_array( $item['data']->get_id(), $matching ) )
          $product_names = $item['data']->get_name();
          } else {
          if( has_term( $matching, 'product_cat', $item['product_id'] ) )
          $product_names = $item['data']->get_name();
          }
          }
          return $product_names;
          }

          // Conditionally disabling shipping methods
          add_filter('woocommerce_package_rates','custom_country_shipping_rules', 10, 2 );
          function custom_country_shipping_rules( $rates, $package ){
          if( isset($package['destination']['country']) && isset($package['contents']) ){
          // Load your settings
          $data = your_country_shipping_settings();

          // If matching allowed countries ==> We Exit
          if( in_array( $package['destination']['country'], $data['countries'] ) )
          return $rates; // Exit

          $product_names = get_items_names( $data['matching'], $package, $data['type'] );

          // When product match we Remove all shipping methods
          if( count($product_names) > 0 ){
          // Removing all shipping methods
          foreach( $rates as $rate_id => $rate )
          unset( $rates[$rate_id] );
          }
          }
          return $rates;
          }

          // Conditionally displaying a shipping message
          add_filter('woocommerce_cart_no_shipping_available_html','custom_country_shipping_notice', 10, 1 );
          add_filter('woocommerce_no_shipping_available_html','custom_country_shipping_notice', 10, 1 );
          function custom_country_shipping_notice( $html ){
          $package = WC()->shipping->get_packages()[0];
          if( isset($package['destination']['country']) && isset($package['contents']) ){
          // Load your settings
          $data = your_country_shipping_settings();

          // If matching allowed countries ==> We Exit
          if( in_array( $package['destination']['country'], $data['countries'] ) )
          return $html; // Exit

          $product_names = get_items_names( $data['matching'], $package, $data['type'] );

          if( count($product_names) > 0 ){
          $text = '"' . implode( '", "', $product_names ) . '" ' . $data['message'];
          $html = wpautop( $text );
          }
          }
          return $html;
          }


          Code goes in function.php file of your active child theme (active theme).



          Tested and works.



          When a cart item match with your settings and if customer is located in another country that the ones defined he will get something like:



          On cart page:



          enter image description here



          On checkout page:



          enter image description here






          share|improve this answer





















          • thank you. i will try
            – user3036214
            Feb 13 at 16:55











          Your Answer






          StackExchange.ifUsing("editor", function () {
          StackExchange.using("externalEditor", function () {
          StackExchange.using("snippets", function () {
          StackExchange.snippets.init();
          });
          });
          }, "code-snippets");

          StackExchange.ready(function() {
          var channelOptions = {
          tags: "".split(" "),
          id: "1"
          };
          initTagRenderer("".split(" "), "".split(" "), channelOptions);

          StackExchange.using("externalEditor", function() {
          // Have to fire editor after snippets, if snippets enabled
          if (StackExchange.settings.snippets.snippetsEnabled) {
          StackExchange.using("snippets", function() {
          createEditor();
          });
          }
          else {
          createEditor();
          }
          });

          function createEditor() {
          StackExchange.prepareEditor({
          heartbeatType: 'answer',
          convertImagesToLinks: true,
          noModals: true,
          showLowRepImageUploadWarning: true,
          reputationToPostImages: 10,
          bindNavPrevention: true,
          postfix: "",
          imageUploader: {
          brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
          contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
          allowUrls: true
          },
          onDemand: true,
          discardSelector: ".discard-answer"
          ,immediatelyShowMarkdownHelp:true
          });


          }
          });














          draft saved

          draft discarded


















          StackExchange.ready(
          function () {
          StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f48756521%2fset-specific-products-to-be-shipped-only-in-specific-countries-in-woocommerce%23new-answer', 'question_page');
          }
          );

          Post as a guest















          Required, but never shown

























          1 Answer
          1






          active

          oldest

          votes








          1 Answer
          1






          active

          oldest

          votes









          active

          oldest

          votes






          active

          oldest

          votes








          up vote
          0
          down vote



          accepted










          This can be done mainly with a custom function hooked in woocommerce_package_rates filter hook.



          The code below, will allow you to disable shipping, for specific products IDs or specific product categories (you can choose) based on defined country codes.



          You will have to add your settings in the first function.



          The code:



          // HERE your settings - Utility function
          function your_country_shipping_settings(){
          $results = array();
          // Can be based on "Product IDs" (or "Product categories" ==> false)
          $results['type'] = true; // or false

          // Allowed countries (Only compatible country codes - 2 digits)
          $results['countries'] = array( 'US', 'CA' );

          if( $results['type'] ){
          // Restricted product IDs
          $results['matching'] = array( 37, 38 );
          } else {
          // Restricted product categories (IDs, Slugs or Names)
          $results['matching'] = array('t-shirts', 'sweet-shirts' );
          }
          // Message
          $results['message'] = __( "can not be delivered to your country.", "woocommerce" );

          return $results;
          }

          // Utility function that check cart items
          function get_items_names( $matching, $package, $type ){
          $product_names = array();

          // Search in cart items
          foreach( $package['contents'] as $item ){
          if( $type ){
          if( in_array( $item['data']->get_id(), $matching ) )
          $product_names = $item['data']->get_name();
          } else {
          if( has_term( $matching, 'product_cat', $item['product_id'] ) )
          $product_names = $item['data']->get_name();
          }
          }
          return $product_names;
          }

          // Conditionally disabling shipping methods
          add_filter('woocommerce_package_rates','custom_country_shipping_rules', 10, 2 );
          function custom_country_shipping_rules( $rates, $package ){
          if( isset($package['destination']['country']) && isset($package['contents']) ){
          // Load your settings
          $data = your_country_shipping_settings();

          // If matching allowed countries ==> We Exit
          if( in_array( $package['destination']['country'], $data['countries'] ) )
          return $rates; // Exit

          $product_names = get_items_names( $data['matching'], $package, $data['type'] );

          // When product match we Remove all shipping methods
          if( count($product_names) > 0 ){
          // Removing all shipping methods
          foreach( $rates as $rate_id => $rate )
          unset( $rates[$rate_id] );
          }
          }
          return $rates;
          }

          // Conditionally displaying a shipping message
          add_filter('woocommerce_cart_no_shipping_available_html','custom_country_shipping_notice', 10, 1 );
          add_filter('woocommerce_no_shipping_available_html','custom_country_shipping_notice', 10, 1 );
          function custom_country_shipping_notice( $html ){
          $package = WC()->shipping->get_packages()[0];
          if( isset($package['destination']['country']) && isset($package['contents']) ){
          // Load your settings
          $data = your_country_shipping_settings();

          // If matching allowed countries ==> We Exit
          if( in_array( $package['destination']['country'], $data['countries'] ) )
          return $html; // Exit

          $product_names = get_items_names( $data['matching'], $package, $data['type'] );

          if( count($product_names) > 0 ){
          $text = '"' . implode( '", "', $product_names ) . '" ' . $data['message'];
          $html = wpautop( $text );
          }
          }
          return $html;
          }


          Code goes in function.php file of your active child theme (active theme).



          Tested and works.



          When a cart item match with your settings and if customer is located in another country that the ones defined he will get something like:



          On cart page:



          enter image description here



          On checkout page:



          enter image description here






          share|improve this answer





















          • thank you. i will try
            – user3036214
            Feb 13 at 16:55















          up vote
          0
          down vote



          accepted










          This can be done mainly with a custom function hooked in woocommerce_package_rates filter hook.



          The code below, will allow you to disable shipping, for specific products IDs or specific product categories (you can choose) based on defined country codes.



          You will have to add your settings in the first function.



          The code:



          // HERE your settings - Utility function
          function your_country_shipping_settings(){
          $results = array();
          // Can be based on "Product IDs" (or "Product categories" ==> false)
          $results['type'] = true; // or false

          // Allowed countries (Only compatible country codes - 2 digits)
          $results['countries'] = array( 'US', 'CA' );

          if( $results['type'] ){
          // Restricted product IDs
          $results['matching'] = array( 37, 38 );
          } else {
          // Restricted product categories (IDs, Slugs or Names)
          $results['matching'] = array('t-shirts', 'sweet-shirts' );
          }
          // Message
          $results['message'] = __( "can not be delivered to your country.", "woocommerce" );

          return $results;
          }

          // Utility function that check cart items
          function get_items_names( $matching, $package, $type ){
          $product_names = array();

          // Search in cart items
          foreach( $package['contents'] as $item ){
          if( $type ){
          if( in_array( $item['data']->get_id(), $matching ) )
          $product_names = $item['data']->get_name();
          } else {
          if( has_term( $matching, 'product_cat', $item['product_id'] ) )
          $product_names = $item['data']->get_name();
          }
          }
          return $product_names;
          }

          // Conditionally disabling shipping methods
          add_filter('woocommerce_package_rates','custom_country_shipping_rules', 10, 2 );
          function custom_country_shipping_rules( $rates, $package ){
          if( isset($package['destination']['country']) && isset($package['contents']) ){
          // Load your settings
          $data = your_country_shipping_settings();

          // If matching allowed countries ==> We Exit
          if( in_array( $package['destination']['country'], $data['countries'] ) )
          return $rates; // Exit

          $product_names = get_items_names( $data['matching'], $package, $data['type'] );

          // When product match we Remove all shipping methods
          if( count($product_names) > 0 ){
          // Removing all shipping methods
          foreach( $rates as $rate_id => $rate )
          unset( $rates[$rate_id] );
          }
          }
          return $rates;
          }

          // Conditionally displaying a shipping message
          add_filter('woocommerce_cart_no_shipping_available_html','custom_country_shipping_notice', 10, 1 );
          add_filter('woocommerce_no_shipping_available_html','custom_country_shipping_notice', 10, 1 );
          function custom_country_shipping_notice( $html ){
          $package = WC()->shipping->get_packages()[0];
          if( isset($package['destination']['country']) && isset($package['contents']) ){
          // Load your settings
          $data = your_country_shipping_settings();

          // If matching allowed countries ==> We Exit
          if( in_array( $package['destination']['country'], $data['countries'] ) )
          return $html; // Exit

          $product_names = get_items_names( $data['matching'], $package, $data['type'] );

          if( count($product_names) > 0 ){
          $text = '"' . implode( '", "', $product_names ) . '" ' . $data['message'];
          $html = wpautop( $text );
          }
          }
          return $html;
          }


          Code goes in function.php file of your active child theme (active theme).



          Tested and works.



          When a cart item match with your settings and if customer is located in another country that the ones defined he will get something like:



          On cart page:



          enter image description here



          On checkout page:



          enter image description here






          share|improve this answer





















          • thank you. i will try
            – user3036214
            Feb 13 at 16:55













          up vote
          0
          down vote



          accepted







          up vote
          0
          down vote



          accepted






          This can be done mainly with a custom function hooked in woocommerce_package_rates filter hook.



          The code below, will allow you to disable shipping, for specific products IDs or specific product categories (you can choose) based on defined country codes.



          You will have to add your settings in the first function.



          The code:



          // HERE your settings - Utility function
          function your_country_shipping_settings(){
          $results = array();
          // Can be based on "Product IDs" (or "Product categories" ==> false)
          $results['type'] = true; // or false

          // Allowed countries (Only compatible country codes - 2 digits)
          $results['countries'] = array( 'US', 'CA' );

          if( $results['type'] ){
          // Restricted product IDs
          $results['matching'] = array( 37, 38 );
          } else {
          // Restricted product categories (IDs, Slugs or Names)
          $results['matching'] = array('t-shirts', 'sweet-shirts' );
          }
          // Message
          $results['message'] = __( "can not be delivered to your country.", "woocommerce" );

          return $results;
          }

          // Utility function that check cart items
          function get_items_names( $matching, $package, $type ){
          $product_names = array();

          // Search in cart items
          foreach( $package['contents'] as $item ){
          if( $type ){
          if( in_array( $item['data']->get_id(), $matching ) )
          $product_names = $item['data']->get_name();
          } else {
          if( has_term( $matching, 'product_cat', $item['product_id'] ) )
          $product_names = $item['data']->get_name();
          }
          }
          return $product_names;
          }

          // Conditionally disabling shipping methods
          add_filter('woocommerce_package_rates','custom_country_shipping_rules', 10, 2 );
          function custom_country_shipping_rules( $rates, $package ){
          if( isset($package['destination']['country']) && isset($package['contents']) ){
          // Load your settings
          $data = your_country_shipping_settings();

          // If matching allowed countries ==> We Exit
          if( in_array( $package['destination']['country'], $data['countries'] ) )
          return $rates; // Exit

          $product_names = get_items_names( $data['matching'], $package, $data['type'] );

          // When product match we Remove all shipping methods
          if( count($product_names) > 0 ){
          // Removing all shipping methods
          foreach( $rates as $rate_id => $rate )
          unset( $rates[$rate_id] );
          }
          }
          return $rates;
          }

          // Conditionally displaying a shipping message
          add_filter('woocommerce_cart_no_shipping_available_html','custom_country_shipping_notice', 10, 1 );
          add_filter('woocommerce_no_shipping_available_html','custom_country_shipping_notice', 10, 1 );
          function custom_country_shipping_notice( $html ){
          $package = WC()->shipping->get_packages()[0];
          if( isset($package['destination']['country']) && isset($package['contents']) ){
          // Load your settings
          $data = your_country_shipping_settings();

          // If matching allowed countries ==> We Exit
          if( in_array( $package['destination']['country'], $data['countries'] ) )
          return $html; // Exit

          $product_names = get_items_names( $data['matching'], $package, $data['type'] );

          if( count($product_names) > 0 ){
          $text = '"' . implode( '", "', $product_names ) . '" ' . $data['message'];
          $html = wpautop( $text );
          }
          }
          return $html;
          }


          Code goes in function.php file of your active child theme (active theme).



          Tested and works.



          When a cart item match with your settings and if customer is located in another country that the ones defined he will get something like:



          On cart page:



          enter image description here



          On checkout page:



          enter image description here






          share|improve this answer












          This can be done mainly with a custom function hooked in woocommerce_package_rates filter hook.



          The code below, will allow you to disable shipping, for specific products IDs or specific product categories (you can choose) based on defined country codes.



          You will have to add your settings in the first function.



          The code:



          // HERE your settings - Utility function
          function your_country_shipping_settings(){
          $results = array();
          // Can be based on "Product IDs" (or "Product categories" ==> false)
          $results['type'] = true; // or false

          // Allowed countries (Only compatible country codes - 2 digits)
          $results['countries'] = array( 'US', 'CA' );

          if( $results['type'] ){
          // Restricted product IDs
          $results['matching'] = array( 37, 38 );
          } else {
          // Restricted product categories (IDs, Slugs or Names)
          $results['matching'] = array('t-shirts', 'sweet-shirts' );
          }
          // Message
          $results['message'] = __( "can not be delivered to your country.", "woocommerce" );

          return $results;
          }

          // Utility function that check cart items
          function get_items_names( $matching, $package, $type ){
          $product_names = array();

          // Search in cart items
          foreach( $package['contents'] as $item ){
          if( $type ){
          if( in_array( $item['data']->get_id(), $matching ) )
          $product_names = $item['data']->get_name();
          } else {
          if( has_term( $matching, 'product_cat', $item['product_id'] ) )
          $product_names = $item['data']->get_name();
          }
          }
          return $product_names;
          }

          // Conditionally disabling shipping methods
          add_filter('woocommerce_package_rates','custom_country_shipping_rules', 10, 2 );
          function custom_country_shipping_rules( $rates, $package ){
          if( isset($package['destination']['country']) && isset($package['contents']) ){
          // Load your settings
          $data = your_country_shipping_settings();

          // If matching allowed countries ==> We Exit
          if( in_array( $package['destination']['country'], $data['countries'] ) )
          return $rates; // Exit

          $product_names = get_items_names( $data['matching'], $package, $data['type'] );

          // When product match we Remove all shipping methods
          if( count($product_names) > 0 ){
          // Removing all shipping methods
          foreach( $rates as $rate_id => $rate )
          unset( $rates[$rate_id] );
          }
          }
          return $rates;
          }

          // Conditionally displaying a shipping message
          add_filter('woocommerce_cart_no_shipping_available_html','custom_country_shipping_notice', 10, 1 );
          add_filter('woocommerce_no_shipping_available_html','custom_country_shipping_notice', 10, 1 );
          function custom_country_shipping_notice( $html ){
          $package = WC()->shipping->get_packages()[0];
          if( isset($package['destination']['country']) && isset($package['contents']) ){
          // Load your settings
          $data = your_country_shipping_settings();

          // If matching allowed countries ==> We Exit
          if( in_array( $package['destination']['country'], $data['countries'] ) )
          return $html; // Exit

          $product_names = get_items_names( $data['matching'], $package, $data['type'] );

          if( count($product_names) > 0 ){
          $text = '"' . implode( '", "', $product_names ) . '" ' . $data['message'];
          $html = wpautop( $text );
          }
          }
          return $html;
          }


          Code goes in function.php file of your active child theme (active theme).



          Tested and works.



          When a cart item match with your settings and if customer is located in another country that the ones defined he will get something like:



          On cart page:



          enter image description here



          On checkout page:



          enter image description here







          share|improve this answer












          share|improve this answer



          share|improve this answer










          answered Feb 13 at 13:08









          LoicTheAztec

          82.2k125993




          82.2k125993












          • thank you. i will try
            – user3036214
            Feb 13 at 16:55


















          • thank you. i will try
            – user3036214
            Feb 13 at 16:55
















          thank you. i will try
          – user3036214
          Feb 13 at 16:55




          thank you. i will try
          – user3036214
          Feb 13 at 16:55


















          draft saved

          draft discarded




















































          Thanks for contributing an answer to Stack Overflow!


          • Please be sure to answer the question. Provide details and share your research!

          But avoid



          • Asking for help, clarification, or responding to other answers.

          • Making statements based on opinion; back them up with references or personal experience.


          To learn more, see our tips on writing great answers.





          Some of your past answers have not been well-received, and you're in danger of being blocked from answering.


          Please pay close attention to the following guidance:


          • Please be sure to answer the question. Provide details and share your research!

          But avoid



          • Asking for help, clarification, or responding to other answers.

          • Making statements based on opinion; back them up with references or personal experience.


          To learn more, see our tips on writing great answers.




          draft saved


          draft discarded














          StackExchange.ready(
          function () {
          StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f48756521%2fset-specific-products-to-be-shipped-only-in-specific-countries-in-woocommerce%23new-answer', 'question_page');
          }
          );

          Post as a guest















          Required, but never shown





















































          Required, but never shown














          Required, but never shown












          Required, but never shown







          Required, but never shown

































          Required, but never shown














          Required, but never shown












          Required, but never shown







          Required, but never shown







          這個網誌中的熱門文章

          Xamarin.form Move up view when keyboard appear

          Post-Redirect-Get with Spring WebFlux and Thymeleaf

          Anylogic : not able to use stopDelay()