WooCommerce: Add Fee To Order During Checkout If Cash On Delivery Or Any Other Reason/Gateway

Recently I was tasked with adding a field to the cash on delivery gateway in WooCommerce.  They wanted a field they could put in a dollar amount that would be tacked on as a fee to orders using that gateway.  Seemed simple enough with some googling but took a bit longer to tweak and get functioning correctly.

Add Field to Cash On Delivery Gateway

Adding fields in WooCommerce to its forms is pretty straight forward.  You hook into the WC Settings API and adjust them using this hook:

add_filter( 'woocommerce_settings_api_form_fields_<id>', function( $form_fields ) { return $form_fields; } );

Replace <id> with the id of the form.  In this case it’s “cod” for the Cash on Delivery form. In your hooked function you can manipulate the form fields array as needed.  For my case I just needed to add a field at the end for a fee so I do this:

https://gist.github.com/ChrisFlannagan/bcfe4ea1cbfdcd629db7f292c22cc40c

Add Fee To The Order

Now that we have a fee set we need to hook into the checkout process.  For this I use the action “woocommerce_checkout_create_order” to manipulate the order right before it’s saved.  In WooCommerce 3.0 and over you no longer use the add_fee() function but instead create a line item fee object and add that to the order.  Here’s how I did what I needed:

https://gist.github.com/ChrisFlannagan/ae68a43ec4b60ac741c95715e58dd001

SUPER IMPORTANT

Notice the add_item( $item ) call to place it in the order.  If that’s all you do then you will see the fee on the order but the order total won’t include it.  You need to make sure you run the order’s calculate_totals() function after adding the item.

2 thoughts on “WooCommerce: Add Fee To Order During Checkout If Cash On Delivery Or Any Other Reason/Gateway”

  1. I’m sorry but i don’t understand because i’m not a developer.
    My customer wants to add a a fee (5 euors) if a buyer select cash on delivery as payment methods.
    in the new woocommerce what and where have i to add the code, that works only for COD methods selected in the cart page?
    I apologize for my bad english.
    Thanks for reading my question

    1. /**
      * Add COD fee 20 Baht
      */
      add_action(‘woocommerce_cart_calculate_fees’, ‘cod_fee’);

      function cod_fee()
      {
      if (is_admin() && !defined(‘DOING_AJAX’))
      return;

      $chosen_gateway = WC()->session->chosen_payment_method;

      $fee = 20;

      if ($chosen_gateway == ‘cod’) { //test with cash on delivery method
      WC()->cart->add_fee(__(‘COD delivery fee’, ‘m2spop’), $fee, false, ”);
      }
      }

Leave a Reply

Your email address will not be published.