WooCommerce: Add Order Fees After Checkout

In a recent Business Bloomer Club Slack conversation, a WooCommerce developer was working on adding a custom fee to orders within the woocommerce_checkout_create_order hook. While the fee appeared correctly in the order’s breakdown, the order total failed to update to reflect this fee on both the Thank You page and in the WooCommerce admin. The user noticed that the total only adjusted after manually clicking “Recalculate” on the admin order page, indicating a missing step in their code to trigger an automatic recalculation of the order total.

In WooCommerce, adding custom fees is a common requirement, especially for special shipping conditions or additional services. Here, I’ll walk through the correct approach to ensure that added fees are properly integrated into the order total right from the moment the order is created.

Why the Order Total Didn’t Update Automatically

WooCommerce’s calculate_totals() method is essential for recalculating an order’s total after modifications. However, as seen here, the calculate_totals() method alone may not always apply the changes unless properly saved.

Code Solution for Adding a Fee and Updating the Order Total

Below is the corrected approach for adding a fee within the woocommerce_checkout_create_order hook, including the necessary steps to recalculate and save the updated order total.

Step 1: Add the Fee to the Order

Using the WC_Order_Item_Fee class, you can add a custom fee to the order. Here’s the initial setup:

$item_fee = new WC_Order_Item_Fee();
$item_fee->set_name( "Cold Shipping (" . $option["label"] . ")" );
$item_fee->set_amount( $option["price"] );
$item_fee->set_tax_class( '' );
$item_fee->set_tax_status( 'none' );
$item_fee->set_total( $option["price"] );
$order->add_item( $item_fee );

Step 2: Update Order Metadata (Optional)

If needed, add any relevant metadata for the fee:

$order->update_meta_data( 'cold_shipping_cost', $option["price"] );

Step 3: Recalculate Totals and Save the Order

To ensure the fee reflects in the order total, you need to call calculate_totals() and then save the order:

$order->calculate_totals();
$order->save();

If taxes are enabled, you may also want to include calculate_taxes() before calculate_totals() as follows:

$order->calculate_taxes();
$order->calculate_totals();
$order->save();

Full Code Example

Combining all steps, the full code for adding the fee and updating the order total is as follows:

add_action( 'woocommerce_checkout_create_order', 'add_custom_fee_to_order', 20, 2 );

function add_custom_fee_to_order( $order, $data ) {
    $option = array( 'label' => 'Cold Shipping', 'price' => 10.00 ); // example values

    $item_fee = new WC_Order_Item_Fee();
    $item_fee->set_name( "Cold Shipping (" . $option["label"] . ")" );
    $item_fee->set_amount( $option["price"] );
    $item_fee->set_tax_class( '' );
    $item_fee->set_tax_status( 'none' );
    $item_fee->set_total( $option["price"] );
    $order->add_item( $item_fee );

    $order->update_meta_data( 'cold_shipping_cost', $option["price"] );

    // Recalculate totals and save order
    $order->calculate_totals();
    $order->save();
}

Summary

By ensuring that you call calculate_totals() and save() after adding the fee, WooCommerce will automatically update the order total, reflecting the additional fee across all checkout and admin pages without requiring any manual recalculations. This solution provides a streamlined experience for both customers and store admins, maintaining accuracy in order totals and enhancing the checkout process.

Related content

Rodolfo Melogli

Business Bloomer Founder

Author, WooCommerce expert and WordCamp speaker, Rodolfo has worked as an independent WooCommerce freelancer since 2011. His goal is to help entrepreneurs and developers overcome their WooCommerce nightmares. Rodolfo loves travelling, chasing tennis & soccer balls and, of course, wood fired oven pizza. Follow @rmelogli

Reply

Your email address will not be published. Required fields are marked *