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?
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.
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;
}
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With