If your WooCommerce store sells products that require extra charges — think tariffs, recycling fees, or packaging costs — you may want to apply those fees only to specific products or variations. Instead of using blanket fees at the cart level, this snippet gives you granular control by letting you toggle the fee on or off for each product directly from the edit screen.
Once enabled, the fee is calculated as a fixed percentage (e.g. 20%) and automatically added at checkout. This works for simple and variable products.
Whether you need to meet regulatory requirements or recover specific costs, this solution offers a flexible, admin-friendly way to charge per-product fees.

PHP Snippet: Add Optional Product Fees in WooCommerce
This snippet enables store owners to apply optional, per-product fees in WooCommerce, ideal for tariffs or special surcharges. First, it adds a checkbox to both simple products and single variations in the backend. This allows the admin to enable a fee manually for each item.
When a product with the fee enabled is added to the cart, the fee is calculated as a percentage of the product’s price before tax (and specifically a 20% tariff, hardcoded in the bbloomer_checkout_fee function). If a variation doesn’t have its own fee setting, the parent product’s setting is used.
Finally, during checkout, WooCommerce adds the fee as a separate line item, using a custom label (hardcoded in the bbloomer_checkout_fee function) and matching the product’s tax class.
/**
* @snippet Per-Product / Per-Variation Fee @ WooCommerce Checkout
* @tutorial https://businessbloomer.com/woocommerce-customization
* @author Rodolfo Melogli, Business Bloomer
* @compatible WooCommerce 9
* @community https://businessbloomer.com/club/
*/
// Add checkbox to simple products
add_action( 'woocommerce_product_options_general_product_data', 'bbloomer_product_fee' );
function bbloomer_product_fee() {
woocommerce_wp_checkbox( [
'id' => '_enable_custom_fee',
'label' => 'Enable Fee',
'description' => 'Apply fee at checkout for this product.',
] );
}
// Save checkbox for simple products
add_action( 'woocommerce_process_product_meta', 'bbloomer_product_fee_save' );
function bbloomer_product_fee_save( $post_id ) {
update_post_meta( $post_id, '_enable_custom_fee', isset( $_POST['_enable_custom_fee'] ) ? 'yes' : 'no' );
}
// Add checkbox to product variations
add_action( 'woocommerce_variation_options_pricing', 'bbloomer_variation_fee', 10, 3 );
function bbloomer_variation_fee( $loop, $variation_data, $variation ) {
woocommerce_wp_checkbox( [
'id' => '_enable_custom_fee[' . $loop . ']',
'label' => 'Enable Fee',
'description' => 'Apply fee at checkout for this variation.',
'value' => get_post_meta( $variation->ID, '_enable_custom_fee', true ),
] );
}
// Save variation checkbox
add_action( 'woocommerce_save_product_variation', 'bbloomer_variation_fee_save', 10, 2 );
function bbloomer_variation_fee_save( $variation_id, $i ) {
$fee_value = isset( $_POST['_enable_custom_fee'][ $i ] ) ? 'yes' : 'no';
update_post_meta( $variation_id, '_enable_custom_fee', $fee_value );
}
// Add fee at checkout
add_action( 'woocommerce_cart_calculate_fees', 'bbloomer_checkout_fee', 9999 );
function bbloomer_checkout_fee( $cart ) {
if ( is_admin() && ! defined( 'DOING_AJAX' ) ) return;
$tariff_percent = 20; // SET THE FEE PERCENTAGE
$fee_label = 'Import Fee'; // SET THE LABEL
foreach ( $cart->get_cart() as $cart_item ) {
$product_id = $cart_item['variation_id'] > 0 ? $cart_item['variation_id'] : $cart_item['product_id'];
$parent_id = $cart_item['product_id'];
$enable_fee = get_post_meta( $product_id, '_enable_custom_fee', true );
// Fallback to parent product if variation doesn't have its own setting
if ( $enable_fee !== 'yes' && $product_id !== $parent_id ) {
$enable_fee = get_post_meta( $parent_id, '_enable_custom_fee', true );
}
if ( $enable_fee === 'yes' ) {
$fee_amount = $tariff_percent / 100 * wc_get_price_excluding_tax( $cart_item['data'] ) * $cart_item['quantity'];
$cart->add_fee( $fee_label . ' (' . $cart_item['data']->get_name() . ')', $fee_amount, true, $cart_item['data']->get_tax_class() );
}
}
}