How to update shipping cost in cart dynamically (ajax) based on a custom field in WooCommerce

WooCommerce by default offers only a few basic options to decide the way shipping cost is calculated. In lot of cases these options may not be sufficient and you may require to create additional checkout fields based on which shipping cost calculations are to be done

Here are a few scenarios

  1. Distance based shipping costs. In some countries e.g. district/territory field is required to decide shipping cost.
  2. For some peculiar products you may want the buyer to agree to some terms before the purchase can be made and extra cost added accordingly.
  3. Extra handling cost based on the type of packing selected

Here are the steps to achieve such requirements

Step 1: Create the necessary extra checkout fields e.g. district .

Step 2: Create JQuery file to send the parameter as a checout parameter so that the necessary calculations can be made based on the custom checkout field update

Step 3: Peform calculation based on the custom checkout field and add the value to the session variable

Step 4: Retreive the value from the session variable and assing it to the shipping cost or add it to the cost



How to add custom checkout fields to WooCommerce order

Follow below steps to add custom checkout fields to WooCommerce.

Scenario: We want to create a new address field named as territory. It will be a drop down field and will be used to decide the shipping cost.

Create the new field/s on the checkout page

To create a similar field in shipping address, $fields array would need to be duplicated mentioning [‘shipping’] instead of [‘billing’]

Now let us understand the parameters used in the above code

Hook: Creating a new field uses woocommerce_checkout_fields hook

type: Since this an drop down field the type of the field is select. If you want a mobile number field it could be a text field

required: specify whether the field is compulsory or not. In our case we are calculating the shipping cost based on this field so it is compulsory.


  1. form-row-wide: The new field will occupy the entire div width for the billing section
  2. form-row-first: The new field will appear in the first half area of the row (like the first name field)
  3. form-row-last: The new field will appear in the last half area of the row (like the last name field)
  4. address-field: specifies that it is an address field
  5. update_totals_on_change: Since we want to update the shipping price on the checkout page based on this field this class triggers the ajax update process on field value change
  6. options: Drop down field options can be provided using this parameters. Obviously this field will not be applicable for text box

Validate the newly created field

Here we are just specifying the error message to display when the field is left empty

Save the field data

Here we are saving the data to the postmeta table for the corresponding order_id after the form is submitted

Show the custom field value on the orders page under billing section