Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Wordpress (Woocommerce extension) - Create new order programmatically

I want to create a new order programmatically.

Workflow is simple: After submitting simple form, user will be created and along with that, a new order.

I managed to create a new user and user_id is returned, now I need to assign a new order all in one step.

How can I accomplish this?

like image 315
Jozko Golonka Avatar asked Jun 18 '13 07:06

Jozko Golonka


People also ask

How do I change the order status in WooCommerce programmatically?

There are a few ways to change the order status in WooCommerce programmatically. The most common way is to use the order statuses API. This API allows you to retrieve the order status for each order in your WooCommerce store. You can also use the order_status() function to change the order status for a specific order.


2 Answers

Here's how I programmatically create my orders. I largely followed WC_Checkout::create_order() from @pavel's suggestion above. This is directly from a plugin I'm writing so you'll have to adjust where the source data comes form.

// build order data
$order_data = array(
    'post_name'     => 'order-' . date_format($order_date, 'M-d-Y-hi-a'), //'order-jun-19-2014-0648-pm'
    'post_type'     => 'shop_order',
    'post_title'    => 'Order – ' . date_format($order_date, 'F d, Y @ h:i A'), //'June 19, 2014 @ 07:19 PM'
    'post_status'   => 'wc-completed',
    'ping_status'   => 'closed',
    'post_excerpt'  => $order->note,
    'post_author'   => $account->user_id,
    'post_password' => uniqid( 'order_' ),   // Protects the post just in case
    'post_date'     => date_format($order_date, 'Y-m-d H:i:s e'), //'order-jun-19-2014-0648-pm'
    'comment_status' => 'open'
);

// create order
$order_id = wp_insert_post( $order_data, true );

if ( is_wp_error( $order_id ) ) {

    $order->errors = $order_id;

} else {

    $order->imported = true;

    // add a bunch of meta data
    add_post_meta($order_id, 'transaction_id', $order->transaction_id, true); 
    add_post_meta($order_id, '_payment_method_title', 'Import', true);
    add_post_meta($order_id, '_order_total', $order->gross, true);
    add_post_meta($order_id, '_customer_user', $account->user_id, true);
    add_post_meta($order_id, '_completed_date', date_format( $order_date, 'Y-m-d H:i:s e'), true);
    add_post_meta($order_id, '_order_currency', $order->currency, true);
    add_post_meta($order_id, '_paid_date', date_format( $order_date, 'Y-m-d H:i:s e'), true);

    // billing info
    add_post_meta($order_id, '_billing_address_1', $order->address_line_1, true);
    add_post_meta($order_id, '_billing_address_2', $order->address_line_2, true);
    add_post_meta($order_id, '_billing_city', $order->city, true);
    add_post_meta($order_id, '_billing_state', $order->state, true);
    add_post_meta($order_id, '_billing_postcode', $order->zip, true);
    add_post_meta($order_id, '_billing_country', $order->country, true);
    add_post_meta($order_id, '_billing_email', $order->from_email, true);
    add_post_meta($order_id, '_billing_first_name', $order->first_name, true);
    add_post_meta($order_id, '_billing_last_name', $order->last_name, true);
    add_post_meta($order_id, '_billing_phone', $order->phone, true);

    // get product by item_id
    $product = get_product_by_sku( $order->item_id );

    if( $product ) {

        // add item
        $item_id = wc_add_order_item( $order_id, array(
            'order_item_name'       => $product->get_title(),
            'order_item_type'       => 'line_item'
        ) );

        if ( $item_id ) {

            // add item meta data
            wc_add_order_item_meta( $item_id, '_qty', 1 ); 
            wc_add_order_item_meta( $item_id, '_tax_class', $product->get_tax_class() );
            wc_add_order_item_meta( $item_id, '_product_id', $product->ID );
            wc_add_order_item_meta( $item_id, '_variation_id', '' );
            wc_add_order_item_meta( $item_id, '_line_subtotal', wc_format_decimal( $order->gross ) );
            wc_add_order_item_meta( $item_id, '_line_total', wc_format_decimal( $order->gross ) );
            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 ) );

        }

        // set order status as completed
        wp_set_object_terms( $order_id, 'completed', 'shop_order_status' );

        // if downloadable 
        if( $product->is_downloadable() ) {

            // add downloadable permission for each file
            $download_files = $product->get_files();
            foreach ( $download_files as $download_id => $file ) {
                wc_downloadable_file_permission( $download_id, $product->id, new WC_Order( $order_id ) );
            }

        }

    } else {

        $order->errors = 'Product SKU (' . $order->$item_id . ') not found.';
    }
}


function get_product_by_sku( $sku ) {

    global $wpdb;

    $product_id = $wpdb->get_var( $wpdb->prepare( "SELECT post_id FROM $wpdb->postmeta WHERE meta_key='_sku' AND meta_value='%s' LIMIT 1", $sku ) );

    if ( $product_id ) return new WC_Product( $product_id );

    return null;
}

Order Class

The is the interim class I use to store the orders before importing into WordPress / WooCommerce.

class ImportOrder
{
    // public vars
    public $date;
    public $time;
    public $time_zone;
    public $first_name;
    public $middle_name;
    public $last_name;
    public $type;
    public $status;
    public $currency;
    public $gross;
    public $fee;
    public $net;
    public $note;
    public $to_email;
    public $from_email;
    public $transaction_id;
    public $counterparty_status;
    public $address_status;
    public $item_title;
    public $item_id;
    public $address_line_1;
    public $address_line_2;
    public $city;
    public $state;
    public $zip;
    public $country;
    public $phone;
    public $imported;
    public $errors;
}

Add Order

The data here is imported from a PayPal CSV download of historical transactions. The $row variable represents one row in the CSV. You can adjust this to suit your needs.

function add_import_order( $row ) {

    // create new order
    $order = new ImportOrder();

    // done this before?
    $order->exists = order_exists( $row[PayPalCols::TRANSACTION_ID] );

    // add a bunch of fields
    $order->date = $row[PayPalCols::DATE];
    $order->time = $row[PayPalCols::TIME];
    $order->time_zone = $row[PayPalCols::TIME_ZONE];
    $order->type = $row[PayPalCols::TYPE];
    $order->status = $row[PayPalCols::STATUS];
    $order->currency = $row[PayPalCols::CURRENCY];
    $order->gross = $row[PayPalCols::GROSS];
    $order->fee = $row[PayPalCols::FEE];
    $order->net = $row[PayPalCols::NET];
    $order->note = $row[PayPalCols::NOTE];
    $order->from_email = $row[PayPalCols::FROM_EMAIL];
    $order->to_email = $row[PayPalCols::TO_EMAIL];
    $order->transaction_id = $row[PayPalCols::TRANSACTION_ID];
    $order->counterparty_status = $row[PayPalCols::COUNTERPARTY_STATUS];
    $order->address_status = $row[PayPalCols::ADDRESS_STATUS];
    $order->item_title = $row[PayPalCols::ITEM_TITLE];
    $order->item_id = $row[PayPalCols::ITEM_ID];
    $order->address_line_1 = utf8_encode( $row[PayPalCols::ADDRESS_LINE_1] );
    $order->address_line_2 = utf8_encode( $row[PayPalCols::ADDRESS_LINE_2] );
    $order->city = utf8_encode( $row[PayPalCols::TOWN_CITY] );
    $order->state = utf8_encode( $row[PayPalCols::STATE] );
    $order->zip = utf8_encode( $row[PayPalCols::ZIP] );
    $order->country = utf8_encode( $row[PayPalCols::COUNTRY] );
    $order->phone = utf8_encode( $row[PayPalCols::PHONE] );

    return $order;

}
like image 65
Jibran Avatar answered Oct 16 '22 12:10

Jibran


For creating New order, You will have to create Object of WC_Order, If you working outside WooCommerce or in function.php then, First Define Global $woocommerce variable.

So, There will be just 2 line of Code.

global $woocommerce;

$order = new WC_Order( $order_id );

Hope, It will help You.

like image 45
Denish Avatar answered Oct 16 '22 10:10

Denish