Wordpress (Woocommerce extension) - Create new order programmatically
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;}
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.
As of WooCommerce 2.2 (or maybe 2.1 I'm not 100% sure) there is now a function specifically designed for this.
wc_create_order( $args = array() )
with the following default arguments.
$default_args = array( 'status' => '', 'customer_id' => null, 'customer_note' => null, 'order_id' => 0);
You can see the whole function in the includes/wc-core-functions.php
file.