How to programatically charge extra fees in WooCommerce
Published:31 December 2022/
in
WooCommerce, WordPress
Tutorials » How to programatically charge extra fees in WooCommerce
In this tutorial we’ll go through a basic example of how to programatically create and charge extra fees in WooCommerce. We will create a basic options page to allow admin users the ability to add extra shipping fees to products based on specific taxonomies. To do this, we will customise the functions.php template file. For real-world use it is recommended that a plugin with separate functions be created.
As this functionality is based off of adding extra shipping fees – we will ensure that custom fees are disregarded if ‘local pickup’ is selected as a shipping option. We will also ensure that custom fees are added to every item assigned to the taxonomy term (e.g. if a user adds two products to the cart that have a fee associated, the fee is added twice. The same goes for if it is the same item with more than one quantity).
To follow the steps in this tutorial you’ll need the following:
We first want to register a new ACF Options page. To do this, we just need to add the following code to our themes functions.php file:
// Add ACF options page
if( function_exists('acf_add_options_page') ) {
acf_add_options_page();
}
Next, we need to create our custom fields and display them on the options page we just created. A new field group should be added called ‘Shipping Options’. The location should be set to show the field group if the options page is equal to ‘Options’.
A new repeater type field called ‘Extra Shipping Prices’ should then be added to this new field group, with an alias / field name of ‘shipping_prices’. This repeater should have three sub-fields added – ‘Tag name’, ‘Fee amount’ and ‘Extra charge message’. All fields should be set as mandatory.
Each subfield should have the following attributes set:
Field Label | Alias | Type | Further Info |
---|---|---|---|
Tag name | tag_name | Taxonomy | The taxonomy to be displayed should be set as ‘Tag (product_tag)’, and the return type should be set to ‘Term ID’ |
Fee amount | fee | Number | |
Extra charge message | extra_charge_message | Text Area |
Now we just need to add the new custom function and action into our themes functions.php file. We first need to create our function and its corresponding action:
/******* Calculate custom fees ********/
function action_thewoocommerce_cart_calculate_fees( $cart ) {
if ( is_admin() && ! defined( 'DOING_AJAX' ) )
return;
// Custom code here
}
add_action( 'woocommerce_cart_calculate_fees', 'action_thewoocommerce_cart_calculate_fees', 10, 1 );
Next, we’ll declare $excluded_shipping_method as ‘local_pickup’. We’ll use this variable later on to ensure that fees are only added if they do not include this shipping method. We’ll then use WC sessions to determine the chosen shipping method:
// Shipping
$excluded_shipping_method = 'local_pickup'; // The excluded shipping method
$chosen_shipping_method_id = WC()->session->get( 'chosen_shipping_methods' )[0];
$chosen_shipping_method = explode( ':', $chosen_shipping_method_id )[0];
We now want to initiate a new $settings array, and populate the array with the data from our ‘shipping_prices’ repeater field on our options page:
// Initiate settings array
$settings = array();
// ACF Repeater
if( have_rows('shipping_prices', 'option') ): // Check rows exist
while( have_rows('shipping_prices', 'option') ) : the_row(); // Loop through rows
// Populate settings array
$settings[] = [
'product_id' => array( get_sub_field('tag_name') ),
'amount' => get_sub_field('fee'),
'name' => __( get_sub_field('extra_charge_message'), 'woocommerce' ),
'total_amount' => 0,
];
endwhile;
else :
endif;
Now we want to loop through the cart contents and settings array and set the total amount depending on the term conditions. We’ll then loop through the settings and, if the total amount is greater than 0 and not using the excluded shipping method, we will add the fee to the cart:
// Loop through cart contents
foreach ( $cart->get_cart_contents() as $cart_item ) {
// Get product id and quantity
$product_id = $cart_item['product_id'];
$quantity = $cart_item['quantity'];
// Loop trough settings array
foreach ( $settings as $key => $setting ) {
// Search for the term ID
if (has_term( $settings[$key]['product_id'], 'product_tag', $product_id )) {
// Set total amount
$settings[$key]['total_amount'] += $setting['amount'] * $quantity;
}
}
}
// Loop trough settings array (output)
foreach ( $settings as $setting ) {
// If greater than 0 and not using excluded shipping method
if ( $setting['total_amount'] > 0 && $chosen_shipping_method != $excluded_shipping_method) {
// Add fee
$cart->add_fee( $setting['name'], $setting['total_amount'], false );
}
}
The final custom function should look something like this:
/******* Calculate custom fees ********/
function action_thewoocommerce_cart_calculate_fees( $cart ) {
if ( is_admin() && ! defined( 'DOING_AJAX' ) )
return;
// Shipping
$excluded_shipping_method = 'local_pickup'; // The excluded shipping method
$chosen_shipping_method_id = WC()->session->get( 'chosen_shipping_methods' )[0];
$chosen_shipping_method = explode( ':', $chosen_shipping_method_id )[0];
// Initiate settings array
$settings = array();
// ACF Repeater
if( have_rows('shipping_prices', 'option') ): // Check rows exist
while( have_rows('shipping_prices', 'option') ) : the_row(); // Loop through rows
// Populate settings array
$settings[] = [
'product_id' => array( get_sub_field('tag_name') ),
'amount' => get_sub_field('fee'),
'name' => __( get_sub_field('extra_charge_message'), 'woocommerce' ),
'total_amount' => 0,
];
endwhile;
else :
endif;
// Loop through cart contents
foreach ( $cart->get_cart_contents() as $cart_item ) {
// Get product id and quantity
$product_id = $cart_item['product_id'];
$quantity = $cart_item['quantity'];
// Loop trough settings array
foreach ( $settings as $key => $setting ) {
// Search for the term ID
if (has_term( $settings[$key]['product_id'], 'product_tag', $product_id )) {
// Set total amount
$settings[$key]['total_amount'] += $setting['amount'] * $quantity;
}
}
}
// Loop trough settings array (output)
foreach ( $settings as $setting ) {
// If greater than 0 and not using excluded shipping method
if ( $setting['total_amount'] > 0 && $chosen_shipping_method != $excluded_shipping_method) {
// Add fee
$cart->add_fee( $setting['name'], $setting['total_amount'], false );
}
}
}
add_action( 'woocommerce_cart_calculate_fees', 'action_thewoocommerce_cart_calculate_fees', 10, 1 );
To conclude, this tutorial should have helped you create some extra custom shipping fees based off of taxonomies using WooCommerce, Advanced Custom Fields PRO and some basic theme functions.
Leave a Reply
Want to join the discussion?Feel free to contribute!