Setting a max quantity for a WooCommerce product in the basket

I recently came across a client requirement to only allow up to a maximum number of a specific item in the WooCommerece basket.

This was primarily to prevent a single customer from order the entire stock of a specific item.

The requirements were as follows:

  • Set a max quantity value for a product which is the maximum quantity amount which can be ordered for the product
  • Set validation rules that prevent adding more than the max quantity to the basket
  • Create validation rules that prevent something updating the item with a higher quantity value than the max quantity value when updating an existing item in the basket
  • Show appropriate messages to the user about the rules regarding max number of items allowed.

I therefore went about building a plugin to handle this.

Add max quantity input field under WooCommerce product inventory

WooCommerce has an inventory section in the product data section on the product edit screen.

I used the following code to add a new _max_quantity_in_cart field to that area.

<?php
/**
 * Adds a max quanity field to the inventory section on the post edit screen.
 */
function wcmqic_add_max_quantity_field() {

	
	// Add a custom text field
	woocommerce_wp_text_input(
		[
			'id'          => '_max_quantity_in_cart',
			'label'       => __( 'Maximum Quantity in Basket', 'wc-max-quantity-in-cart' ),
			'description' => __( 'Set the maximum quantity of this product which can be added to the basket in a single transaction.', 'wc-max-quantity-in-cart' ),
			'type'        => 'number',
			'desc_tip'    => true,
			'custom_attributes' => array(
				'min' => '1', // Minimum value is 1
			),
		]
	);
}

add_action( 'woocommerce_product_options_inventory_product_data', 'wcmqic_add_max_quantity_field' );

Save the max quantity value when the product post is saved

The following code then saves the added quantity value when the product post is saved.

<?php
/**
 * Save the max quantity custom field value.
 */
function wcmqic_save_max_quantity_field( $post_id ) {
	
	// get the max quantity value from the posted data.
	$max_quantity = isset( $_POST['_max_quantity_in_cart'] ) ? sanitize_text_field( $_POST['_max_quantity_in_cart'] ) : '';

	// if we have a max quantity value.
	if ( ! empty( $max_quantity ) ) {

		// save the value as post meta data.
		update_post_meta( $post_id, '_max_quantity_in_cart', $max_quantity );

	} else {

		// delete the post meta data if empty.
		delete_post_meta( $post_id, '_max_quantity_in_cart' );
	}
}

// Save the custom field value
add_action( 'woocommerce_process_product_meta', 'wcmqic_save_max_quantity_field' );

I then used the following code to create validation when someone adds the product to their basket. The code checks whether the quantity selected is higher than the max quantity set, and if so, it prevents the item from being added to the basket and shows the user an error message.

Validate when a product is added to the basket, ensuring it is equal or less to the max quantity value

<?php
/**
 * Limits the number of a product that can be added to the cart.
 * When the product has a max quantity.
 */
function wcmqic_limit_product_quantity_in_cart( $passed, $product_id, $quantity ) {
    
	// get the max quantity from the product.
	$max_quantity = get_post_meta( $product_id, '_max_quantity_in_cart', true );

	//if we don't have a max quantity.
	if ( empty( $max_quantity ) ) {
		return $passed;
	}

    // Get the existing quantity of the product in the cart
    $existing_quantity = 0;
    foreach ( WC()->cart->get_cart() as $cart_item ) {
        if ( $cart_item['product_id'] == $product_id ) {
            $existing_quantity = $cart_item['quantity'];
            break;
        }
    }

    // Check if the new quantity exceeds the maximum allowed
    if ( ( $existing_quantity + $quantity ) > $max_quantity ) {
        wc_add_notice(
            sprintf(
                'You can only add up to %d of this product to your cart.',
                $max_quantity
            ),
            'error'
        );
        return false;
    }

    return $passed;
}

add_filter( 'woocommerce_add_to_cart_validation', 'wcmqic_limit_product_quantity_in_cart', 10, 3 );

Finally, the following code does the same thing but this time when a user updates an item in the their current basket.

Validate when the user updates their basket

<?php
/**
 * Limits the number of a product that can be updated in the cart.
 */
function wcmqic_limit_product_quantity_in_cart_update( $passed, $cart_item_key, $values, $quantity ) {

	// get the max quantity from the product.
	$max_quantity = get_post_meta( $values['product_id'], '_max_quantity_in_cart', true );

	//if we don't have a max quantity.
	if ( empty( $max_quantity ) ) {
		return $passed;
	}

    if ( $quantity > $max_quantity ) {
        wc_add_notice(
            sprintf(
                'You can only have a maximum of %d of this product in your basket.',
                $max_quantity
            ),
            'error'
        );
        return false;
    }

    return $passed;
}

add_filter( 'woocommerce_update_cart_validation', 'wcmqic_limit_product_quantity_in_cart_update', 10, 4 );

And there you have it, a plugin that sets a maximum quantity in basket for WooCommerce products.

You can view the entire code on Github.