Add a fee to WooCommerce per product, based on category
I was having the same issue and came across a code snippet that set me on the correct path. For the life of me, I cannot find the original site that housed the snippet, but here is my reworked version.
function df_add_ticket_surcharge( $cart_object ) {
global $woocommerce;
$specialfeecat = 86; // category id for the special fee
$spfee = 0.00; // initialize special fee
$spfeeperprod = 0.05; //special fee per product
foreach ( $cart_object->cart_contents as $key => $value ) {
$proid = $value['product_id']; //get the product id from cart
$quantiy = $value['quantity']; //get quantity from cart
$itmprice = $value['data']->price; //get product price
$terms = get_the_terms( $proid, 'product_cat' ); //get taxonamy of the prducts
if ( $terms && ! is_wp_error( $terms ) ) :
foreach ( $terms as $term ) {
$catid = $term->term_id;
if($specialfeecat == $catid ) {
$spfee = $spfee + $itmprice * $quantiy * $spfeeperprod;
}
}
endif;
}
if($spfee > 0 ) {
$woocommerce->cart->add_fee( 'Ticket Concierge Charge', $spfee, true, 'standard' );
}
}
add_action( 'woocommerce_cart_calculate_fees', 'df_add_ticket_surcharge' );
This will add a 5% surcharge to each item in the cart with the category of ticket (id: 86). I hope this helps you out, if you have not found a solution already.
Add a fee for a specific product category in Woocommerce
The code you are using is a bit outdated and you should use has_term()
Wordpress conditional function to target a product category this way:
add_action( 'woocommerce_cart_calculate_fees','custom_pcat_fee', 20, 1 );
function custom_pcat_fee( $cart ) {
if ( is_admin() && ! defined( 'DOING_AJAX' ) )
return;
// Set HERE your categories (can be term IDs, slugs or names) in a coma separated array
$categories = array('349');
$fee_amount = 0;
// Loop through cart items
foreach( $cart->get_cart() as $cart_item ){
if( has_term( $categories, 'product_cat', $cart_item['product_id']) )
$fee_amount = 60;
}
// Adding the fee
if ( $fee_amount > 0 ){
// Last argument is related to enable tax (true or false)
WC()->cart->add_fee( __( "Extra bezorgkosten kunstgras", "woocommerce" ), $fee_amount, false );
}
}
Code goes in function.php file of your active child theme (or active theme). Tested and works.
A fee of 60 will always be added if there is in cart an item from 349 product category ID.
How to add fees based on product categories and quantity in WooCommerce
Your code contains some mistakes and/or could be optimized:
- When calculating the totals, you do not take into account the quantity
- Your if condition for adding the fee, is in your foreach loop, so it is overwritten every loop
- The use of
WC()->cart
is not necessary, as$cart
is already passed to the callback function - Use
has_term()
versuswc_get_product_category_list()
andstrstr()
So you get:
function action_woocommerce_cart_calculate_fees( $cart ) {
if ( is_admin() && ! defined( 'DOING_AJAX' ) )
return;
// Specific categories: the term name/term_id/slug. Several could be added, separated by a comma
$categories = array( 'org-prod', 'categorie-1', 83 );
// Initialize
$total_act_fee = 0;
$amount = 15;
// Gets cart contents
foreach ( $cart->get_cart_contents() as $cart_item ) {
// Has certain category
if ( has_term( $categories, 'product_cat', $cart_item['product_id'] ) ) {
// Get quantity
$quantity = $cart_item['quantity'];
// Addition to the total
$total_act_fee += $amount * $quantity;
}
}
// Greater than
if ( $total_act_fee > 0 ) {
// Add fee
$cart->add_fee( __( 'Shipping Fees', 'woocommerce' ), $total_act_fee, true );
}
}
add_action( 'woocommerce_cart_calculate_fees', 'action_woocommerce_cart_calculate_fees', 10, 1 );
How to add additional fees to different products in WooCommerce cart
There are several ways. For example, you could indeed add a custom field to the admin product settings.
But it doesn't have to be complicated, installing an extra plugin for this is way too far-fetched!
Adding the same code several times is also a bad idea, because that way you will go through the cart several times. Which would not only slows down your website but will also eventually cause errors.
Adding an array where you would not only determine the product ID but also immediately determine an additional fee based on the array key seems to me to be the most simple and effective way.
So you get:
function action_woocommerce_cart_calculate_fees( $cart ) {
if ( is_admin() && ! defined( 'DOING_AJAX' ) )
return;
// Add in the following way: Additional fee => Product ID
$settings = array(
10 => 1234,
20 => 5678,
5 => 30,
2 => 815,
);
// Initialize
$additional_fee = 0;
// Loop through cart contents
foreach ( $cart->get_cart_contents() as $cart_item ) {
// Get product id
$product_id = $cart_item['product_id'];
// In array, get the key as well
if ( false !== $key = array_search( $product_id, $settings ) ) {
$additional_fee += $key;
}
}
// If greater than 0, so a matching product ID was found in the cart
if ( $additional_fee > 0 ) {
// Add additional fee (total)
$cart->add_fee( __( 'Additional fee', 'woocommerce' ), $additional_fee, false );
}
}
add_action( 'woocommerce_cart_calculate_fees', 'action_woocommerce_cart_calculate_fees', 10, 1 );
Optional:
To display the addition per fee separately, so that the customer knows which fee refers to which product, you can use a multidimensional array.
Add the necessary information to the settings array, everything else happens automatically.
So you get:
function action_woocommerce_cart_calculate_fees( $cart ) {
if ( is_admin() && ! defined( 'DOING_AJAX' ) )
return;
// Settings
$settings = array(
array(
'product_id' => 30,
'amount' => 5,
'name' => __( 'Additional service fee', 'woocommerce' ),
),
array(
'product_id' => 813,
'amount' => 10,
'name' => __( 'Packing fee', 'woocommerce' ),
),
array(
'product_id' => 815,
'amount' => 15,
'name' => __( 'Another fee', 'woocommerce' ),
),
);
// Loop through cart contents
foreach ( $cart->get_cart_contents() as $cart_item ) {
// Get product id
$product_id = $cart_item['product_id'];
// Loop trough settings array
foreach ( $settings as $setting ) {
// Search for the product ID
if ( $setting['product_id'] == $product_id ) {
// Add fee
$cart->add_fee( $setting['name'], $setting['amount'], false );
}
}
}
}
add_action( 'woocommerce_cart_calculate_fees', 'action_woocommerce_cart_calculate_fees', 10, 1 );
Related: How to sum the additional fees of added product ID's in WooCommerce cart
Add fee for certain products in WooCommerce cart
Your code contains some mistakes
- No need to use
WC()->cart
,$cart
is passed to the function $quantiy
is overwritten on each loop- Same for adding the fee, this is overwritten on each loop
So you get:
function action_woocommerce_cart_calculate_fees( $cart ) {
if ( is_admin() && ! defined( 'DOING_AJAX' ) ) return;
// Initialize
$quantity = 0;
// Loop though each cart item
foreach ( $cart->get_cart() as $cart_item ) {
// Compare
if ( in_array( $cart_item['product_id'], statiegeld_ids() ) ) {
// Addition
// Get product quantity in cart
$quantity += $cart_item['quantity'];
}
}
// Greater than
if ( $quantity > 0 ) {
// Add fee
$cart->add_fee( __( 'Statiegeld Petfles 24', 'woocommerce' ), 3.60 * $quantity );
}
}
add_action( 'woocommerce_cart_calculate_fees', 'action_woocommerce_cart_calculate_fees', 10, 1 );
// Specify the product IDs
function statiegeld_ids() {
return array( 4535, 4537, 89694, 89706, 3223, 4742, 14846, 26972, 32925, 32927, 32929, 37475 );
}
Apply fee based on product category and product length in WooCommerce
Your code contains some mistakes or can be optimized:
- The use of global
$woocommerce;
is not necessary get_the_terms()
is replaced byhas_term()
- In your 2nd code attempt you are using 4
foreach
loops while 1 should suffice - You can apply the if/else condition in the loop, so you don't have to go through everything twice
So you get:
function action_woocommerce_cart_calculate_fees( $cart ) {
if ( is_admin() && ! defined( 'DOING_AJAX' ) )
return;
// Specific categories: the term name/term_id/slug. Several could be added, separated by a comma
$categories = array( 83, 'categorie-1' );
// Settings
$cut_price = 30;
$length = 30;
// Initialize
$cp_fee = 0;
// Gets cart contents
foreach ( $cart->get_cart_contents() as $cart_item ) {
// Has certain category
if ( has_term( $categories, 'product_cat', $cart_item['product_id'] ) ) {
// Get length
$product_length = $cart_item['data']->get_length();
// NOT empty and less than
if ( ! empty ( $product_length ) && $product_length < $length ) {
// Get quantity
$quantity = $cart_item['quantity'];
// Addition to the total
$cp_fee += $cut_price * $quantity;
}
}
}
// Greater than
if ( $cp_fee > 0 ) {
// Add fee
$cart->add_fee( __( 'Cut Price', 'woocommerce' ), $cp_fee, true );
}
}
add_action( 'woocommerce_cart_calculate_fees', 'action_woocommerce_cart_calculate_fees', 10, 1 );
Note: if the product quantity per product should not be taken into account
Replace:
// NOT empty and less than
if ( ! empty ( $product_length ) && $product_length < $length ) {
// Get quantity
$quantity = $cart_item['quantity'];
// Addition to the total
$cp_fee += $cut_price * $quantity;
}
With:
// NOT empty and less than
if ( ! empty ( $product_length ) && $product_length < $length ) {
// Addition to the total
$cp_fee += $cut_price;
}
How to sum the additional fees of added product ID's in WooCommerce cart
The __() WordPress function retrieve the translation and therefore has nothing to do with adding multiple productIDs. Instead, you can add multiple product IDs as an array.
Note: The total_amount
setting serves as a counter to keep track of the total amount and should therefore not be changed!
Note: I've added extra code that also takes product quantity into account. If not applicable. Just delete $quantity = $cart_item['quantity'];
and change $setting['amount'] * $quantity;
to $setting['amount'];
So you get:
function action_woocommerce_cart_calculate_fees( $cart ) {
if ( is_admin() && ! defined( 'DOING_AJAX' ) )
return;
// Settings (multiple settings arrays can be added/removed if desired)
$settings = array(
array(
'product_id' => array( 30, 813, 815 ),
'amount' => 5,
'name' => __( 'Additional service fee', 'woocommerce' ),
'total_amount' => 0,
),
array(
'product_id' => array( 817, 819, 820 ),
'amount' => 25,
'name' => __( 'Packing fee', 'woocommerce' ),
'total_amount' => 0,
),
array(
'product_id' => array( 825 ),
'amount' => 100,
'name' => __( 'Another fee', 'woocommerce' ),
'total_amount' => 0,
),
);
// Loop through cart contents
foreach ( $cart->get_cart_contents() as $cart_item ) {
// Get product id
$product_id = $cart_item['product_id'];
// Get quantity
$quantity = $cart_item['quantity'];
// Loop trough settings array (determine total amount)
foreach ( $settings as $key => $setting ) {
// Search for the product ID
if ( in_array( $product_id, $settings[$key]['product_id'] ) ) {
// Addition
$settings[$key]['total_amount'] += $setting['amount'] * $quantity;
}
}
}
// Loop trough settings array (output)
foreach ( $settings as $setting ) {
// Greater than 0
if ( $setting['total_amount'] > 0 ) {
// Add fee
$cart->add_fee( $setting['name'], $setting['total_amount'], false );
}
}
}
add_action( 'woocommerce_cart_calculate_fees', 'action_woocommerce_cart_calculate_fees', 10, 1 );
Add the values of product meta as fee in WooCommerce cart
The cart can contain multiple products, so global $product
is not applicable here.
Instead, you can go through the cart and for each product for which the meta exists, add the value for this to the fee.
If the $fee is greater than 0, you can then apply it.
So you get:
function action_woocommerce_cart_calculate_fees( $cart ) {
if ( is_admin() && ! defined( 'DOING_AJAX' ) )
return;
// Initialize
$fee = 0;
// Loop through cart contents
foreach ( $cart->get_cart_contents() as $cart_item ) {
// Get meta
$ecofee = $cart_item['data']->get_meta( 'meta_product_grossecofee', true );
// NOT empty & variable is a number
if ( ! empty ( $ecofee ) && is_numeric( $ecofee ) ) {
// Addition
$fee += $ecofee;
}
}
// If greater than 0
if ( $fee > 0 ) {
// Add additional fee (total)
$cart->add_fee( __( 'Ecofee', 'woocommerce' ), $fee, false );
}
}
add_action( 'woocommerce_cart_calculate_fees', 'action_woocommerce_cart_calculate_fees', 10, 1 );
Note: if you want to take into account the quantity per product:
Replace
// NOT empty & variable is a number
if ( ! empty ( $ecofee ) && is_numeric( $ecofee ) ) {
// Addition
$fee += $ecofee;
}
With
// NOT empty & variable is a number
if ( ! empty ( $ecofee ) && is_numeric( $ecofee ) ) {
// Get product quantity in cart
$quantity = $cart_item['quantity'];
// Addition
$fee += $ecofee * $quantity;
}
Extra cost for each category in woocommerce
Add Extra Price dynamically from categories meta
Steps:
- Add extra price input fields on product category add / edit
- Save product category extra price input fields
- Optional - Show/List extra price column on the category listing(table)
- Finally - Add category extra price into categories products( assign product)
Code:
/**
* Step 1: Create an extra price column on add/edit/list categories page
*
*/
/* =========1(a). Product Create Category page ============== */
function woo_taxonomy_add_extra_price_meta_field() {
?>
<div class="form-field">
<label for="extra_price"><?php __('Extra Product Price', 'woocommerece'); ?></label>
<input type="number" name="extra_price" id="extra_price" maxlength="4" value="0" />
<p class="description"><?php _e('Add extra cost to the product price', 'woocommerece'); ?></p>
</div>
<?php
}
/* =========1(b). Product Edit Category page ============== */
function woo_taxonomy_edit_extra_price_meta_field($term) {
$term_id = $term->term_id;
$extra_price = get_term_meta($term_id, 'extra_price', true);
?>
<tr class="form-field">
<th scope="row" valign="top"><label for="extra_price"><?php __('Extra Product Price', 'woocommerece'); ?></label></th>
<td>
<input type="number" name="extra_price" id="extra_price" value="<?php echo esc_attr($extra_price) ? esc_attr($extra_price) : 0; ?>" maxlength="4" />
<p class="description"><?php _e('Add extra cost to the product price', 'woocommerece'); ?></p>
</td>
</tr>
<?php
}
add_action('product_cat_add_form_fields', 'woo_taxonomy_add_extra_price_meta_field', 10, 1);
add_action('product_cat_edit_form_fields', 'woo_taxonomy_edit_extra_price_meta_field', 10, 1);
/* ======== 2. Save extra taxonomy fields callback function. ========= */
function woo_save_taxonomy_extra_price_meta($term_id) {
$extra_price = filter_input(INPUT_POST, 'extra_price');
update_term_meta($term_id, 'extra_price', $extra_price);
}
add_action('edited_product_cat', 'woo_save_taxonomy_extra_price_meta', 10, 1);
add_action('create_product_cat', 'woo_save_taxonomy_extra_price_meta', 10, 1);
/* ========= 3(optional). Displaying Additional Columns on admin screen(category grid) ============== */
add_filter( 'manage_edit-product_cat_columns', 'woo_FieldsListExtraPrice' ); //Register Function
add_action( 'manage_product_cat_custom_column', 'woo_FieldsListExtraPriceDisplay' , 10, 3); //Populating the Columns
/* ========= Extra Price column added to category admin screen. ============== */
function woo_FieldsListExtraPrice( $columns ) {
$columns['extra_price'] = __( 'Extra Product Price', 'woocommerce' );
return $columns;
}
/* ========= Extra Price column value added to product category admin screen. ============== */
function woo_FieldsListExtraPriceDisplay( $columns, $column, $id ) {
if ( 'extra_price' == $column ) {
$columns = esc_html( get_term_meta($id, 'extra_price', true) );
}
return $columns;
}
/**
* Step 4: Add Extra Price in products
*
* @return numaric
*/
add_filter('woocommerce_get_price', 'woocommerce_change_price_by_addition', 10, 2);
function woocommerce_change_price_by_addition($price, $product) {
// Product ID
$product_id = isset($product->id) ? $product->id : 0;
$product_categories_id = isset($product->category_ids) ? $product->category_ids : array();
$extra_amount = 0;
if(!empty($product_categories_id))
{
foreach($product_categories_id as $cat_id)
{
$category_extra_price = (float)get_term_meta($cat_id, 'extra_price', true);
if ($category_extra_price && is_numeric($category_extra_price))
{
$extra_amount = $extra_amount + $category_extra_price;
}
}
}
if ($product_id) {
//get the product
$product = wc_get_product($product_id);
// change the price by adding the 35
$price = ($price + $extra_amount);
//return the new price
return $price;
}
}
Related Topics
Fix iOS Picture Orientation After Upload PHP
Boolean Variables Posted Through Ajax Being Treated as Strings in Server Side
Using Curl in PHP with Client Certificate and Private Key in Separate Files
Subtracting a Certain Number of Hours, Days, Months or Years from Date
Connecting to Websocket with PHP Client
Change Array Key Without Changing Order
Htmlpurifier Iframe Vimeo and Youtube Video
Copy Large Files (Over 2 Gb) in PHP
Partially Hide Email Address in PHP
How to Get Random Image from Directory Using PHP
Mp4 Plays When Accessed Directly, But Not When Read Through PHP, on iOS
How to Remove Null Values from an Array
Apache's Errordocument Directive Does Not Redirect
iOS Push Notification Does Not Work When Using Crontab Scheduler