It is very common that customers are on the lookout for the choice of shipping and payment methods that aligns with their preferences and requirements. If you are looking for a solution to include additional costs for the shipping & payment method chosen by your customers, then this post will certainly help you.
Although these customizations can be done manually using the WooCommerce settings it has its own limitations.
- Limited flexibility in assigning fees
- Difficulties in managing multiple shipping methods
- Payment gateways with distinct features.
If you want to add flat or percentage-based fees based on payment methods alone, you can check our post on adding fees for different payment methods in WooCommerce.
Where to Add Custom Code in WooCommerce?
It is advisable to add the code snippets to the functions.php file of your child theme. Access the file directly from Appearance->Theme File Editor->Locating the child theme’s functions.php from the right sidebar. You can also access it from your theme’s directory file. Insert the following code snippet in functions.php that will add the checkout fees based on shipping and payment methods. The alternative & easy option is to install the Code Snippets plugin. You can then add the code as a new snippet via the plugin.
Planning to add a LOCAL PICKUP option or let the user choose their delivery date on your WooCommerce store?
Meet Order Delivery Date Pro that lets you set delivery date and time based on product category, shipping methods, pickup methods etc.
Let your customer choose a convenient delivery date and time set by you so that you can handle order fulfillment without any worries. It’s a win-win for both.
Solution: Checkout Fees Based on Shipping Method & Payment Method
The following code snippet allows you to calculate and add custom fees based on the chosen payment method and shipping methods during the WooCommerce checkout process.
add_action( 'woocommerce_cart_calculate_fees', 'ts_add_bacs_fee', 20, 1 ); function ts_add_bacs_fee( $cart ) { if ( is_admin() && ! defined( 'DOING_AJAX' ) ) return; ## ------ Your Settings (below) ------ ## $your_payment_id = 'bacs'; // The payment method $your_shipping_method = 'flat_rate'; // The shipping method $fee_amount = 19; // The fee amount ## ----------------------------------- ## $chosen_payment_method_id = WC()->session->get( 'chosen_payment_method' ); $chosen_shipping_method_id = WC()->session->get( 'chosen_shipping_methods' )[0]; $chosen_shipping_method = explode( ':', $chosen_shipping_method_id )[0]; if ( $chosen_shipping_method == $your_shipping_method && $chosen_payment_method_id == $your_payment_id ) { $fee_text = __( "Additional Fee", "woocommerce" ); $cart->add_fee( $fee_text, $fee_amount, false ); } }
Output
So, when the customer selects the payment method as “Direct bank transfer” (bacs) and the shipping method as “Flat rate” (flat_rate), the code will calculate and display an additional fee of $19 for that combination.
If any other combination of payment method and shipping method is selected, the additional fee will not be assigned.
Related Article: How to Add WooCommerce Checkout Fees Only for Specific Product & Payment Methods
Let us understand the code snippet in detail:
- The add_action() function, hooks the ts_add_bacs_fee function to the woocommerce_cart_calculate_fees action. This means that the ts_add_bacs_fee function will be executed when the fees for the cart are calculated.
- Inside the ts__add_bacs_fee function, there is a conditional check if ( is_admin() && ! defined( ‘DOING_AJAX’ ) ) to ensure that the code is not executed in the admin area or during AJAX requests.
- The variable $your_payment_id represents the chosen payment method ID, which in this example is set to ‘bacs’ (Bank Transfer).
- The variable $your_shipping_method represents the chosen shipping method, here it is set to ‘flat_rate’.
- The variable $fee_amount represents the amount of the additional fee, set to 19.
- Next, the function WC()->session->get(‘choosen_payment_method’ ) retrieves the chosen payment method ID, and WC()->session->get(‘choosen_shipping_methods’) retrieves the chosen shipping method ID from the WooCommerce session.
- $chosen_shipping_method extracts the shipping method slug from the chosen shipping method ID using explode().
- The code then checks if the chosen shipping method matches the specified $your_shipping_method and if the chosen payment method matches the specified $your_payment_id. If both conditions are true, it proceeds to add the additional fee to the cart.
- Inside the conditional block, a fee label is created using the __() function for localization support stored in the variable $fee_text and you can set it as “Additional Fee”.
- Finally, the additional fee is added to the cart using the add_fee() method of the $cart object. The fee label, fee amount, and taxable status (false in this case) are passed as arguments.
Solution: Checkout Fees Based on Shipping Method & Payment Method in WooCommerce Checkout Blocks
The method to add the fees in the checkout block is a bit different than the normal checkout. The checkout blocks will require the Node.js installation. Install the dependencies mentioned in this blog on how to add custom fields in WooCommmerce Checkout blocks. The initial part of this blog explains in detail about how to install the required dependencies for checkout blocks.
Adding fees based on the shipping method and payment method in checkout blocks is achieved by creating a plugin folder with a given structure or adding the same structure to the theme folder. Start with installing the dependencies and once it is done, you will be able to see the node modules installed in the plugins folder.
The first step is to update the cart when the shipping method is changed. We need to make the data available for our extension. To do this, we will be using extensionCartUpdate. This is similar to the update_cart/update_checkout trigger.
In extensionCartUpdate, we need to provide the namespace for our plugin and the data we want to make available to the plugin when the cart is updated. In this case, we need the shipping method and payment method selected on the checkout block.
Create a new JavaScript file in the src folder of your custom plugin folder directory and add the given below code to the js file.
wp.hooks.addAction( 'experimental__woocommerce_blocks-checkout-set-selected-shipping-rate', 'checkout-block-example', function( shipping ) { console.log( document.querySelector('input[name="radio-control-wc-payment-method-options"]:checked').value ); var update_cart = extensionCartUpdate( { namespace: 'checkout-block-example', data: { shipping_method: shipping.shippingRateId, payment_method: document.querySelector('input[name="radio-control-wc-payment-method-options"]:checked').value }, }); } );
The above action is run when the shipping method is changed on the checkout. Here, we are sending the selected shipping method and payment method to add the fees.
As a next step, we will add a function woocommerce_store_api_register_update_callback which defines our namespace and callback function. The data that we sent from extensionCartUpdate will now be available to us in this callback function.
Create a new PHP file in the wp-content/plugins/ directory and the code given below is added to the PHP file.
if ( function_exists( 'woocommerce_store_api_register_update_callback' ) ) { woocommerce_store_api_register_update_callback( array( 'namespace' => 'checkout-block-example', 'callback' => 'update_cart_fees', ) ); } function update_cart_fees( $data ) { if ( isset( $data['shipping_method'] ) ) { WC()->session->set( 'cb_shipping_method', $data['shipping_method'] ); } if ( isset( $data['payment_method'] ) ) { WC()->session->set( 'cb_payment_method', $data['payment_method'] ); } WC()->cart->calculate_totals(); } add_action( 'woocommerce_cart_calculate_fees', 'ts_add_bacs_fee', 20, 1 ); function ts_add_bacs_fee( $cart ) { if ( is_admin() && ! defined( 'DOING_AJAX' ) ) return; ## ------ Your Settings (below) ------ ## $your_payment_id = 'bacs'; // The payment method $your_shipping_method = 'local_pickup'; // The shipping method $fee_amount = 19; // The fee amount ## ----------------------------------- ## $chosen_payment_method_id = WC()->session->get( 'cb_payment_method' ); $chosen_shipping_method_id = WC()->session->get( 'cb_shipping_method' ); $chosen_shipping_method = explode( ':', $chosen_shipping_method_id )[0]; if ( $chosen_shipping_method == $your_shipping_method && $chosen_payment_method_id == $your_payment_id ) { $fee_text = __( "Additional Fee", "woocommerce" ); $cart->add_fee( $fee_text, $fee_amount, false ); } }
We have set the values in the WC session variables which we will then use to add our fees using woocommerce_cart_calculate_fees hook. This will add fees based on the selected shipping method and payment method.
Note: Enqueue the files created in the build folder in the file where you have defined your IntegrationInterface class.
Also, make sure to add the filename in webpack.config.js as given in the image below.
Output
Usecase: Additional fee is added
When the customer selects the specified combination of shipping and payment methods in the code, an additional fee is applied.
Usecase: Additional fee is not added
If the customer selects a combination of shipping and payment methods that isn’t specified in the code, the additional fee won’t be applied.
Conclusion
The above code snippets will allow you to charge additional fees for any WooCommerce shipping method and payment method combination on the WooCommerce checkout page and in checkout blocks as well. It will also work if you have custom shipping methods or payment methods from 3rd party plugins.
Hi Saranya,
In my case additional fee is added on checkout page but on place order it is not adding in order(using woocommerce blocks)
Hi Muhammad,
I have tested the code and it works fine in showing the additional fee even after placing the order (https://prnt.sc/UQ6wIac7vIi6). Please provide additional details for further assistance.
Hi Saranya,
Below is my code for adding custom fee.
add_action( ‘woocommerce_cart_calculate_fees’, ‘ts_add_bacs_fee’, 20, 1 );
function ts_add_bacs_fee( $cart ) {
if ( is_admin() && ! defined( ‘DOING_AJAX’ ) )
return;
$fee_text = __( “Additional Fee”, “woocommerce” );
WC()->cart->add_fee( $fee_text, ‘200’, false );
}
i added this code in my blocks integration file.
fee is added on cart and checkout pages successfully.
Hi Muhammad, I believe that you want to add the fee irrespective of the chosen shipping method and payment method. If that is the case, then the code that you have provided works well directly when implementing the code in the functions.php file. In the other case of trying to implement as mentioned in this post, you need to add your code in the checkout-blocks-initialize.php file(https://prnt.sc/6jLqUHIo3b0Y). The code you provided has been tested in both methods & works well at my end. Please try switching to a default WordPress theme and deactivating other plugins to check if there is a… Read more »
Hi Saranya,
Previously, I encountered issue while incorporating it into the checkout block integration file where the checkout block is registered. However, after moving it to my frontend file, the problem has been resolved and everything is functioning smoothly. I truly appreciate your support throughout this process.
Hi Saranya,
can you get this code working using the Checkout Block?
Hi Larsen, Yes, the code provided will work just fine with the Checkout Block too. The code has been tested from my end and here is the image link for reference: https://prnt.sc/Gyv6kyuVbR5Q
Hi Saranya. But when you change the payment method, do the totals update? When you add a fee just for one payment method, does the fee in the checkout block disappears / appears when changing the selected payment method? Doesn’t work when I test it. Thanks in advance for your reply.
Hi Larsen,
The issues you’re experiencing are due to the differences in how WooCommerce Blocks handles dynamic updates. You may need to add JavaScript to update fees when the payment method changes. We’ve updated the blog to address this issue, and you can find it under the section titled “Solution: Checkout Fees Based on Shipping Method & Payment Method in WooCommerce Checkout Blocks.” If you have questions or need help, please let us know.