Duplicate/Copy Order Woocommerce
Asked Answered
E

2

5

Anyone know how i could duplicate/copy an order from woocommmerce and create a new order from the old one?

I am working in a Payment gateway and after a payment has been made in a recurring subscription i will need to duplicate a new order and mark as paid!!!!

Is that possible?

Cheers.

Erdman answered 6/11, 2013 at 6:48 Comment(0)
H
9

When PayPal sends an IPN subscr_payment update to WooCommerce I'm using this code inside the valid_paypal_standard_ipn_request action to create new orders from existing orders. Once in a while the shipping info is empty on the new order. I'm not sure what's causing that, but this is new code so it might be buggy.

All the components of a WooCommerce order are here. I created this from the logic in class-cw-checkout.php create_order, but used an existing order to provide the values.

<?php

add_action( 'valid-paypal-standard-ipn-request', 'sapce_valid_paypal_standard_ipn_request', 10, 1 );

function sapce_valid_paypal_standard_ipn_request($formdata){
    if (!empty($formdata['txn_type'])) {
        if ($formdata['txn_type'] === "subscr_signup") {
            $custom = unserialize(stripslashes($formdata['custom']));
            $order_id = $custom[0];
            $payment_profile_id = $formdata['subscr_id'];
            addPayPalPaymentProfileIdToAutoShipOrder($order_id, $payment_profile_id);
        }

        if ($formdata['txn_type'] === "subscr_payment" && $formdata['payment_status'] === "Completed") {
            $paypal_transaction_id = $formdata['txn_id'];
            $custom = unserialize(stripslashes($formdata['custom']));
            $original_order_id = $custom[0];
            createNewOrderAndRecordPayment($formdata);
        }

        if ($formdata['txn_type'] === "subscr_cancel") {
            customerCanceledAutoShipOrderFromPayPal($order_id, $payment_profile_id);
        }
    }
}
<?php

include_once ('../../../wp-load.php');
include_once ('../../../wp-blog-header.php');


function createNewOrderAndRecordPayment($formdata) {

    global $wpdb;
    global $woocommerce;

    $paypal_transaction_id = $formdata['txn_id'];

    $custom = unserialize(stripslashes($formdata['custom']));
    $original_order_id = $custom[0];
    $original_order = new WC_Order($original_order_id);
    $currentUser = wp_get_current_user();

    writeToLog("Attempting to copy original order: $original_order_id");

    //1 Create Order
    $order_data =  array(
        'post_type'     => 'shop_order',
        'post_title'    => sprintf( __( 'Auto-Ship Order &ndash; %s', 'woocommerce' ), strftime( _x( '%b %d, %Y @ %I:%M %p', 'Order date parsed by strftime', 'woocommerce' ) ) ),
        'post_status'   => 'publish',
        'ping_status'   => 'closed',
        'post_excerpt'  => 'Auto-Ship Order based on original order ' . $original_order_id,
        'post_author'   => $currentUser->ID,
        'post_password' => uniqid( 'order_' )   // Protects the post just in case
    );

    $order_id = wp_insert_post( $order_data, true );

    if ( is_wp_error( $order_id ) ){
        $msg = "Unable to create order:" . $order_id->get_error_message();;
        throw new Exception( $msg );
    } else {

        $order = new WC_Order($order_id);

        //2 Update Order Header

        update_post_meta( $order_id, '_order_shipping',         get_post_meta($original_order_id, '_order_shipping', true) );
        update_post_meta( $order_id, '_order_discount',         get_post_meta($original_order_id, '_order_discount', true) );
        update_post_meta( $order_id, '_cart_discount',          get_post_meta($original_order_id, '_cart_discount', true) );
        update_post_meta( $order_id, '_order_tax',              get_post_meta($original_order_id, '_order_tax', true) );
        update_post_meta( $order_id, '_order_shipping_tax',     get_post_meta($original_order_id, '_order_shipping_tax', true) );
        update_post_meta( $order_id, '_order_total',            get_post_meta($original_order_id, '_order_total', true) );

        update_post_meta( $order_id, '_order_key',              'wc_' . apply_filters('woocommerce_generate_order_key', uniqid('order_') ) );
        update_post_meta( $order_id, '_customer_user',          get_post_meta($original_order_id, '_customer_user', true) );
        update_post_meta( $order_id, '_order_currency',         get_post_meta($original_order_id, '_order_currency', true) );
        update_post_meta( $order_id, '_prices_include_tax',     get_post_meta($original_order_id, '_prices_include_tax', true) );
        update_post_meta( $order_id, '_customer_ip_address',    get_post_meta($original_order_id, '_customer_ip_address', true) );
        update_post_meta( $order_id, '_customer_user_agent',    get_post_meta($original_order_id, '_customer_user_agent', true) );

        writeToLog("Updated order header");

        //3 Add Billing Fields

        update_post_meta( $order_id, '_billing_city',           get_post_meta($original_order_id, '_billing_city', true));
        update_post_meta( $order_id, '_billing_state',          get_post_meta($original_order_id, '_billing_state', true));
        update_post_meta( $order_id, '_billing_postcode',       get_post_meta($original_order_id, '_billing_postcode', true));
        update_post_meta( $order_id, '_billing_email',          get_post_meta($original_order_id, '_billing_email', true));
        update_post_meta( $order_id, '_billing_phone',          get_post_meta($original_order_id, '_billing_phone', true));
        update_post_meta( $order_id, '_billing_address_1',      get_post_meta($original_order_id, '_billing_address_1', true));
        update_post_meta( $order_id, '_billing_address_2',      get_post_meta($original_order_id, '_billing_address_2', true));
        update_post_meta( $order_id, '_billing_country',        get_post_meta($original_order_id, '_billing_country', true));
        update_post_meta( $order_id, '_billing_first_name',     get_post_meta($original_order_id, '_billing_first_name', true));
        update_post_meta( $order_id, '_billing_last_name',      get_post_meta($original_order_id, '_billing_last_name', true));
        update_post_meta( $order_id, '_billing_company',        get_post_meta($original_order_id, '_billing_company', true));

        writeToLog("Updated billing fields");

        //4 Add Shipping Fields

        update_post_meta( $order_id, '_shipping_country',       get_post_meta($original_order_id, '_shipping_country', true));
        update_post_meta( $order_id, '_shipping_first_name',    get_post_meta($original_order_id, '_shipping_first_name', true));
        update_post_meta( $order_id, '_shipping_last_name',     get_post_meta($original_order_id, '_shipping_last_name', true));
        update_post_meta( $order_id, '_shipping_company',       get_post_meta($original_order_id, '_shipping_company', true));
        update_post_meta( $order_id, '_shipping_address_1',     get_post_meta($original_order_id, '_shipping_address_1', true));
        update_post_meta( $order_id, '_shipping_address_2',     get_post_meta($original_order_id, '_shipping_address_2', true));
        update_post_meta( $order_id, '_shipping_city',          get_post_meta($original_order_id, '_shipping_city', true));
        update_post_meta( $order_id, '_shipping_state',         get_post_meta($original_order_id, '_shipping_state', true));
        update_post_meta( $order_id, '_shipping_postcode',      get_post_meta($original_order_id, '_shipping_postcode', true));

        writeToLog("Updated shipping fields");

        //5 Add Line Items

        writeToLog("Adding 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, array(
                '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', $_product->get_tax_class() );
            wc_add_order_item_meta( $item_id, '_product_id', $productID );
            //wc_add_order_item_meta( $item_id, '_variation_id', $values['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( '0' ) );
            wc_add_order_item_meta( $item_id, '_line_subtotal_tax', wc_format_decimal( '0' ) );

        }

        writeToLog("Copying shipping items");

        //6 Copy shipping items and shipping item meta from original order
        $original_order_shipping_items = $original_order->get_items('shipping');
        writeToLog(print_r($original_order_shipping_items));
        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'] ) );
            }

        }

        writeToLog("Copying store coupons");

        // Store 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'
            ) );
            // Add line item meta
            if ( $item_id ) {
                wc_add_order_item_meta( $item_id, 'discount_amount', $original_order_coupon['discount_amount'] );
            }
        }

        writeToLog("Setting payment info");

        //Payment Info
        update_post_meta( $order_id, '_payment_method',         get_post_meta($original_order_id, '_payment_method', true) );
        update_post_meta( $order_id, '_payment_method_title',   get_post_meta($original_order_id, '_payment_method_title', true) );
        update_post_meta( $order->id, 'Transaction ID',         get_post_meta($original_order_id, 'Transaction ID', true) );
        $order->payment_complete();

        writeToLog("Setting order to processing");

        //6 Set Order Status to processing to trigger initial emails to end user and vendor
        $updateNote = "This Auto-Ship order was created by SAP Commerce Engine, per PayPal payment installment.";
        $order->update_status('processing');
        $order->add_order_note($updateNote);

        writeToLog("Auto-Ship Order copy complete.");
    }
}
Herbart answered 12/6, 2014 at 18:10 Comment(1)
Just used your code here for order duplication mechanics that I need in my custom code. You have absolutely no idea how much time you've saved me - barely had to change anything in your code. Thanks A LOT!Sakovich
M
0

You can copy all the order meta data first using wc_get_order_item_meta(), like this:

$main_order_metadata = get_metadata( 'post', $main_order_id );

And you can add the copied metadata using add_post_meta()


After that you can copy all item meta keys with wc_get_order_item_meta(), like this:

$order_item_metas = wc_get_order_item_meta( $order_item_id, '' );

And you can add the copied item metas using wc_add_order_item_meta()

Mckeown answered 24/5, 2017 at 19:0 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.