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
have a look at my solution: creating Woocommerce order with line_item programmatically
Works like a charm and goes to the correct WC class that is used by the new REST API
in woocommerce WC_Checkout class has a "create_order" method. You can clone WC_Checkout class, give it another name, change the code of the method for your purposes and call like
include 'path_to_Cloned_WC_Checkout';
$chk = new Cloned_WC_Checkout();
$chk->create_order();
in form handler
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.
Unfortunately, I don't think there are no easy way to do this I'm afraid.
You need to add the order post using wp_insert_post();
and then add all the meta data using update_post_meta()
. You then need to add the using woocommerce_add_order_item()
and woocommerce_add_order_item_meta()
. Lasty you need to set the order status using wp_set_object_terms()
.
It's quite a lot of steps and pitfalls. You need to check your database carefully and add all the data and meta data you need to process and complete the order.
maybe this way..
function insert_order_to_db($seller,$order_date){
global $wpdb;
$result = $wpdb->query(
"
INSERT INTO `wp_posts`(`ID`, `post_author`, `post_date`, `post_date_gmt`, `post_content`, `post_title`, `post_excerpt`, `post_status`, `comment_status`, `ping_status`, `post_password`, `post_name`, `to_ping`, `pinged`, `post_modified`, `post_modified_gmt`, `post_content_filtered`, `post_parent`, `guid`, `menu_order`, `post_type`, `post_mime_type`, `comment_count`)
VALUES (
17188,
$seller,
'".date_format($order_date, 'Y-m-d H:i:s e')."',
'".date_format($order_date, 'Y-m-d H:i:s e')."',
'no',
'Order –". date_format($order_date, 'F d, Y @ h:i A')."',
'noxp',
'wc-completed',
'open',
'close',
'".uniqid( 'order_' )."',
'order-". date_format($order_date, 'M-d-Y-hi-a')."',
'',
'',
'2017-07-24',
'2017-07-24',
'',
0,
'',
0,
'shop_order',
'',
0)
"
);
$order_id = $wpdb->insert_id;
return $order_id;
}
function proccess_order_meta(){
$date = date_create("2017-07-24");
$order_id = insert_order_to_db(194816,$date);
if( is_wp_error( $order_id ) ){
$order->errors = $order_id;
}
else
{
$order_id = 17188;
add_post_meta($order_id, '_payment_method_title', 'پرداخت آنلاین', true);
add_post_meta($order_id, '_order_total', 30000, true);
add_post_meta($order_id, '_customer_user', 194816, true);
add_post_meta($order_id, '_completed_date', date_format( $date, 'Y-m-d H:i:s e'), true);
add_post_meta($order_id, '_paid_date', date_format( $date, 'Y-m-d H:i:s e'), true);
add_post_meta($order_id, '_billing_email', "mavaezi46@gmail.com", true);
add_post_meta($order_id, '_billing_first_name', "علی", true);
}
}
proccess_order_meta();
There's a much easier way of doing it, using wc_create_order()
. Here's an example, which also adds shipping and product line items. It also creates a Woocommerce subscription, but you can ignore that part for a normal product, the same code will work.
function create_test_sub() {
$email = 'test@test.com';
$start_date = '2015-01-01 00:00:00';
$address = array(
'first_name' => 'Jeremy',
'last_name' => 'Test',
'company' => '',
'email' => $email,
'phone' => '777-777-777-777',
'address_1' => '31 Main Street',
'address_2' => '',
'city' => 'Auckland',
'state' => 'AKL',
'postcode' => '12345',
'country' => 'AU'
);
$default_password = wp_generate_password();
if (!$user = get_user_by('login', $email)) $user = wp_create_user( $email, $default_password, $email );
// I've used one product with multiple variations
$parent_product = wc_get_product(22998);
$args = array(
'attribute_billing-period' => 'Yearly',
'attribute_subscription-type' => 'Both'
);
$product_variation = $parent_product->get_matching_variation($args);
$product = wc_get_product($product_variation);
// Each variation also has its own shipping class
$shipping_class = get_term_by('slug', $product->get_shipping_class(), 'product_shipping_class');
WC()->shipping->load_shipping_methods();
$shipping_methods = WC()->shipping->get_shipping_methods();
// I have some logic for selecting which shipping method to use; your use case will likely be different, so figure out the method you need and store it in $selected_shipping_method
$selected_shipping_method = $shipping_methods['free_shipping'];
$class_cost = $selected_shipping_method->get_option('class_cost_' . $shipping_class->term_id);
$quantity = 1;
// As far as I can see, you need to create the order first, then the sub
$order = wc_create_order(array('customer_id' => $user->id));
$order->add_product( $product, $quantity, $args);
$order->set_address( $address, 'billing' );
$order->set_address( $address, 'shipping' );
$order->add_shipping((object)array (
'id' => $selected_shipping_method->id,
'label' => $selected_shipping_method->title,
'cost' => (float)$class_cost,
'taxes' => array(),
'calc_tax' => 'per_order'
));
$order->calculate_totals();
$order->update_status("completed", 'Imported order', TRUE);
// Order created, now create sub attached to it -- optional if you're not creating a subscription, obvs
// Each variation has a different subscription period
$period = WC_Subscriptions_Product::get_period( $product );
$interval = WC_Subscriptions_Product::get_interval( $product );
$sub = wcs_create_subscription(array('order_id' => $order->id, 'billing_period' => $period, 'billing_interval' => $interval, 'start_date' => $start_date));
$sub->add_product( $product, $quantity, $args);
$sub->set_address( $address, 'billing' );
$sub->set_address( $address, 'shipping' );
$sub->add_shipping((object)array (
'id' => $selected_shipping_method->id,
'label' => $selected_shipping_method->title,
'cost' => (float)$class_cost,
'taxes' => array(),
'calc_tax' => 'per_order'
));
$sub->calculate_totals();
WC_Subscriptions_Manager::activate_subscriptions_for_order($order);
print "<a href='/wp-admin/post.php?post=" . $sub->id . "&action=edit'>Sub created! Click here to edit</a>";
}