Woocommerce Tips

How to Duplicate or Clone an Order in WooCommerce (No Plugin Needed)

By 28 August 2026No Comments8 min read

WooCommerce has no built-in way to duplicate an order. You can duplicate products, pages and posts, but there is no option for orders when a customer wants to repeat a previous purchase or when you need to recreate a phone order. This post covers two ways to do it: a free, HPOS-ready code snippet that adds a Clone button to your orders list, and the customer-facing Order Again button for self-serve reorders.

Why you would duplicate an order

We build and maintain WooCommerce stores for butchers, wholesalers and retailers across Australia, and order cloning is one of the most common requests. The usual reasons:

  • Phone and email orders: a regular customer wants exactly what they ordered last week.
  • Replacement shipments: a parcel went missing and you need an identical order to fulfil, without charging the customer again.
  • Standing wholesale orders: cafes and restaurants that order the same list every Monday.
  • Testing: recreating a problem order on staging to debug shipping, tax or plugin behaviour.
Butcher shop display counter with cuts of meat, the kind of store that takes repeat weekly orders

What should (and should not) be copied

A WooCommerce order is more than a list of products. Before cloning anything, it helps to understand which parts of an order are safe to copy and which parts must never travel to the new order. Tap each part below to see how a safe clone treats it:

Interactive: tap a part of the order

Pick a part aboveThe general rule: copy the order details, never the payment details.

Method 1: add a Clone button to the orders list (free snippet)

This snippet adds a Clone action to every row of your WooCommerce orders screen. One click creates a new Pending payment order with the same products, addresses, shipping and fees, then opens it for editing. It uses the modern CRUD API only, so it works with both HPOS (High-Performance Order Storage) and legacy post storage.

/**
 * EUX: add a "Clone" action to the WooCommerce orders list.
 * HPOS compatible. Creates a Pending copy and opens it for editing.
 */
add_filter( 'woocommerce_admin_order_actions', function( $actions, $order ) {
    $actions['eux_clone'] = array(
        'url'    => wp_nonce_url(
            admin_url( 'admin-ajax.php?action=eux_clone_order&order_id=' . $order->get_id() ),
            'eux-clone-order'
        ),
        'name'   => __( 'Clone' ),
        'action' => 'eux_clone',
    );
    return $actions;
}, 10, 2 );

add_action( 'wp_ajax_eux_clone_order', function() {
    check_admin_referer( 'eux-clone-order' );

    if ( ! current_user_can( 'edit_shop_orders' ) ) {
        wp_die( 'You are not allowed to clone orders.' );
    }

    $source = wc_get_order( absint( $_GET['order_id'] ?? 0 ) );
    if ( ! $source ) {
        wp_die( 'Order not found.' );
    }

    $clone = wc_create_order( array(
        'customer_id' => $source->get_customer_id(),
        'created_via' => 'clone',
    ) );

    // Addresses.
    $clone->set_address( $source->get_address( 'billing' ), 'billing' );
    $clone->set_address( $source->get_address( 'shipping' ), 'shipping' );

    // Line items (re-added at current catalog prices).
    foreach ( $source->get_items() as $item ) {
        $product = $item->get_product();
        if ( $product ) {
            $clone->add_product( $product, $item->get_quantity() );
        }
    }

    // Shipping lines.
    foreach ( $source->get_items( 'shipping' ) as $ship ) {
        $new_ship = new WC_Order_Item_Shipping();
        $new_ship->set_method_title( $ship->get_method_title() );
        $new_ship->set_method_id( $ship->get_method_id() );
        $new_ship->set_total( $ship->get_total() );
        $clone->add_item( $new_ship );
    }

    // Fees.
    foreach ( $source->get_items( 'fee' ) as $fee ) {
        $new_fee = new WC_Order_Item_Fee();
        $new_fee->set_name( $fee->get_name() );
        $new_fee->set_total( $fee->get_total() );
        $clone->add_item( $new_fee );
    }

    $clone->set_customer_note( $source->get_customer_note() );
    $clone->calculate_totals();
    $clone->update_status(
        'pending',
        sprintf( 'Cloned from order #%s.', $source->get_order_number() )
    );

    wp_safe_redirect( $clone->get_edit_order_url() );
    exit;
} );

Where to put it

Add the snippet to your child theme’s functions.php, or better, a small site-specific plugin so it survives theme updates. If you paste it into a file that already opens with <?php, paste it exactly as shown, without a second opening tag.

See the flow in action

Here is exactly what happens behind that one click. Press Clone on the demo order below:

Interactive: a one-click clone, step by step

OrderCustomerTotalStatus
#1042R. Latham$186.50Completed
  1. Create a new empty order for the same customer
  2. Copy billing and shipping addresses
  3. Re-add 3 line items at current prices
  4. Copy shipping method and fees, recalculate totals
  5. Set status to Pending payment and log “Cloned from #1042”

The clone lands on the order edit screen as Pending payment, so nothing is charged and no emails go out until you decide what to do next: take payment over the phone, send the customer a payment link, or mark it paid manually for a replacement shipment.

Method 2: let customers reorder themselves

If the goal is repeat purchases rather than admin copies, you do not need to clone anything. WooCommerce ships with an Order Again button that refills the cart from a previous order, and we covered how to surface it properly in our earlier post: add an “Order Again” button to the My Account orders list. The short version:

// Show "Order Again" for completed orders in My Account > Orders.
add_filter( 'woocommerce_my_account_my_orders_actions', function( $actions, $order ) {
    if ( $order->has_status( 'completed' ) ) {
        $actions['order-again'] = array(
            'url'  => wp_nonce_url(
                add_query_arg( 'order_again', $order->get_id(), wc_get_cart_url() ),
                'woocommerce-order_again'
            ),
            'name' => __( 'Order again', 'woocommerce' ),
        );
    }
    return $actions;
}, 10, 2 );

The difference matters: Order Again builds a fresh cart and the customer pays at checkout as normal. The Clone snippet builds a back-office order with no payment attached. Use the right tool for each situation.

Customer holding a credit card while paying for an online order

Gotchas we hit in production

Prices are re-read from the catalog

add_product() uses the product’s current price. If the original order was placed during a sale, the clone will total differently. For a replacement shipment where the totals must match to the cent, edit the line item prices on the clone before saving.

Stock is not reserved until you act

A Pending order created by the snippet does not reduce stock. Stock reduces when the order moves to Processing (or when you trigger it manually), so clones do not affect your inventory until you process them.

Deleted products are skipped

If a product on the original order has since been deleted, the snippet skips it rather than crashing. It is worth comparing item counts after cloning an old order.

Coupons need a decision

We deliberately do not copy coupon lines. A coupon from the original order may be expired or single-use. It is safer to re-apply coupons on the clone manually.

FAQ

Does cloning an order charge the customer again?

No. The clone is created as Pending payment with no payment method attached. Nothing is charged unless you take payment on the new order.

Does this work with HPOS?

Yes. The snippet only uses the WooCommerce CRUD API (wc_get_order, wc_create_order, order item objects), so it behaves identically on HPOS and legacy post-based storage.

Can it copy subscription orders?

It will copy the line items, but it will not create a new subscription. Subscriptions carry billing schedules and payment tokens that must never be duplicated this way. If you need subscription tooling, that is a separate piece of work.

Need a custom order workflow?

EUX is a WooCommerce Pro Partner, one of only three in Australia. We build custom order workflows every week: cloning with original pricing, standing wholesale orders, POS-synced ordering and more. If your store needs more than a snippet, talk to us or browse our WooCommerce development services.

Adrian Rodriguez

I use 15+ years of Web Design and Development experience to help eCommerce businesses increase sales and enhance online presence.