skip to Main Content

I am trying to remove the proceed to checkout button and restrict access to the checkout page until a customer fills out the ‘Calculate shipping’ option on the basket page.

I created a local shipping method that’s restricted to multiple post/zipcodes. I then went and added this to my functions.php file.

function disable_checkout_button_no_shipping() {
  $package_counts = array();

  // get shipping packages and their rate counts
  $packages = WC()->shipping->get_packages();
  foreach( $packages as $key => $pkg )
      $package_counts[ $key ] = count( $pkg[ 'rates' ] );

  // remove button if any packages are missing shipping options
  if( in_array( 0, $package_counts ) )
      remove_action( 'woocommerce_proceed_to_checkout', 'woocommerce_button_proceed_to_checkout', 20 );
}
add_action( 'woocommerce_proceed_to_checkout', 'disable_checkout_button_no_shipping', 1 );

However when I test the site in different browsers and in incognito modes the ‘Proceed to checkout’ button is there.

If I click on the ‘Calculate shipping’ link and not fill out the form but update it the button disappears. I basically want the button to appear when a customer fills out the ‘Calculate shipping’ form on the cart page (and have one of the postcodes in my shipping method) before being able to proceed to the checkout page.

2

Answers


  1. You should better try with the “Chosen shipping method” from WooCommerce session like:

    function disable_checkout_button_no_shipping() {
    
        $chosen_shipping_methods = WC()->session->get( 'chosen_shipping_methods' );
    
        // remove button if there is no chosen shipping method
        if( empty( $chosen_shipping_methods ) ) {
            remove_action( 'woocommerce_proceed_to_checkout', 'woocommerce_button_proceed_to_checkout', 20 );
        }
    }
    add_action( 'woocommerce_proceed_to_checkout', 'disable_checkout_button_no_shipping', 1 );
    

    Or in a different way using woocommerce_check_cart_items action hook:

    add_action( 'woocommerce_check_cart_items', 'required_chosen_shipping_methods' );
    function required_chosen_shipping_methods() {
        $chosen_shipping_methods = WC()->session->get( 'chosen_shipping_methods' );
    
        if( is_array( $chosen_shipping_methods ) && count( $chosen_shipping_methods ) > 0 ) {
            // Display an error message
            wc_add_notice( __("A shipping method is required in order to proceed to checkout."), 'error' );
        }
    }
    

    It should better work.

    Login or Signup to reply.
  2. The code above didn’t work ($chosen_shipping_methods is an array and if it has more than 0 elements this condition will always be true because $chosen_shipping_methods is an array that is initialized with a default value of array(”) in WooCommerce), so I rejigged it:

    add_action( 'woocommerce_check_cart_items', 'required_chosen_shipping_methods' );
    function required_chosen_shipping_methods() {
        $chosen_shipping_methods = WC()->session->get( 'chosen_shipping_methods' );
    
        // Check if $chosen_shipping_methods is an array and if it contains a valid shipping method
        if( is_array( $chosen_shipping_methods ) && ! in_array( '', $chosen_shipping_methods ) ) {
            // A valid shipping method has been selected, so do nothing
            return;
        }
    
        // Display an error message
        wc_add_notice( __("A shipping method is required in order to proceed to checkout."), 'error' );
    }
    
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search