How a reorder works
This walkthrough follows a customer from their order history to a refilled cart, and explains what Reorder does at each step, and what a developer can hook into.
1. Finding the button
Section titled “1. Finding the button”A logged-in customer opens My Account → Orders. Next to each past order whose status you have enabled (Completed by default) sits the Order again button with your chosen label. It is added through WooCommerce’s own woocommerce_my_account_my_orders_actions filter, so it lives in the standard order-actions column, no separate widget, no layout shift. The button appears only on the orders list; there is no separate single-order-view control.
2. One click re-adds the order
Section titled “2. One click re-adds the order”The button is a link back to the orders endpoint carrying the order ID, action=reorder_again and a nonce. The handler runs on template_redirect, before any output, so it can redirect cleanly. It reads the order’s line items and, for each product line, calls WC()->cart->add_to_cart() with the product ID, the ordered quantity (at least 1), the variation ID and the variation attributes. There is no clicking through individual product pages.
3. Unavailable items are skipped with a notice
Section titled “3. Unavailable items are skipped with a notice”A product from an old order may no longer be buyable, deleted, not purchasable, or out of stock. Reorder skips that line (and skips any line add_to_cart itself rejects) and adds everything else. The customer then sees notices summarising the result:
- a success notice with the count of items added back,
- a notice naming the items that were skipped because they are no longer available,
- or, if the order had nothing addable at all, a single notice saying there was nothing to add.
Nothing fails silently and the cart never breaks on a missing product.
4. Variations are preserved
Section titled “4. Variations are preserved”If the original line was a specific variation, a medium black hoodie, say, Reorder re-adds that exact variation. It passes the stored variation ID and reads the line’s pa_ attribute meta (for example pa_size, pa_color) so WooCommerce resolves the right variation. The customer does not have to re-pick size and colour.
5. Landing on the cart or checkout
Section titled “5. Landing on the cart or checkout”Once the items are added, the customer is redirected by wp_safe_redirect per your After reordering setting, to the cart to review and adjust, or straight to checkout for the fastest repeat purchase.
The security model
Section titled “The security model”A customer can only ever reorder their own orders:
- Nonce-protected. Every reorder link carries a per-order nonce (
reorder_again_<id>). An expired or missing nonce produces a friendly “that link has expired” notice and a redirect back to the orders list, no cart change. - Ownership-checked. Before adding anything, the handler confirms the current logged-in user’s ID matches the order’s customer ID. Changing an order ID in the URL does not let anyone reorder someone else’s order (no IDOR); a mismatch returns a “could not find that order” notice.
- Owner-only button. The button is only ever rendered for the customer who owns the order, and only for orders with a qualifying status that contain at least one item.
These checks are always on and have no setting to disable them.
Extending a reorder (developers)
Section titled “Extending a reorder (developers)”After the items are re-added, Reorder fires an action so add-ons can react to a completed reorder:
add_action( 'reorder/refilled', function ( WC_Order $order, int $added, array $skipped ): void { // $order , the order that was reordered // $added , number of line items added back to the cart // $skipped, list of product names that could not be re-added if ( $added > 0 ) { WC()->cart->apply_coupon( 'welcome-back' ); }}, 10, 3 );This is the same hook Reorder Pro uses to apply its reward coupon. Reorder registers no shortcodes, the button appears automatically in the My Account orders actions; there is no [reorder]-style tag to place.
Performance and accessibility
Section titled “Performance and accessibility”The button is server-rendered into the standard order actions, so there is no jQuery and no extra markup. A single stylesheet loads only on the My Account → Orders endpoint (gated by is_account_page() and the orders endpoint check), so the rest of the store loads nothing. The control inherits the theme’s button geometry, shows a visible focus-visible ring, reserves the glyph track to avoid layout shift, supports a dark colour scheme, and confines its one hover animation behind prefers-reduced-motion.