Christian Giupponi
Christian Giupponi

Reputation: 7618

Add a fee based on chosen shipping method in WooCommerce

In WooCommerce, I need to add a fee when user select specific shipping methods.

I have found "Add a fee based on shipping method and payment method in Woocommerce" answer, that looks like what I need.

I have tried the code and removed the pieces about payment method which I don't need.

The problem is that when I change the shipping method the fee is not added, looks like that I just keep the old value in the session.

This is my code:

// Add a conditional fee
add_action( 'woocommerce_cart_calculate_fees', 'add_cod_fee', 20, 1 );
function add_cod_fee( $cart ) {
    if ( is_admin() && ! defined( 'DOING_AJAX' ) )
        return;

    $chosen_shipping_method_id = WC()->session->get( 'chosen_shipping_methods' )[0];

    var_dump($chosen_shipping_method_id); die;

    switch($chosen_shipping_method_id){
        case 'flat_rate:3': {
            $fee_text = __( "Spese per ritiro", "woocommerce" );
            $cart->add_fee( $fee_text, 12, false );
            break;
        }
        case 'flat_rate:4': {
            $fee_text = __( "Spese per consegna a domicilio", "woocommerce" );
            $cart->add_fee( $fee_text, 24, false );
            break;
        }

    }
}

// Refresh checkout on payment method change
add_action( 'wp_footer', 'refresh_checkout_script' );
function refresh_checkout_script() {
    // Only on checkout page
    if( is_checkout() && ! is_wc_endpoint_url('order-received') ) :
    ?>
    <script type="text/javascript">
    jQuery(function($){
        // On payment method change
        $('form.woocommerce-checkout').on( 'change', '.shipping_method', function(){
            // Refresh checkout
            $('body').trigger('update_checkout');
        });
    })
    </script>
    <?php
    endif;
}

It just keep the old value in $chosen_shipping_method_id

Upvotes: 1

Views: 1609

Answers (1)

LoicTheAztec
LoicTheAztec

Reputation: 253784

Your code works nicely if you comment var_dump($chosen_shipping_method_id); die;. Also the jQuery script is not needed as it was for payment methods that doesn't update checkout by default.

So there is something else that is making trouble in your case.

Now I have revisited a bit your code (it will work too):

// Add a conditional fee
add_action( 'woocommerce_cart_calculate_fees', 'flat_rate_based_fee', 20, 1 );
function flat_rate_based_fee( $cart ) {
    if ( is_admin() && ! defined( 'DOING_AJAX' ) )
        return;

    $chosen_shipping_methods = WC()->session->get( 'chosen_shipping_methods' );

    if( in_array( 'flat_rate:3', $chosen_shipping_methods ) ) {
        $fee = array( 'text' => __( "Spese per ritiro", "woocommerce" ), 'amount' => 12 );
    } elseif ( in_array( 'flat_rate:4', $chosen_shipping_methods ) ) {
        $fee = array( 'text' => __( "Spese per consegna a domicilio", "woocommerce" ), 'amount' => 24 );
    }

    if( isset($fee) ) {
        $cart->add_fee( $fee['text'], $fee['amount'], false );
    }
}

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

Tested and work (on Woocommerce 3.5.x and 3.6.x). See it working live on this test server.

Upvotes: 1

Related Questions