TUTORIALReorder is one of the few post-purchase features WooCommerce already ships. It is called order_again, it works, and it is hedged about with restrictions that most stores never find out about.
On the My Account orders list, completed orders get an “Order again” button. Clicking it fills the cart with that order’s items and sends the customer to the cart.
The gate is a filter, and its default is a single status:
$statuses_for_reordering = apply_filters(
'woocommerce_valid_order_statuses_for_order_again',
array( 'completed' )
);
There is a second gate that is easier to miss. The handler in WC_Cart_Session requires is_user_logged_in() before it will do anything at all. Guests cannot reorder, even holding a valid link — which matters a lot if a meaningful share of your customers check out as guests.
And a third, in the capability layer: order_again is granted by comparing the current user against the order’s user, so a customer can only reorder their own orders. That one is correct and should stay.
If you mark orders processing and rarely move them to completed, your customers have never seen a reorder button. This is common and easily fixed:
add_filter(
'woocommerce_valid_order_statuses_for_order_again',
function ( $statuses ) {
$statuses[] = 'processing';
return $statuses;
}
);
Unlike widening the cancellation statuses, this one is safe. Reordering creates a new cart; it does not touch the original order, the payment or the stock allocation. The only judgement call is whether “buy this again” makes sense for an order that has not arrived yet — for consumables it often does.
An order is a snapshot of a catalogue that has since moved on. Four things can have changed between then and now, and core handles them in a way that is defensible but thin.
Looking at populate_cart_from_order(), an item is silently skipped when:
$item->get_product() returns nothing, and the loop continues.is_in_stock() is false, and the loop continues.Then, at the end, core counts what it could not add and prints one notice:
2 items from your previous order are currently unavailable and could not be added to your cart.
That is better than silence, and it is not enough. It does not say which two items, and it does not say why — out of stock, discontinued and blocked-by-a-rule are three different problems with three different customer responses.
And there is a fifth change core says nothing about at all: the price. Reorder adds the current product to the cart at the current price. A customer reordering something that has gone up 15% finds out at the cart, having believed they were repeating a known purchase. Nothing warned them.
The fix is a screen between the button and the cart that says what changed, before anything is added.

A useful summary states an outcome per item, in the customer’s language:
Then one button: add what is available. The customer arrives at the cart with no surprises in it, which is the entire objective.
The trust argument is simple. A reorder that quietly drops two of five items is a reorder the customer will check every time from then on — and checking every time is the friction the feature existed to remove.
Core has already decided this for you, and probably not the way you would.
if ( apply_filters( 'woocommerce_empty_cart_when_order_again', true ) ) {
$cart = array();
}
Reorder empties the cart by default. A customer who was mid-shop, clicks “Order again” out of curiosity, and loses everything they had chosen is a customer with a genuine complaint.
You can switch it off:
add_filter( 'woocommerce_empty_cart_when_order_again', '__return_false' );
But blind merging has its own failure: the customer already had two of an item in the cart, reorders an order containing three, and ends up with five without having asked for five.
The honest answer is to ask, but only when it matters. If the cart is empty — which it usually is, because people arrive at their order history from an email — do not ask anything. If the cart has items in it, that is the one moment a prompt is worth the interruption.
Both places, and they are different hooks. On the orders list, through woocommerce_my_account_my_orders_actions. On the single order page, after the items table. The guide to changing that page covers the mechanics.
Label it in the customer’s words. “Order again” is WooCommerce’s phrasing; “Buy these again” tells people it is the items they are getting back, which is the question they were actually asking.
Reorder is the feature most likely to be oversold to you, so here is the plain version.
It works on consumables — coffee, supplements, pet food, filters, printer ink, anything with a natural refill cycle. For those stores the order page is genuinely a sales channel and reorder friction is worth attacking. The case for treating your orders page as a revenue channel is about exactly that kind of store.
It does close to nothing on one-off purchases. If you sell furniture, or jewellery, or a piece of equipment somebody buys once every five years, a Buy Again button will be clicked by approximately nobody. That is not a failure of implementation. Amazon’s Buy Again works because a large share of Amazon’s catalogue is things people rebuy, and your catalogue is probably not.
Build it — the core filter alone is a five-minute change, and the reconciliation screen is an afternoon. Just do not expect it to move revenue unless your products get used up.