0

I am using a custom code that shows a notification of the minimum order amount and blocks the checkout button if the amount is less.

/* Minimum Order Notification */
add_action('woocommerce_check_cart_items', 'custom_checkout_min_order_amount');
function custom_checkout_min_order_amount() {
    $minimum_amount = 1000;

    if (WC()->cart && WC()->cart->subtotal < $minimum_amount) {
        wc_add_notice(
            sprintf(
                'The minimum order is %s. Your order is for %s. You need to add more %s',
                wc_price($minimum_amount),
                wc_price(WC()->cart->subtotal),
                wc_price($minimum_amount - (WC()->cart->subtotal))
            ),
            'error'
        );
    }
}
remove_action( 'woocommerce_before_cart', 'woocommerce_output_all_notices', 10 );
add_action( 'woocommerce_cart_totals_after_order_total', 'woocommerce_output_all_notices', 10 );

/* Blocking the checkout button */
add_action( 'woocommerce_proceed_to_checkout', 'disable_checkout_button', 1 );
function disable_checkout_button() { 

    $minimum_amount = 1000;
    $total = WC()->cart->cart_contents_total;
    if( $total < $minimum_amount ){
        remove_action( 'woocommerce_proceed_to_checkout', 'woocommerce_button_proceed_to_checkout', 20 );
        echo '<a style="pointer-events: none !important; background: #fb7df3;" href="#" class="checkout-button button alt wc-forward">Proceed to checkout</a>';
    }  
}

I added this notification to the "Your Order" block. There is a problem when automatically updating the quantity of products in the cart, this notification disappears.

How to make the notification not respond to the cart update or show the notification again after the update. I can't find the right code for this.

5
  • Try to use this action hook when cart is updated 'woocommerce_after_cart_item_quantity_update', add notification with this hook Commented Aug 6 at 14:12
  • 1
    Thats because WooCommerce is using AJAX to update cart totals, and your message doesn't stick around after quantity updates. So you need to rerender your message after each cart update. See this helpful question: How to check if Woocommerce cart page is updated dynamically and show/update notifications. Commented Aug 6 at 14:29
  • @Richard Thank you for comment. I just don't understand how to combine my code with this one. Could you help me with that? Commented Aug 6 at 21:42
  • 2
    just add this add_action('woocommerce_after_cart_item_quantity_update','disable_checkout_button'); Commented Aug 7 at 7:57
  • Snuffy and Mehdi. Thanks for yours comments. But this option is not suitable. @Richard gave the most extended answer to my question. Commented Aug 7 at 22:17

2 Answers 2

2

Since you're displaying the custom notice inside the "Your Order" block using the woocommerce_cart_totals_after_order_total hook, you'll need to make sure it's added back each time the cart updates.

That's because WooCommerce clears notices during AJAX updates, so when you change quantities, add, or remove items, your custom notice disappears unless it's dynamically refreshed.

WooCommerce uses AJAX fragments to update parts of the cart page, so you can hook into that system to keep the notice visible.

1) Add placeholder for the notice

First, add a placeholder for your custom notice, to the "Your Order" block using woocommerce_cart_totals_after_order_total hook. This gives WooCommerce a specific spot to inject/add the notice:

/* Placeholder for custom cart notice */
add_action('woocommerce_cart_totals_after_order_total', 'add_min_order_notice_placeholder');
function add_min_order_notice_placeholder() {
    echo '<div id="custom-min-order-notice"></div>';
}

2) Add the notice via AJAX fragments

Next, hook into woocommerce_add_to_cart_fragments to update the notice dynamically when the cart changes:

/* Hook into WooCommerce's AJAX cart update system */
add_filter('woocommerce_add_to_cart_fragments', 'custom_min_order_notice_fragment');
function custom_min_order_notice_fragment($fragments) {
    $minimum_amount = 1000; // Minimum order amount required
    $subtotal = WC()->cart->subtotal; // Get current cart subtotal (excluding shipping and taxes)

    // Store the notice markup for later use
    ob_start();

    // Display notice if subtotal is below minimum required amount
    if ($subtotal < $minimum_amount) {
        ?>
        <div id="custom-min-order-notice" class="woocommerce-error">
            <?php
            echo sprintf(
                'The minimum order is %s. Your order is for %s. You need to add more %s',
                wc_price($minimum_amount),
                wc_price($subtotal),
                wc_price($minimum_amount - $subtotal)
            );
            ?>
        </div>
        <?php
    }

    // Add the notice to WooCommerce's AJAX fragments
    $fragments['#custom-min-order-notice'] = ob_get_clean();

    // Return the updated fragments to WooCommerce
    return $fragments;
}

3) Block the checkout button

And then your code for blocking the checkout button:

/* Blocking the checkout button */
add_action('woocommerce_proceed_to_checkout', 'disable_checkout_button', 1);
function disable_checkout_button() {
    $minimum_amount = 1000;
    $total = WC()->cart->cart_contents_total;

    if ($total < $minimum_amount) {
        remove_action('woocommerce_proceed_to_checkout', 'woocommerce_button_proceed_to_checkout', 20);
        echo '<a style="pointer-events: none !important; background: #fb7df3;" href="#" class="checkout-button button alt wc-forward">Proceed to checkout</a>';
    }
}

NOTICE!: This solution is designed for WooCommerce's legacy checkout system. The hooks used here (woocommerce_cart_totals_after_order_total, woocommerce_add_to_cart_fragments, etc.) are not supported in the block-based architecture.

Reference:

Sign up to request clarification or add additional context in comments.

Comments

1

The issue occurs because wc_add_notice() creates temporary notices that are cleared during AJAX cart updates. When customers modify cart quantities, WooCommerce performs AJAX operations that wipe these session-based notices, causing your minimum order notification to disappear.

The solution is to use WooCommerce Cart Fragments instead of notices. Cart fragments are specifically designed to persist and update automatically during AJAX cart operations, ensuring your notification always displays with current cart values.

Solution:

/* Add minimum order notification as cart fragment */
add_filter( 'woocommerce_add_to_cart_fragments', 'add_minimum_order_fragment' );
function add_minimum_order_fragment( $fragments ) {
    $minimum_amount = 1000;
    $cart_total = WC()->cart ? WC()->cart->subtotal : 0;

    ob_start();
    echo '<div class="minimum-order-notification">';
    if ($cart_total > 0 && $cart_total < $minimum_amount) {
        $shortage = $minimum_amount - $cart_total;
        echo '<div class="woocommerce-error" role="alert">';
        echo 'The minimum order is ' . wc_price($minimum_amount) . '. Your order is for ' . wc_price($cart_total) . '. You need to add more ' . wc_price($shortage);
        echo '</div>';
    }
    echo '</div>';
    $notification_html = ob_get_clean();

    $fragments['.minimum-order-notification'] = $notification_html;
    return $fragments;
}

/* Add the notification container to cart totals */
add_action( 'woocommerce_cart_totals_after_order_total', 'add_minimum_order_container' );
function add_minimum_order_container() {
    $minimum_amount = 1000;
    $cart_total = WC()->cart ? WC()->cart->subtotal : 0;

    echo '<div class="minimum-order-notification">';
    if ($cart_total > 0 && $cart_total < $minimum_amount) {
        $shortage = $minimum_amount - $cart_total;
        echo '<div class="woocommerce-error" role="alert">';
        echo ' The minimum order is ' . wc_price($minimum_amount) . '. Your order is for ' . wc_price($cart_total) . '. You need to add more ' . wc_price($shortage);
        echo '</div>';
    }
    echo '</div>';
}

/* Blocking the checkout button */
add_action( 'woocommerce_proceed_to_checkout', 'disable_checkout_button', 1 );
function disable_checkout_button() { 
    $minimum_amount = 1000;
    $total = WC()->cart->cart_contents_total;
    if( $total < $minimum_amount ){
        remove_action( 'woocommerce_proceed_to_checkout', 'woocommerce_button_proceed_to_checkout', 20 );
        echo '<a style="pointer-events: none !important; background: #fb7df3;" href="#" class="checkout-button button alt wc-forward">Proceed to checkout</a>';
    }  

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.