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?
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;
}
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;
}
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;
}