Updated for H.P.O.S. compatibility on July 20th, 2024.
function ccom_duplicate_order( $original_order_id ) {
// Load Original Order
$original_order = wc_get_order( $original_order_id );
$user_id = $original_order->get_user_id();
// Setup Cart
WC()->frontend_includes();
WC()->session = new WC_Session_Handler();
WC()->session->init();
WC()->customer = new WC_Customer( $user_id, true );
WC()->cart = new WC_Cart();
// Setup New Order
$checkout = WC()->checkout();
WC()->cart->calculate_totals();
$order_id = $checkout->create_order( [ ] );
$order = wc_get_order( $order_id );
$order->update_meta_data( '_customer_user', $original_order->get_meta( '_order_shipping' ) );
// Header
$order->update_meta_data( '_order_shipping', $original_order->get_meta( '_order_shipping' ) );
$order->update_meta_data( '_order_discount', $original_order->get_meta( '_order_discount' ) );
$order->update_meta_data( '_cart_discount', $original_order->get_meta( '_cart_discount' ) );
$order->update_meta_data( '_order_tax', $original_order->get_meta( '_order_tax' ) );
$order->update_meta_data( '_order_shipping_tax', $original_order->get_meta( '_order_shipping_tax' ) );
$order->update_meta_data( '_order_total', $original_order->get_meta( '_order_total' ) );
$order->update_meta_data( '_order_key', 'wc_' . apply_filters( 'woocommerce_generate_order_key', uniqid( 'order_' ) ) );
$order->update_meta_data( '_customer_user', $original_order->get_meta( '_customer_user' ) );
$order->update_meta_data( '_order_currency', $original_order->get_meta( '_order_currency' ) );
$order->update_meta_data( '_prices_include_tax', $original_order->get_meta( '_prices_include_tax' ) );
$order->update_meta_data( '_customer_ip_address', $original_order->get_meta( '_customer_ip_address' ) );
$order->update_meta_data( '_customer_user_agent', $original_order->get_meta( '_customer_user_agent' ) );
// Billing
$order->update_meta_data( '_billing_city', $original_order->get_meta( '_billing_city' ) );
$order->update_meta_data( '_billing_state', $original_order->get_meta( '_billing_state' ) );
$order->update_meta_data( '_billing_postcode', $original_order->get_meta( '_billing_postcode' ) );
$order->update_meta_data( '_billing_email', $original_order->get_meta( '_billing_email' ) );
$order->update_meta_data( '_billing_phone', $original_order->get_meta( '_billing_phone' ) );
$order->update_meta_data( '_billing_address_1', $original_order->get_meta( '_billing_address_1' ) );
$order->update_meta_data( '_billing_address_2', $original_order->get_meta( '_billing_address_2' ) );
$order->update_meta_data( '_billing_country', $original_order->get_meta( '_billing_country' ) );
$order->update_meta_data( '_billing_first_name', $original_order->get_meta( '_billing_first_name' ) );
$order->update_meta_data( '_billing_last_name', $original_order->get_meta( '_billing_last_name' ) );
$order->update_meta_data( '_billing_company', $original_order->get_meta( '_billing_company' ) );
// Shipping
$order->update_meta_data( '_shipping_country', $original_order->get_meta( '_shipping_country' ) );
$order->update_meta_data( '_shipping_first_name', $original_order->get_meta( '_shipping_first_name' ) );
$order->update_meta_data( '_shipping_last_name', $original_order->get_meta( '_shipping_last_name' ) );
$order->update_meta_data( '_shipping_company', $original_order->get_meta( '_shipping_company' ) );
$order->update_meta_data( '_shipping_address_1', $original_order->get_meta( '_shipping_address_1' ) );
$order->update_meta_data( '_shipping_address_2', $original_order->get_meta( '_shipping_address_2' ) );
$order->update_meta_data( '_shipping_city', $original_order->get_meta( '_shipping_city' ) );
$order->update_meta_data( '_shipping_state', $original_order->get_meta( '_shipping_state' ) );
$order->update_meta_data( '_shipping_postcode', $original_order->get_meta( '_shipping_postcode' ) );
// Shipping Items
$original_order_shipping_items = $original_order->get_items( 'shipping' );
foreach( $original_order_shipping_items as $original_order_shipping_item ) {
$item_id = wc_add_order_item( $order_id, array(
'order_item_name' => $original_order_shipping_item['name'],
'order_item_type' => 'shipping'
) );
if( $item_id ) {
wc_add_order_item_meta( $item_id, 'method_id', $original_order_shipping_item['method_id'] );
wc_add_order_item_meta( $item_id, 'cost', wc_format_decimal( $original_order_shipping_item['cost'] ) );
}
}
// Coupons
$original_order_coupons = $original_order->get_items( 'coupon' );
foreach( $original_order_coupons as $original_order_coupon ) {
$item_id = wc_add_order_item( $order_id, array(
'order_item_name' => $original_order_coupon['name'],
'order_item_type' => 'coupon'
) );
if ( $item_id ) {
wc_add_order_item_meta( $item_id, 'discount_amount', $original_order_coupon['discount_amount'] );
}
}
// Payment
$order->update_meta_data( '_payment_method', $original_order->get_meta( '_payment_method' ) );
$order->update_meta_data( '_payment_method_title', $original_order->get_meta( '_payment_method_title' ) );
$order->update_meta_data( 'Transaction ID', $original_order->get_meta( 'Transaction ID' ) );
// Line Items
foreach( $original_order->get_items() as $originalOrderItem ) {
$itemName = $originalOrderItem['name'];
$qty = $originalOrderItem['qty'];
$lineTotal = $originalOrderItem['line_total'];
$lineTax = $originalOrderItem['line_tax'];
$productID = $originalOrderItem['product_id'];
$item_id = wc_add_order_item( $order_id, [
'order_item_name' => $itemName,
'order_item_type' => 'line_item'
] );
wc_add_order_item_meta( $item_id, '_qty', $qty );
wc_add_order_item_meta( $item_id, '_tax_class', $originalOrderItem['tax_class'] );
wc_add_order_item_meta( $item_id, '_product_id', $productID );
wc_add_order_item_meta( $item_id, '_variation_id', $originalOrderItem['variation_id'] );
wc_add_order_item_meta( $item_id, '_line_subtotal', wc_format_decimal( $lineTotal ) );
wc_add_order_item_meta( $item_id, '_line_total', wc_format_decimal( $lineTotal ) );
wc_add_order_item_meta( $item_id, '_line_tax', wc_format_decimal( $lineTax ) );
wc_add_order_item_meta( $item_id, '_line_subtotal_tax', wc_format_decimal( $originalOrderItem['line_subtotal_tax'] ) );
}
// Close New Order
$order->save();
$order->calculate_totals();
$order->payment_complete();
$order->update_status( 'processing' );
// Note
$message = sprintf(
'This order was duplicated from order %d.',
$original_order_id
);
$order->add_order_note( $message );
// Return
return $order_id;
}
Here’s an example of using this custom function in a Run Once Code Snippet:
add_action( 'admin_notices', function() {
$original_order_id = 5703489;
$order_id = ccom_duplicate_order( $original_order_id );
wp_admin_notice(
sprintf(
'Successfully copied order %d to order %d',
$original_order_id,
$order_id
),
[ 'type' => 'success' ]
);
} );