Add a minimum WooCommerce order amount

How to Restrict Checkout in WooCommerce if Order Amount is Too Low

If you run an online store using WooCommerce, you might want to set a minimum order amount to ensure your sales cover shipping and handling costs or to encourage larger purchases. In this tutorial, you’ll learn exactly how to add a minimum order total in WooCommerce without using a plugin. This step-by-step guide will show you how to restrict checkout, display a custom error message when the cart total is too low, and disable the “Proceed to checkout” button until the minimum order requirement is met.

Define WooCommerce minimum order amount - cart page
Define WooCommerce minimum order amount – cart page

A client had Carding attacks on his WooCommerce store. The result was very small orders that all end up failed. To stop this carding attack I added a minimum order. This effectively stopped Carding attacks and it also a good way to add a minimum order to a store.

Inspired by Business Bloomer – WooCommerce define a minimum order amount.
I then worked with ChatGPT on a new code. This WooCommerce code snippet accomplishes several things:

  • It checks the cart subtotal (excluding shipping and fees) to see if it meets the minimum order amount you set.
  • If the subtotal is too low, it displays a clear error notice on the cart page so customers understand why they can’t check out yet.
  • It disables the checkout button to prevent accidental purchases.
  • If someone tries to access the checkout page directly via the menu or URL, the script automatically redirects them back to the cart page with the same error message.

This approach is lightweight, doesn’t require additional plugins, and can easily be adjusted to fit your store’s needs.

The final result of the minimum order subtotal amount code.

Added to a Code snippet plugin.

// Set the minimum order amount (based on subtotal)
function custom_wc_minimum_order_amount() {
    return 30;
}

// Show error notice if subtotal is below minimum
function custom_wc_minimum_order_notice() {
    if ( is_admin() || ! is_cart() || defined( 'DOING_AJAX' ) ) return;

    $minimum = custom_wc_minimum_order_amount();
    $total = WC()->cart->get_subtotal();

    if ( $total > 0 && $total < $minimum ) {
        // Avoid duplicate notices
        $notices = wc_get_notices( 'error' );
        foreach ( $notices as $notice ) {
            if ( isset( $notice['notice'] ) && strpos( $notice['notice'], 'minimum order amount' ) !== false ) {
                return;
            }
        }

        wc_add_notice(
            sprintf(
                'Your current order total is %s — the minimum order amount is %s.',
                wc_price( $total ),
                wc_price( $minimum )
            ),
            'error'
        );
    }
}
add_action( 'woocommerce_cart_loaded_from_session', 'custom_wc_minimum_order_notice' );
add_action( 'woocommerce_before_cart', 'custom_wc_minimum_order_notice', 5 );

// Disable "Proceed to checkout" button if below minimum
function custom_wc_disable_checkout_button_below_minimum() {
    if ( ! is_cart() ) return;

    $minimum = custom_wc_minimum_order_amount();
    $total = WC()->cart->get_subtotal();

    if ( $total > 0 && $total < $minimum ) {
        ?>
        <style>
            .checkout-button {
                pointer-events: none;
                opacity: 0.5;
                cursor: not-allowed !important;
            }
        </style>
        <?php
    }
}
add_action( 'woocommerce_proceed_to_checkout', 'custom_wc_disable_checkout_button_below_minimum', 20 );

// Block checkout access if subtotal is below minimum
function custom_wc_block_checkout_if_below_minimum() {
    if ( is_admin() || ! is_checkout() || defined( 'DOING_AJAX' ) ) return;

    if ( WC()->cart && ! WC()->cart->is_empty() ) {
        $minimum = custom_wc_minimum_order_amount();
        $total = WC()->cart->get_subtotal();

        if ( $total < $minimum ) {
            wc_add_notice(
                sprintf(
                    'Your current order total is %s — the minimum order amount is %s.',
                    wc_price( $total ),
                    wc_price( $minimum )
                ),
                'error'
            );
            wp_safe_redirect( wc_get_cart_url() );
            exit;
        }
    }
}
add_action( 'template_redirect', 'custom_wc_block_checkout_if_below_minimum', 5 ); // Priority 5 = early

CSS code used

.woocommerce-error {
    border: 1px solid #d63638;
    background-color: #fcebea;
    color: #a00e0e;
    border-radius: 4px;
    list-style: none;
}

.woocommerce-error li {
    list-style: none;
	position: relative;
}

.site-main .entry-content ul li, .site-main .entry-content ol li {
    position: relative;
    padding-left: 30px !important;
}

Setting a minimum WooCommerce order amount is a smart way to improve your average order value and reduce unprofitable transactions. By using this simple code snippet, you can customize exactly how the restriction works and ensure your customers are clearly informed.

Additional PHP code snippet adjustments

Different minimums by Product Category

If you only want to enforce the rule on certain categories:

$minimum = 0;
foreach ( WC()->cart->get_cart() as $cart_item ) {
    if ( has_term( 'seafood', 'product_cat', $cart_item['product_id'] ) ) {
        $minimum += $cart_item['line_subtotal'];
    }
}
if ( $minimum < 30 ) {
    // show notice or redirect
}

This way you calculate subtotal only for products in the “seafood” category.

Different Minimum Amounts by User Role

If you want, for example, wholesale customers to have a higher minimum:

$current_user = wp_get_current_user();

if ( in_array('wholesale_customer', (array) $current_user->roles) ) {
    $minimum = 100;
} else {
    $minimum = 30;
}

Put that inside the functions where $minimum is set.

Showing the Error Message on Other Pages

Right now, the error shows only on the cart page and checkout redirect.
If you also want to show it on the mini-cart widget, you could hook into:

add_action( 'woocommerce_before_mini_cart', 'custom_wc_minimum_order_notice' );

Custom Styling

If you’d prefer to have a custom color or icon, just adjust your CSS, e.g.:

.woocommerce-error {
    border: 2px dashed #e67e22;
    background: #fdf2e9;
    color: #a94442;
}

Changing the Error Message Text

Update this part:

sprintf(
    'Your current order total is %s — the minimum order amount is %s.',
    wc_price( $total ),
    wc_price( $minimum )
)

to something friendlier, like:

sprintf(
    'Oops! Your cart total is %s. Please add more products until you reach the minimum of %s.',
    wc_price( $total ),
    wc_price( $minimum )
)

Allowing Checkout But Showing a Warning

If you don’t want to block checkout, just remove the template_redirect part and the CSS that disables the button.
Instead, keep only the notice to inform customers.

Using Taxes Instead of Subtotal

If you prefer to include tax, use this line instead:

$total = WC()->cart->get_displayed_subtotal();

If you found this tutorial helpful, please share it or leave a comment below. For more WooCommerce tips and tutorials, check out other WooCommerce tutorials I have written.

Resources

Inspired by Business Bloomer – WooCommerce define a minimum order amount.
Carding attacks and making sure it does not happen again. (Posted at wp.org support forum for WooCommerce PayPal Payments plugin.)
denialdesign.co.uk/blocking-card-testing-attacks-in-woocommerce/ (A code snippet that might be interesting to test out.)
3-negative-consequences-of-carding-attacks-for-your-ecommerce-business
woocommerce.com/document/how-do-i-prevent-and-respond-to-card-testing-attacks/#how-to-respond

Share the article:

Leave a Reply

Your email address will not be published. Required fields are marked *