WooCommerce product table backorders: Add to cart and quantity limits
Backorders in a WooCommerce product table follow stricter rules than the product page. A product with tracked stock at 0 that allows backorders shows no Add to cart button, the quantity box stops at the number in stock, and the Stock status column shows the same check mark for On backorder as for In stock. None of this is a setting you missed: the table builds its button and quantity box from the stock quantity. Below is exactly how it decides, and how to sell backordered products from the table without editing plugin files.
How the table decides whether to show Add to cart
For each row the table checks the product, then builds a quantity box and a button in the browser. For simple products and for the variation rows of the variations popup the rules are:
| Product | Button | Largest quantity |
|---|---|---|
| Not purchasable (no price) or Out of stock | No | - |
| Stock not tracked, status In stock or On backorder | Yes | 9999 |
| Stock tracked, quantity above 0 | Yes | The stock quantity, even if backorders are allowed |
| Stock tracked, quantity 0, backorders allowed | No | - |
| Stock tracked, quantity below 0 (after backorders were placed) | Yes, but adding fails | The negative quantity |
The last row explains a confusing message. The quantity box gets the stock number as its maximum, and when a shopper asks for more, the table refuses before contacting the server with Max count of products is: followed by that number, for example -3. Variable and grouped products show a button that opens their popup; it is hidden when the parent product tracks its own stock and that quantity is 0. External products always show their button.
So the table is built for selling what is on the shelf. When backorders are part of your business, change it in one of the ways below.
Without code: stop tracking stock for backordered products
If you do not need WooCommerce to count the stock of a product, open it, go to Inventory, switch off stock tracking (Track stock quantity for this product in current WooCommerce versions) and set the stock status to On backorder. The table then shows the button and allows up to 9999 per click. The price is that WooCommerce no longer counts the stock of that product and does not mark its order items as backordered. When you need both, stock counting and backorders, use the snippet in the next section.
Show Add to cart for products that allow backorders
The snippet replaces the content of the Cart column through the woot_profile_extend filter, only for products and variations that track stock and allow backorders (Allow or Allow, but notify customer). For them it prints the same placeholder the table prints for any simple product, with an empty quantity, so the table's own script builds its usual quantity box, checkbox and button with no stock cap. All other products keep the normal button.
/*
* Products tables: Add to cart for products that track stock and allow
* backorders, also at 0 or negative stock, without a quantity cap.
* Child theme functions.php or a code snippets plugin.
*/
add_filter('woot_profile_extend', function ($fields, $action, $shortcode_args) {
if (!isset($fields['add_to_cart']['action'])) {
return $fields;
}
$original = $fields['add_to_cart']['action'];
$fields['add_to_cart']['action'] = function ($post_id) use ($original) {
$product = wc_get_product($post_id);
if ($product
&& $product->is_type(['simple', 'variation'])
&& $product->is_purchasable()
&& $product->managing_stock()
&& $product->backorders_allowed()) {
// As the table option "After to cart adding":
// 0 stay on the page, 1 redirect to the cart, 2 redirect to the checkout
$redirect = 0;
// The table's own button placeholder; an empty quantity means no cap
return sprintf(
'<span class="woot-button-buy-pack" data-instant-redirect="%d" data-sold-individually="%d" data-about="simple,%d,,%s"></span>',
$redirect,
(int) $product->is_sold_individually(),
$product->get_id(),
esc_attr($product->get_sku())
);
}
return $original($post_id);
};
return $fields;
}, 33, 3);
Notes on this snippet:
- Set
$redirectto the value your table uses in Options → After to cart adding; the snippet cannot read that option for you. - WooCommerce still checks every addition. Products are added through WooCommerce's own add to cart request, so they are accepted only because the product allows backorders. With Allow, but notify customer, the cart and the order mark them as backordered, as on the product page.
- A variable product whose stock is tracked on the parent at 0 still hides its popup button. Track the stock on the variations instead.
- The snippet reuses the table's button markup. Test it after major plugin updates, as you would any customization.
Do not get the same result by editing profiles/woocommerce/views/add_to_cart.php or woocommerce-cart.js in the plugin folder. It works until the next update, which silently restores the original files.
Show "On backorder" in the Stock status column
The Stock status column shows a check mark for both In stock and On backorder, and a cross for Out of stock. To tell shoppers that a product ships later, override the column output with the same filter. The text comes from WooCommerce, so it is already translated into your shop language:
/*
* Products tables: show "On backorder" instead of the check mark
* in the Stock status column. Child theme functions.php or a code snippets plugin.
*/
add_filter('woot_profile_extend', function ($fields, $action, $shortcode_args) {
if (isset($fields['stock_status']['action'])) {
$fields['stock_status']['action'] = function ($post_id) {
$product = wc_get_product($post_id);
$status = $product ? $product->get_stock_status() : 'outofstock';
if ('onbackorder' === $status) {
$labels = wc_get_product_stock_status_options();
return '<span class="woot-stock-backorder">' . esc_html($labels['onbackorder']) . '</span>';
}
if ('instock' === $status) {
return '<span class="woot-html-check"><i class="woot-icon"></i></span>';
}
return '<span class="woot-html-cross"><i class="woot-icon"></i></span>';
};
}
return $fields;
}, 33, 3);
Style the label with the class woot-stock-backorder in the table's Custom CSS tab or your theme, for example in orange.
Backordered products missing from the table
If products on backorder do not appear at all, check the Predefinition tab. Its In stock only switch keeps only products whose stock status is exactly In stock, so it hides backordered products together with sold-out ones (see showing only products in stock). The Stock status switch of the front-end filter works differently: it hides only Out of stock products. To hide only sold-out products in a table without a filter, switch In stock only off and add this:
/*
* Products tables: hide out-of-stock products, keep products on backorder.
* Child theme functions.php or a code snippets plugin.
*/
add_filter('woot_wp_query_args', function ($args, $table_id) {
if (in_array((int) $table_id, [5, 8], true)) { // IDs of your tables
$args['meta_query'][] = [
'key' => '_stock_status',
'value' => 'outofstock',
'compare' => '!=',
];
}
return $args;
}, 10, 2);
Quantity limits: stock, custom maximum and min/max/step plugins
The table's quantity box always starts at 1 and steps by 1. Its maximum is the stock quantity for products with tracked stock and 9999 otherwise; for products sold individually the box is locked at 1. Asking for more than the maximum shows Max count of products is: without adding anything. Raising the maximum above the stock only makes sense for products that allow backorders, which the snippet above already does, because WooCommerce itself refuses quantities above the stock for all others.
To set a lower maximum per click, for example 10, change the boxes after the table has drawn its rows:
/*
* Products tables: at most 10 items per click (or the stock, if lower).
* Site footer: a JavaScript snippet in a code snippets plugin,
* or the footer scripts field of your theme.
*/
document.addEventListener('table23-after-build-rows', function (e) {
var table = e.detail.otable.table;
// wait until the table has created its quantity boxes
setTimeout(function () {
table.querySelectorAll('.woot-add-to-cart-input').forEach(function (input) {
var max = parseInt(input.getAttribute('max'), 10) || 10;
input.setAttribute('max', Math.min(max, 10));
});
}, 0);
});
This limits one click, not the order: a shopper can click again. A real per-order limit belongs in WooCommerce, usually through a quantity rules plugin.
Such plugins set minimum, maximum and step values on WooCommerce's own quantity fields. The table's box does not read those values. If the plugin also checks quantities when a product is added to the cart, through WooCommerce's add to cart validation, a wrong quantity from the table is refused and the table shows its message that the product cannot be added; the box itself still starts at 1 and steps by 1. If you need the plugin's input in the table, show the product's own add to cart form in a custom column, as described in how to add a custom column to the tables.
Checklist
- Backordered products tracked at 0 or below: the
woot_profile_extendsnippet for the Cart column is active, or stock tracking is off for them. $redirectin the snippet matches After to cart adding of your table.- In stock only in Predefinition is off if backordered products must be listed.
- The Stock status column shows On backorder where it applies.
- Tested logged out, after clearing the page cache: the button appears, more than the stock quantity can be added, and with Allow, but notify customer the cart marks the items as backordered.
If a backordered product still cannot be added from the table, ask on the WOOT support forum with its stock settings and the message the table shows.