Adding a handling fee to your Woocommerce store without a plugin.

Want to add a handling fee to your Woocommerce store products, but don’t want to buy an expensive plugin? There is an easy way to accomplish this with a snippet.

In the store I am working on, the client wants a handling fee, but only if the product is a physical item that is being shipped. Since they also sell PDF’s that don’t require shipping, we don’t want the handling fee to be added to those. But we do want the handling fee if the order contains both PDF and a physical item.

So here you go – just add the following to your functionality plugin. It is tested and works as of Woocommerce v8+. This code snippet adds a $3 handling fee, but you can change it to whatever price you would like.

/* Add handling fee of $3 to cart at checkout */
add_action( 'woocommerce_cart_calculate_fees','handling_fee' );
function handling_fee() {
    global $woocommerce; 

    if ( is_admin() && ! defined( 'DOING_AJAX' ) )
        return;

    // First test if all products are virtual. Only add fee if at least one product is physical.
    $allproductsvirtual = true; 
    $fee = 0;
    foreach ( $woocommerce->cart->get_cart() as $cart_item_key => $values) {

        $product = $values['data'];

        if( !$product->is_virtual() ){
            $allproductsvirtual = false;
        }
    }
    if ( !$allproductsvirtual ) {
        $fee = 3.00;
    }
    $woocommerce->cart->add_fee( 'Handling', $fee, false, 'standard' );
}

The extended explanation…

WooCommerce has a built-in system that lets developers hook into different parts of the checkout process. One of those moments is when WooCommerce calculates cart totals.
This snippet taps into that moment and runs a quick check on what’s in the cart.

It loops through each item and asks a simple question – “Is this product virtual (like a PDF), or does it need to be shipped?”

If everything in the cart is virtual, nothing happens and no fee is added. The moment it finds even one physical product, it flags the order as needing handling.
Once that check is done, the snippet adds a flat handling fee to the cart before totals are finalized.

The important part isn’t the fee itself – it’s the conditional logic.

Instead of blindly adding a fee to every order, the code looks at the type of products in the cart and makes a decision based on that.

That means:
Digital-only orders stay clean (no unnecessary charges)
Physical orders get the extra handling cost
Mixed carts behave correctly without any extra setup

Why This Approach Is Nice
No plugin needed
No per-product setup
Automatically adapts to whatever is in the cart
Works with simple and variable products

It’s a small piece of code, but it’s using WooCommerce exactly how it was designed to be extended.

Leave a Reply

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