0

I have one particular item that I do not want shipped overseas. Everything else is fine. I already created a shipping class for it and when it gets added to the cart, it has no shipping added to it and the button doesn't let the customer pay. So, all of this is out-of-the-box in woocommerce. The problem is, when someone overseas wants to buy multiple items and one of them happens to be the one I do not ship overseas. It still adds it to the cart total even though it says it wont be shipped!! See screenshot

enter image description here

I found the code snippet below that I think it's somewhat the concept of what I need but this one removes a shipping method. I am not a PHP developer or Wordpress Codex developer. I'm a front end dev/designer. So, please be gentle lol I do know I don't want to load my site with plugins for something so simple.

Simply put, I just need the cart to remove any item without a shipping method from the total. So, in my example, it would say $59 in the total ($55 + $4 shipping). The $45 item gets knocked out of the total for not being able to be shipped

add_filter( 'woocommerce_package_rates', 'bbloomer_hide_free_shipping_for_shipping_class', 9999, 2 );
  
function bbloomer_hide_free_shipping_for_shipping_class( $rates, $package ) {
  $shipping_class_target = 15; // shipping class ID (to find it, see screenshot below)
  $in_cart = false;
  foreach ( WC()->cart->get_cart_contents() as $key => $values ) {
      if ( $values[ 'data' ]->get_shipping_class_id() == $shipping_class_target ) {
        $in_cart = true;
        break;
      } 
  }
  if ( $in_cart ) {
      unset( $rates['free_shipping:8'] ); // shipping method with ID (to find it, see screenshot below)
  }
  return $rates;
}
LOTUSMS
  • 10,317
  • 15
  • 71
  • 140

2 Answers2

1

Use woocommerce_package_rates hook since it is called after user entered their shipping details and that is how you can check whether it is overseas shipping or not. This code also will check each cart item and whether it has specific shipping class slug. If both checks out, then it will remove the item from the cart and shows the notice to the user. Code goes into theme functions.php.

add_filter( 'woocommerce_package_rates', 'remove_product_from_cart', 10, 2 );
function remove_product_from_cart($rates, $package) {

    foreach( WC()->cart->get_cart() as $key => $item ){

        $product = wc_get_product( $item['product_id'] );
        $product_name = $product->get_title();
        $is_prohibited_product = 'your-shipping-class-slug-here' === $product->get_shipping_class();
        $is_shipping_overseas = 'US' !== WC()->customer->get_shipping_country();

        if( $is_prohibited_product && $is_shipping_overseas ){
            WC()->cart->remove_cart_item($key);

            wc_add_notice( __( "{$product_name} has been removed from cart because we can't ship that overseas.", 'theme_domain' ), 'error' );
        }
    }

    return $rates;
}
Zaim
  • 466
  • 5
  • 17
  • This worked, extremely aggressive! lol It didn't even let me add it to the cart! But I guess that works because why have an item that cant' be bought from your country anyway? I accept this answer. Thanks! Also, I did a minor adjustment. Instead of "US", it needed to be 'United States (US)'. – LOTUSMS Jul 19 '22 at 14:10
0

first of all, find your unique 'shipping class id', if you haven't, figure out what it is from the instructions that it is described in this question best answer.

then you can remove that product from the cart with something like this (put below script in your function.php) :

add_action( 'woocommerce_before_checkout', 'remove_product_from_cart' );
add_action( 'woocommerce_before_cart', 'remove_product_from_cart' );
add_action( 'template_redirect', 'remove_product_from_cart' );

function remove_product_from_cart() {
    if ( is_admin() ) return;
    $shipping_class_target = 15; // the id 15 is an example from what you find in prev step 
    foreach ( WC()->cart->get_cart_contents() as $key => $values ) {
        if ( $values[ 'data' ]->get_shipping_class_id() == $shipping_class_target ) {
            $product_id = $values['product_id'];
            $product_cart_id = WC()->cart->generate_cart_id( $product_id );
            $cart_item_key = WC()->cart->find_product_in_cart( $product_cart_id );
            if ( $cart_item_key ) WC()->cart->remove_cart_item( $cart_item_key );   
        }
         

     } 
}
behzad m salehi
  • 1,038
  • 9
  • 23