Search code examples
phpwoocommercecartcheckoutshipping-method

Shipping methods only enabled in checkout page on Woocommerce


On Woocommerce, we need to remove the shipping-methods from the Cart section an add it to the Checkout page only.

Any track or help should be really appreciated?


Solution

  • There will be multiple ways to do it depending on the "why?" and on "for what?" you need this:

    1) Hide shipping related from cart - The easiest way;

    add_filter( 'woocommerce_cart_ready_to_calc_shipping', 'disable_shipping_on_cart' );
    add_filter( 'woocommerce_cart_needs_shipping', 'disable_shipping_on_cart' );
    function disable_shipping_on_cart( $enabled ){
        return is_checkout() ? true : false;
    }
    

    Code goes in function.php file of your active child theme (or active theme). Tested and work.

    enter image description here

    But it will not remove the shipping methods (or shipping packages) from session…


    2) Remove all shipping methods (and shipping packages) everywhere except in checkout page:

    // Shipping methods
    add_filter( 'woocommerce_package_rates', 'keep_shipping_methods_on_checkout', 100, 2 );
    function keep_shipping_methods_on_checkout( $rates, $package ) {
        if ( ! is_checkout() ) {
            // Loop through shipping methods rates
            foreach( $rates as $rate_key => $rate ){
                unset($rates[$rate_key]); // Remove
            }
        }
        return $rates;
    }
    
    // Shipping packages
    add_filter( 'woocommerce_shipping_packages', 'keep_shipping_packages_on_checkout', 20, 1 );
    add_filter( 'woocommerce_cart_shipping_packages', 'keep_shipping_packages_on_checkout', 20, 1 );
    function keep_shipping_packages_on_checkout( $packages ) {
        if ( ! is_checkout() ) {
            foreach( $packages as $key => $package ) {
                WC()->session->__unset('shipping_for_package_'.$key); // Remove
                unset($packages[$key]); // Remove
            }
        }
        return $packages;
    }
    

    Code goes in function.php file of your active child theme (or active theme). Tested and work.

    enter image description here

    It will remove all shipping methods and all shipping packages from cart and WC_Session.

    The related registered WC_Session data will be something like:

    WC_Session_Handler Object
    (
        [_data:protected] => Array
            (
                [previous_shipping_methods] => a:1:{i:0;a:3:{i:0;s:16:"free_shipping:10";i:1;s:12:"flat_rate:14";i:2;s:15:"local_pickup:13";}}
                [shipping_method_counts] => a:1:{i:0;i:3;}
                [chosen_shipping_methods] => a:1:{i:0;s:16:"free_shipping:10";}
            )
    )
    

    without shipping package…

    It will only keep the previous shipping methods and the previous chosen shipping method for customers that have already purchased something before.