Flexibility is one of the main reasons I love WooCommerce. In the previous posts, we learned how to add custom columns to the WooCommerce import/export suite or how to add custom fields to WooCommere webhooks. You can modify and extend almost every part of WooCommerce: even the process of calculating the cart totals.
Recently, I found another interesting question on StackOverflow. Someone asked how to round WooCommerce cart total based on the selected payment method. More specifically, the person wanted to round the cart total if a user chose “Cash on Delivery” as the payment method.
Well, it sounded like a good idea for a new post for me. So let’s see how to achieve this goal.
How to modify the cart total programmatically
Without delving into details, the most important thing you need to know is that the cart total value is modifiable by using the woocommerce_calculated_total filter hook. As the WooCommerde developers write in the comments, this filter allows us to filter the grand total, and sum the cart totals in case of modifications.
For example, if you want to add $100 to the cart total, your code should look like this:
add_filter( 'woocommerce_calculated_total', 'add_hundred_dollars_to_cart_total', 10, 2 );
function add_hundred_dollars_to_cart_total( $total, $cart ) {
return $total + 100;
}
Pretty straightforward as you see. Let’s see how we can use this filter to achieve our goal.
Solution
First of all, we have to make sure that this hook will be triggered when a user chooses the payment method. Some themes recalculate the cart totals after the payment method switch automatically and some do not. This piece of code will guarantee that the checkout will be updated whenever a user changes the payment method:
<?php
add_action('wp_footer', 'trigger_checkout_refresh_on_payment_method_change');
function trigger_checkout_refresh_on_payment_method_change(){
if ( is_checkout() && ! is_wc_endpoint_url() ) :
?>
<script type="text/javascript">
(function($){
$(document.body).on('change', 'input[name="payment_method"]', function(){
$(document.body).trigger('update_checkout').trigger('wc_fragment_refresh');
});
})(jQuery);
</script>
<?php
endif;
}
There are at least a few ways how to round prices in PHP. Which one to choose depends on the logic you want to build. For this tutorial, I’ll go with a simple round() function.
Now, let’s get to our main goal: writing the code snippet that will round the cart total if a user chose “Cash on Delivery” as the payment method.
add_filter( 'woocommerce_calculated_total', 'round_total_for_specific_payment_methods', 10, 2 );
function round_total_for_specific_payment_methods( $total, $cart ) {
$chosen_payment_method = WC()->session->get( 'chosen_payment_method' );
if ( $chosen_payment_method && $chosen_payment_method === 'cod' ) {
$total = round( $total );
}
return $total;
}
Let’s check if the code works as expected.
As you see, when the current payment method is Direct bank transfer, the cart total is 1072,12. I hate coins, so it’s much easier for me to pay the rounded price when I pay for something with cash. So I switch my payment method to Cash on delivery. What do I see?
As you see, I don’t need to lurk through the pockets of all of my jeans and shorts to find these annoying 12 cents. The cart total is 1072,00 – it was rounded after I changed the payment method.
Final code
<?php
add_action('wp_footer', 'trigger_checkout_refresh_on_payment_method_change');
function trigger_checkout_refresh_on_payment_method_change(){
if ( is_checkout() && ! is_wc_endpoint_url() ) :
?>
<script type="text/javascript">
(function($){
$(document.body).on('change', 'input[name="payment_method"]', function(){
$(document.body).trigger('update_checkout').trigger('wc_fragment_refresh');
});
})(jQuery);
</script>
<?php
endif;
}
add_filter( 'woocommerce_calculated_total', 'round_total_for_specific_payment_methods', 10, 2 );
function round_total_for_specific_payment_methods( $total, $cart ) {
$chosen_payment_method = WC()->session->get( 'chosen_payment_method' );
if ( $chosen_payment_method && $chosen_payment_method === 'cod' ) {
$total = round( $total );
}
return $total;
}
Summary
It was a short post, but I hope it’ll be helpful for you. As always, feel free to share your opinion about this post or ask any questions you’ve got in the comments section.
Don’t forget to follow me on LinkedIn if you don’t want to miss new posts on my blog.
Thank you for your attention; see you in the next one!