php - Custom AJAX update outside order review table in WooCommerce checkout

Solution:

If you need to add a custom message based on the cart total you can simply work with Javascript (or JQuery).

Using the hook woocommerce_checkout_before_order_review the message will be shown only if, when the page is loaded, the total of the cart is equal to 0.01.

Here you can find the list of WooCommerce Javascript events:

You could then add something like this into your active theme's functions.php file (it's just an idea):

// show or hide a custom message in checkout based on cart total
add_action( 'wp_footer', 'show_hide_message_based_on_cart_total' );
function show_hide_message_based_on_cart_total() {
    ?>
    <script type="text/javascript">
        // the script is triggered every time the checkout updates
        jQuery(document.body).on('updated_checkout', function(){
            // gets the values of the cart total and the discount total by removing the currency symbol and converting the string to a number
            var cartTotal = jQuery('table.shop_table tr.cart-subtotal bdi').text().replace("€","").replace(",",".").trim();
            var coupon = jQuery('table.shop_table tr.cart-discount span.amount').text().replace("€","").replace(",",".").trim();
            if ( cartTotal - coupon == 0.01 ) {
                // show the message
                jQuery('<span id="custom_message">Custom Message</span>').insertBefore('#order_review');
            } else {
                // removes the message
                jQuery('#custom_message').remove();
            } 
        });
    </script>
    <?php
}

Answer

Solution:

The following will show or hide your custom message based on checkout coupon events via Ajax and on cart contents total amount:

add_action( 'woocommerce_checkout_before_order_review', 'action_woocommerce_checkout_before_order_review', 10, 0 );
function action_woocommerce_checkout_before_order_review () {
    // Here below set your message
    $message    = __( 'My message', 'woocommerce' );
    $threshold  = 0.01; // Here your targeted subtotal amount

    $cart_total = WC()->cart->get_cart_contents_total();

    echo '<p class="custom-message" style="'. ( $cart_total > $threshold ? '' : 'display:none;' ) .'">' . $message . '</p>';

    // jQuery Ajax
    wc_enqueue_js( "jQuery( function($){
        if (typeof wc_checkout_params === 'undefined') return false;

        function checkoutCouponEvent() {
            $.ajax({
                type: 'POST',
                url: wc_checkout_params.ajax_url,
                data: {
                    'action': 'checkout_coupon',
                    'ccevent': 'Yes'
                },
                success: function (response) {
                    if ( parseFloat(response) == " . $threshold . " ) {
                        $('.custom-message').show();
                    } else {
                        $('.custom-message').hide();
                    }
                }
            });
        }

        $(document.body).on('applied_coupon_in_checkout removed_coupon_in_checkout', function( event ){
            setTimeout(function(){
                checkoutCouponEvent();
            }, event.type === 'removed_coupon_in_checkout' ? 350 : 0 );
        });
    });" );
}

// Ajax receiver function
add_action( 'wp_ajax_checkout_coupon', 'checkout_coupon_ajax_receiver' );
add_action( 'wp_ajax_nopriv_checkout_coupon', 'checkout_coupon_ajax_receiver' );
function checkout_coupon_ajax_receiver() {
    if ( isset($_POST['ccevent']) && $_POST['ccevent'] ) {
        echo WC()->cart->get_cart_contents_total();
    }
    wp_die();
}

Code goes in functions.php file of the active child theme (or active theme). Tested and works.

Answer

Solution:

The following code solved my issue

function action_woocommerce_checkout_before_order_review () {
  $cart_total = WC()->cart->get_cart_contents_total();
  if ( $cart_total == 0.01 ) {
    echo '<p class="notice">' . __( 'My message', 'woocommerce' ) . '</p>';
  }
  ?>
  
  <script type="text/javascript">
  jQuery('.woocommerce-remove-coupon').click(function(){
    jQuery('.notice').hide();
  });
  </script>
  
  <?php
}
add_action( 'woocommerce_review_order_before_cart_contents', 'action_woocommerce_checkout_before_order_review', 10, 0 );

Source