class CheckoutTax
{
public function __construct()
{
// add a note after the order details, when a tax is charged and country changes
// the html snippet is shown after the order details on a page refresh
add_action('woocommerce_review_order_before_payment', array($this, 'checkout_note_tax'));
// the action is called when the country changes
// but it does not show the html snippet at the correct place
add_action('woocommerce_cart_calculate_fees', array($this, 'checkout_note_tax'));
// how to combine
// - show HTML snippet after the order details
// - act on a country change
}
/**
* Show checkout note, tax paid
*
* @return void
*/
function checkout_note_tax() {
if (is_admin() && !defined('DOING_AJAX')) return;
if (!is_checkout()) return;
global $WOOCS;
$total_tax = WC()->cart->get_totals()['total_tax'];
$shipping_country = WC()->customer->get_shipping_country();
error_log( $total_tax );
error_log( $shipping_country );
if( $total_tax > 0 && $shipping_country != 'CH') {
?>
<h3>VAT / Custom Duties</h3>
<?php
}
}
}
The hook woocommerce_review_order_before_payment shows the html snippet at the correct page, but only on a page refresh.
The hook woocommerce_cart_calculate_fees triggers changes made to the country field.
How can I combine an action to show a HTML snippet after the order details on the checkout page and update the HTML snippet when the shipping country is changed?
You need something a bit different to get your custom content refreshed on checkout_update
Ajax event. I have replaced woocommerce_review_order_before_payment
hook with a more convenient one.
Now your content is also added to Ajax "order review fragments", so on "Update checkout" event your display gets refreshed dynamically.
Try the following (commented):
class CheckoutTax
{
public function __construct()
{
add_action( 'woocommerce_checkout_order_review', array( $this, 'checkout_display_custom_taxes'), 15 );
add_filter( 'woocommerce_update_order_review_fragments', array( $this, 'update_checkout_custom_fragments') );
}
/**
* Here your HTML content
*
* @return string
*/
public function output() {
$total_tax = WC()->cart->get_totals()['total_tax'];
$shipping_country = WC()->customer->get_shipping_country();
$html = '<div class="woocommerce-checkout-custom-tax">'; // Mandatory wrapper html
if( $total_tax > 0 && $shipping_country !== 'CH') {
$html .= sprintf('<h3>%s</h3>', __('VAT / Custom Duties', 'woocommerce') );
}
return $html . '</div>';
}
/**
* Output html content in checkout page
*
* @return void
*/
public function checkout_display_custom_taxes() {
echo $this->output();
}
/**
* Add the html content to be refreshed on checkout update Ajax event
*
* @return array
*/
public function update_checkout_custom_fragments( $fragments ){
// We add the selector class of our wrapper div as array key
$fragments['.woocommerce-checkout-custom-tax'] = $this->output();
return $fragments;
}
}
For testing purpose in the child theme's functions.php file, I use additionally:
add_action('woocommerce_checkout_init', function(){
$CheckoutTax = new CheckoutTax();
});
Code goes in functions.php file of your child theme (or in a plugin). Tested and works.
Related: