Programmatically creating new order in Woocommerce

The problem is in your action hook. Use following hook :

add_action('woocommerce_checkout_process', 'create_vip_order');

function create_vip_order() {

  global $woocommerce;

  $address = array(
      'first_name' => '111Joe',
      'last_name'  => 'Conlin',
      'company'    => 'Speed Society',
      'email'      => '[email protected]',
      'phone'      => '760-555-1212',
      'address_1'  => '123 Main st.',
      'address_2'  => '104',
      'city'       => 'San Diego',
      'state'      => 'Ca',
      'postcode'   => '92121',
      'country'    => 'US'
  );

  // Now we create the order
  $order = wc_create_order();

  // The add_product() function below is located in /plugins/woocommerce/includes/abstracts/abstract_wc_order.php
  $order->add_product( get_product('275962'), 1); // This is an existing SIMPLE product
  $order->set_address( $address, 'billing' );
  //
  $order->calculate_totals();
  $order->update_status("Completed", 'Imported order', TRUE);  
}

Make sure the product id given should exists in the system.


Well you can do this without wc_create_order function.

            $order_data                        = array();
            $order_data[ 'post_type' ]         = 'shop_order';
            $order_data[ 'post_status' ]       = 'wc-' . apply_filters( 'woocommerce_default_order_status', 'pending' );
            $order_data[ 'ping_status' ]       = 'closed';
            $order_data[ 'post_author' ]       = 1;
            $order_data[ 'post_password' ]     = uniqid( 'order_' );
            $order_data[ 'post_title' ]        = sprintf( __( 'Order – %s', 'woocommerce' ), strftime( _x( '%b %d, %Y @ %I:%M %p', 'Order date parsed by strftime', 'woocommerce' ), strtotime( $post_date ) ) );
            $order_data[ 'post_parent' ]       = 12; // parent post id
            $order_data[ 'post_content' ]      = "";
            $order_data[ 'comment_status' ]    = "open";
            $order_data[ 'post_name' ]         = sanitize_title( sprintf( __( 'Order – %s', 'woocommerce' ), strftime( _x( '%b %d, %Y @ %I:%M %p', 'Order date parsed by strftime', 'woocommerce' ), strtotime( $post_date) ) ) );

            $order_id = wp_insert_post( apply_filters( 'woocommerce_new_order_data', $order_data ), true );

Then you can use this $order_id for adding other details, like...

$order = wc_get_order( $order_id );
$product_item_id = $order->add_product( wc_get_product( $product_id ));
wc_add_order_item_meta($product_item_id,"meta_key","meta_values");
$addressShipping = array(
       'first_name' => $shippingName,
       'email'      => $user_email_id,
       'phone'      => $billingPhone,
       'address_1'  => $shippingAddress,
       'address_2'  => $shippingAddress2,
       'city'       => $shippingCity,
       'state'      => $shippingStateCode,
       'postcode'   => $shippingZip,
       'country'    => 'US');
$order->set_address( $addressShipping, 'shipping' );
    $addressBilling = array(
       'first_name' => $billingName,
       'email'      => $user_email_id,
       'phone'      => $billingPhone,
       'address_1'  => $billingAddress,
       'address_2'  => $billingAddress2,
       'city'       => $billingCity,
       'state'      => $billingStateCode,
       'postcode'   => $billingZip,
       'country'    => 'US');
$order->set_address( $addressBilling, 'billing' );
$order->calculate_totals();