/** * Adds cart fees based on the product's category. * * @see https://wpcodebook.com/cart-fees-product-category-woocommerce-php/ * @see https://github.com/woocommerce/woocommerce/blob/8.0.1/plugins/woocommerce/includes/class-wc-cart.php#L1893 * @see https://github.com/woocommerce/woocommerce/blob/8.0.1/plugins/woocommerce/includes/class-wc-cart.php#L1919 * @see https://github.com/woocommerce/woocommerce/blob/8.0.1/plugins/woocommerce/includes/class-wc-cart.php#L597 * @see https://github.com/woocommerce/woocommerce/blob/8.0.1/plugins/woocommerce/includes/abstracts/abstract-wc-product.php * @see https://developer.wordpress.org/reference/functions/get_term_by/ */ add_action( 'woocommerce_cart_calculate_fees', function ( $cart ) { // Set your fees here, in `category slug` => `fee amount` format $fee_amounts = array( 'shirts' => 10.50, 'jackets' => 12.50, 'accessories' => 15.00, ); // Prepare fees $fees = array(); foreach ( $cart->get_cart() as $cart_item_key => $values ) { if ( is_a( $values['data'], 'WC_Product' ) ) { $product = $values['data']; // Get product categories $category_ids = $product->get_category_ids(); if ( empty( $category_ids ) && 0 != ( $parent_id = $product->get_parent_id() ) && ( $parent_product = wc_get_product( $parent_id ) ) ) { $category_ids = $parent_product->get_category_ids(); } // Product categories loop foreach ( $category_ids as $category_id ) { if ( ( $term = get_term_by( 'term_id', $category_id, 'product_cat' ) ) && ! empty( $fee_amounts[ $term->slug ] ) ) { $name = sprintf( esc_html__( '%s fee (%s)' ), $product->get_name(), $term->name ); if ( ! isset( $fees[ $name ] ) ) { $fees[ $name ] = 0; } $fees[ $name ] += ( $fee_amounts[ $term->slug ] * $values['quantity'] ); } } } } // Add fees if ( ! empty( $fees ) ) { foreach ( $fees as $name => $amount ) { /** * - WooCommerce sorts fees by amount (see the `woocommerce_sort_fees_callback` filter). * - Last two params are `taxable` and `tax_class`. */ $cart->add_fee( $name, $amount, true, '' ); } } } );