skip to Main Content

On my WooCommerce site I use this function to add a 4€ fee if you select cash on delivery as payment method:

add_action('woocommerce_cart_calculate_fees', 'increase_cod_cost');

function increase_cod_cost() {
  if(WC()->session->chosen_payment_method=='cod')
    WC()->cart->add_fee(__('COD Fee'), 4);
}

I also use this function to immediately update the checkout whenever you change payment method so that the fee is added when you select cod, and removed when you select any other method:

add_action('woocommerce_review_order_before_payment', 'custom_checkout_update');

function custom_checkout_update() {
  echo '
    <script type="text/javascript">
    (function($){
    $('form.checkout').on('change', 'input[name="payment_method"]', function() {
    $('body').trigger('update_checkout');
    });
    })(jQuery);
    </script>
  ';
}

Both functions work 100%.

Now, Instead of adding a fee, I’d like to properly increase the actual shipping cost, so I’ve tried this function instead of the first one:

add_filter('woocommerce_package_rates', 'increase_cod_cost_2', 10, 2);

function increase_cod_cost_2($rates, $package) {
  if(WC()->session->chosen_payment_method=='cod')
    $rates['flat_rate:1']->cost=$rates['flat_rate:1']->cost+4;
  return $rates;
}

This function also works, but only if I empty the cart and then add a product again. For some reason it doesn’t immediately update the shipping cost whenever I select cod. I really don’t understand why the jQuery function would work with the first php function by adding the fee, but not with this one by changing the shipping cost. Can you please help me and tell me what’s wrong? Thank you.

2

Answers


  1. I cannot actually help you to fully understand what is going wrong, but I can share you some experience:
    Try to include log commands in these cases, it helps you to see when the hook is called, if it is called and depending on your log details if the code went through the if clause or fell into the else case

    From experience and what you write, the second hook is not always called, therefore it works when you freshly add a product but not during an shipping method change during checkout.
    So I am wildly guessing you probably need another hook like

    do_action( 'woocommerce_shipping_method_chosen', $chosen_method );
    

    or something better which triggers whenever woocommerce goes to look for the available shipping methods.

    Be careful that the hooks are not called sequentially and you add 4 USD more han 1 time…

    PD: I’ve noticed that the suggested hook is not ideal neither, you could try one of these:

    add_action( 'woocommerce_load_shipping_methods', 'action_woocommerce_load_shipping_methods', 10, 1 ); 
    add_filter( 'woocommerce_package_rates', 'woocommerce_package_rates' );
    

    or else check here all the woocommerce hooks:
    https://docs.woocommerce.com/wc-apidocs/hook-docs.html

    Login or Signup to reply.
  2. Please try this.

    add_filter( 'woocommerce_package_rates', 'custom_shipping_costs', 20, 2 );
    function custom_shipping_costs( $rates, $package ) {
        // New shipping cost (can be calculated)
        $new_cost = 1000;
        $tax_rate = 0.4;
    
        foreach( $rates as $rate_key => $rate ){
            // Excluding free shipping methods
            if( $rate->method_id != 'free_shipping'){
    
                // Set rate cost
                $rates[$rate_key]->cost = $new_cost;
    
                // Set taxes rate cost (if enabled)
                $taxes = array();
                foreach ($rates[$rate_key]->taxes as $key => $tax){
                    if( $rates[$rate_key]->taxes[$key] > 0 )
                        $taxes[$key] = $new_cost * $tax_rate;
                }
                $rates[$rate_key]->taxes = $taxes;
    
            }
        }
        return $rates;
    }
    
    
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search