Programmatically creating new order in Woocommerce

I am having the hardest time programmatically creating an order in WooCommerce. I am using the code below and is DOES create an order BUT I cannot get customer information OR product line items added to the order. The new order that is create is simply as Guest with no items, user information, etc.

The issue seems to be that once the order object is created, it is failing when trying to add data to the order.

Read More
function create_vip_order() {

  global $woocommerce;

  $address = array(
      'first_name' => '111Joe',
      'last_name'  => 'Conlin',
      'company'    => 'Speed Society',
      'email'      => 'joe@testing.com',
      '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);

}

add_action( 'woocommerce_init', 'create_vip_order' );

Here is the error I am getting in my logs:

[19-Apr-2016 21:16:38 UTC] PHP Fatal error:  Uncaught Error: Call to a member function add_product() on boolean in /Users/joe/Sites/speedsociety-2/wp-content/themes/ss/lib/contests/order.php:107
Stack trace:
#0 /Users/joe/Sites/speedsociety-2/wp-includes/plugin.php(525): create_vip_order('')
#1 /Users/joe/Sites/speedsociety-2/wp-content/plugins/woocommerce/woocommerce.php(330): do_action('woocommerce_ini...')
#2 /Users/joe/Sites/speedsociety-2/wp-includes/plugin.php(525): WooCommerce->init('')
#3 /Users/joe/Sites/speedsociety-2/wp-settings.php(392): do_action('init')
#4 /Users/joe/Sites/speedsociety-2/wp-config.php(67): require_once('/Users/joe/Site...')
#5 /Users/joe/Sites/speedsociety-2/wp-load.php(37): require_once('/Users/joe/Site...')
#6 /Users/joe/Sites/speedsociety-2/wp-admin/admin.php(31): require_once('/Users/joe/Site...')
#7 /Users/joe/Sites/speedsociety-2/wp-admin/edit.php(10): require_once('/Users/joe/Site...')
#8 {main}
  thrown in /Users/joe/Sites/speedsociety-2/wp-content/themes/ss/lib/contests/order.php on line 107

Any help on this would be MOST appreciated!

Related posts

4 comments

  1. 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'      => 'joe@testing.com',
          '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.

  2. 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();
    
  3. I actually couldn’t figure out your problem but providing you another alternative, this might help you.

    I have added products in $woocommerce->cart first and then assign that cart data to new order created like this :

    //For simple product

    $woocommerce->cart->add_to_cart($product_id, $quantity);
    

    //For variable product

        $woocommerce->cart->add_to_cart($product_id, $quantity, $variationID, $attr_array);
    
        $order_data = array(
             'status' => apply_filters('woocommerce_default_order_status', 'processing'),
             'customer_id' => $user_id
        );
        $new_order = wc_create_order($order_data);
        foreach ($woocommerce->cart->get_cart() as $cart_item_key => $values) {
                $item_id = $new_order->add_product(
                        $values['data'], $values['quantity'], array(
                    'variation' => $values['variation'],
                    'totals' => array(
                        'subtotal' => $values['line_subtotal'],
                        'subtotal_tax' => $values['line_subtotal_tax'],
                        'total' => $values['line_total'],
                        'tax' => $values['line_tax'],
                        'tax_data' => $values['line_tax_data'] // Since 2.2
                    )
                        )
                );
            }
        $new_order->set_address($address, 'billing');
        $new_order->set_address($address, 'shipping');
    
  4. you almost had it, add_action( 'woocommerce_init', 'create_vip_order' );
    woocommerce_init is too early, you need to change your hook to at least init,
    your errors

    [19-Apr-2016 21:16:38 UTC] PHP Fatal error:  Uncaught Error: Call to a member function add_product() on boolean in /Users/joe/Sites/speedsociety-2/wp-content/themes/ss/lib/contests/order.php:107
    Stack trace:
    #0 /Users/joe/Sites/speedsociety-2/wp-includes/plugin.php(525): create_vip_order('')
    #1 /Users/joe/Sites/speedsociety-2/wp-content/plugins/woocommerce/woocommerce.php(330): do_action('woocommerce_ini...')
    #2 /Users/joe/Sites/speedsociety-2/wp-includes/plugin.php(525): WooCommerce->init('')
    #3 /Users/joe/Sites/speedsociety-2/wp-settings.php(392): do_action('init')
    #4 /Users/joe/Sites/speedsociety-2/wp-config.php(67): require_once('/Users/joe/Site...')
    #5 /Users/joe/Sites/speedsociety-2/wp-load.php(37): require_once('/Users/joe/Site...')
    #6 /Users/joe/Sites/speedsociety-2/wp-admin/admin.php(31): require_once('/Users/joe/Site...')
    #7 /Users/joe/Sites/speedsociety-2/wp-admin/edit.php(10): require_once('/Users/joe/Site...')
    #8 {main}
      thrown in /Users/joe/Sites/speedsociety-2/wp-content/themes/ss/lib/contests/order.php on line 107
    

    show that it’s happening the $order variable has been returned false and hence you can’t use $order->add_product

    here’s my working code

    function create_vip_order() {
    
      global $woocommerce;
    
      $address = array(
          'first_name' => '111Joe',
          'last_name'  => 'Conlin',
          'company'    => 'Speed Society',
          'email'      => 'joe@testing.com',
          '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( '129' ), 1 ); // This is an existing SIMPLE product
      $order->set_address( $address, 'billing' );
      //
      $order->calculate_totals();
      $order->update_status("Completed", 'Imported order', TRUE);
    
    }
    
    add_action( 'init', 'create_vip_order' );
    

    Good luck and happy coding 😀

Comments are closed.