user6684898
user6684898

Reputation:

Set "free shipping" method as selected default shipping option in WooCommerce

I'm struggling with changing the shipping option selected default. The 'Free shipping' shipping option only shows up if the customer has the amount over $70 + in the cart. If the amount on the cart is less than $70 the shipping option will not show up on the shipping options.

If the customer has over $70 or more, the "Free shipping" option will show up and it should be a default selected shipping option.

I tried adding the following snippet but it seems not working for me or maybe there's a mistake on modifying the ID's(unsure).

add_action( 'woocommerce_before_cart', 'set_default_chosen_shipping_method', 5 );
function set_default_chosen_shipping_method(){
    //
    if( count( WC()->session->get('shipping_method_0')['rates'] ) > 0 ){
        foreach( WC()->session->get('shipping_method_0')['rates'] as $rate_id =>$rate)
            if($rate->method_id == 'free_shipping30'){
                $default_rate_id = array( $rate_id );
                break;
            }

        WC()->session->set('chosen_shipping_methods', $default_rate_id );
    }
}

I got this snippet idea here

enter image description here

enter image description here

Thank you in advance!!

Upvotes: 4

Views: 3353

Answers (3)

Reagan
Reagan

Reputation: 2377

I think this might be helpful as well. Using Javascript and JS checkout event checkout_init

I combined jQuery and Javascript because I only have limited knowledge with jQuery.

jQuery(document).ready(function($) {
$(document).on('init_checkout', function() {
    const shippingOptions = document.querySelectorAll('#shipping_method input')
    if(!shippingOptions && shippingOptions.length === 0) {
        return
    }
    shippingOptions.forEach((shipping) => {
       if(shipping.value.includes('free_shipping')) {
        shipping.checked = true
        const event = new Event('click');
        dropdown.dispatchEvent(event);
       }
    })
});
});

Upvotes: 0

autopoietic
autopoietic

Reputation: 197

The answer given by @7uc1f3r does deselect free shipping if available, but also deselects other default shipping methods* if no free shipping is available, resulting in no shipping method being selected.

The following should only affect the default shipping method if there is a free shipping method available.

function select_free_shipping_by_default()
{
    if ($rates = WC()->session->get('shipping_for_package_0')['rates']) {
        foreach ($rates as $rate_id => $rate) {
            if ($rate->method_id == 'free_shipping') {
                WC()->session->set('chosen_shipping_methods', array($rate_id));
                break;
            }
        }
    }
}
add_action('woocommerce_before_cart', 'select_free_shipping_by_default', 10, 0);

Depending on your aesthetic, you could alternatively accomplish this without a the foreach loop, though I accept this may be less legible (and would require PHP 7.4+ for the arrow function).

function select_free_shipping_by_default()
{
    if ($rates = WC()->session->get('shipping_for_package_0')['rates']) {
        if ($free = array_filter($rates, fn ($x) => $x->method_id == 'free_shipping')) {
            WC()->session->set('chosen_shipping_methods', array_keys($free));
        }
    }
}
add_action('woocommerce_before_cart', 'select_free_shipping_by_default', 10, 0);

Tested on: WooComerce 8.3.1 | WordPress 6.4.3 | PHP 8.1.23

Hope this helps someone :)


* The default selection for shipping method is normally configured in the admin. The first item in drag/drop order of the shipping methods in the relevant shipping zone is selected by default (eg at /wp-admin/admin.php?page=wc-settings&tab=shipping&zone_id=1).

Upvotes: 0

7uc1f3r
7uc1f3r

Reputation: 29614

Your code contains some mistakes

  • Replace WC()->session->get('shipping_method_0')['rates'] with WC()->session->get( 'shipping_for_package_0')['rates']
  • Replace if($rate->method_id == 'free_shipping30'){ with if ( $rate->method_id == 'free_shipping' ) {

So you get:

function action_woocommerce_before_cart() { 
    // NOT empty (get)
    if ( count( WC()->session->get( 'shipping_for_package_0')['rates'] ) > 0 ) {
        // Loop through
        foreach ( WC()->session->get('shipping_for_package_0')['rates'] as $rate_id => $rate ) {            
            // For free shipping
            if ( $rate->method_id == 'free_shipping' ) {
                $default_rate_id = array( $rate_id );
                break;
            }
        }

        // Set
        WC()->session->set( 'chosen_shipping_methods', $default_rate_id );
    }
}
add_action( 'woocommerce_before_cart', 'action_woocommerce_before_cart', 10, 0 );

Upvotes: 5

Related Questions