Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Create an order programmatically with line items in Woocommerce 3+

I needed to create a Woocommerce order programatically, however using the 'old' Woocommerce made this a very dirty procedure.

I had to insert all kind of database records manually, using many update_post_meta calls.

Looking for a better solution.

like image 324
Mattijs Avatar asked Oct 27 '14 05:10

Mattijs


People also ask

How do I create a custom order in WooCommerce programmatically?

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.


2 Answers

With latest version of WooCommerce is possible try this as something like

$address = array(             'first_name' => 'Fresher',             'last_name'  => 'StAcK OvErFloW',             'company'    => 'stackoverflow',             'email'      => '[email protected]',             'phone'      => '777-777-777-777',             'address_1'  => '31 Main Street',             'address_2'  => '',              'city'       => 'Chennai',             'state'      => 'TN',             'postcode'   => '12345',             'country'    => 'IN'         );          $order = wc_create_order();         $order->add_product( get_product( '12' ), 2 ); //(get_product with id and next is for quantity)         $order->set_address( $address, 'billing' );         $order->set_address( $address, 'shipping' );         $order->add_coupon('Fresher','10','2'); // accepted param $couponcode, $couponamount,$coupon_tax         $order->calculate_totals(); 

Call this above code with your function then it will work accordingly.

Note it not work with old version of WooCommerce like 2.1.12, It works only from 2.2 of WooCommerce.

Hope it helps

like image 66
Vignesh Pichamani Avatar answered Oct 14 '22 12:10

Vignesh Pichamani


2017-2021 For WooCommerce 3 and Above

Woocommerce 3 has introduced CRUD objects and there is lot of changes on Order items… Also some WC_Order methods are now deprecated like add_coupon().

Here is a function that allow creating programmatically an order nicely with all required data in it, including the taxes:

function create_wc_order( $data ){     $gateways = WC()->payment_gateways->get_available_payment_gateways();     $order    = new WC_Order();      // Set Billing and Shipping adresses     foreach( array('billing_', 'shipping_') as $type ) {         foreach ( $data['address'] as $key => $value ) {             if( $type === 'shipping_' && in_array( $key, array( 'email', 'phone' ) ) )                 continue;              $type_key = $type.$key;              if ( is_callable( array( $order, "set_{$type_key}" ) ) ) {                 $order->{"set_{$type_key}"}( $value );             }         }     }      // Set other details     $order->set_created_via( 'programatically' );     $order->set_customer_id( $data['user_id'] );     $order->set_currency( get_woocommerce_currency() );     $order->set_prices_include_tax( 'yes' === get_option( 'woocommerce_prices_include_tax' ) );     $order->set_customer_note( isset( $data['order_comments'] ) ? $data['order_comments'] : '' );     $order->set_payment_method( isset( $gateways[ $data['payment_method'] ] ) ? $gateways[ $data['payment_method'] ] : $data['payment_method'] );      $calculate_taxes_for = array(         'country'  => $data['address']['country'],         'state'    => $data['address']['state'],         'postcode' => $data['address']['postcode'],         'city'     => $data['address']['city']     );      // Line items     foreach( $data['line_items'] as $line_item ) {         $args = $line_item['args'];         $product = wc_get_product( isset($args['variation_id']) && $args['variation_id'] > 0 ? $$args['variation_id'] : $args['product_id'] );         $item_id = $order->add_product( $product, $line_item['quantity'], $line_item['args'] );          $item    = $order->get_item( $item_id, false );          $item->calculate_taxes($calculate_taxes_for);         $item->save();     }      // Coupon items     if( isset($data['coupon_items'])){         foreach( $data['coupon_items'] as $coupon_item ) {             $order->apply_coupon(sanitize_title($coupon_item['code']));         }     }      // Fee items     if( isset($data['fee_items'])){         foreach( $data['fee_items'] as $fee_item ) {             $item = new WC_Order_Item_Fee();              $item->set_name( $fee_item['name'] );             $item->set_total( $fee_item['total'] );             $tax_class = isset($fee_item['tax_class']) && $fee_item['tax_class'] != 0 ? $fee_item['tax_class'] : 0;             $item->set_tax_class( $tax_class ); // O if not taxable              $item->calculate_taxes($calculate_taxes_for);              $item->save();             $order->add_item( $item );         }     }      // Set calculated totals     $order->calculate_totals();              if( isset($data['order_status']) ) {         // Update order status from pending to your defined status and save data         $order->update_status($data['order_status']['status'], $data['order_status']['note']);         $order_id = $order->get_id();     } else {         // Save order to database (returns the order ID)         $order_id = $order->save();     }          // Returns the order ID     return $order_id; } 

Code goes in function.php file of your active child theme (or active theme) or in a plugin file.


USAGE EXAMPLE from a data array:

create_wc_order( array(     'address' => array(         'first_name' => 'Fresher',         'last_name'  => 'StAcK OvErFloW',         'company'    => 'stackoverflow',         'email'      => '[email protected]',         'phone'      => '777-777-777-777',         'address_1'  => '31 Main Street',         'address_2'  => '',         'city'       => 'Chennai',         'state'      => 'TN',         'postcode'   => '12345',         'country'    => 'IN',     ),     'user_id'        => '',     'order_comments' => '',     'payment_method' => 'bacs',     'order_status'   => array(         'status' => 'on-hold',         'note'   => '',     ),     'line_items' => array(         array(             'quantity' => 1,             'args'     => array(                 'product_id'    => 37,                 'variation_id'  => '',                 'variation'     => array(),             )         ),     ),     'coupon_items' => array(         array(             'code'         => 'summer',         ),     ),     'fee_items' => array(         array(             'name'      => 'Delivery',             'total'     => 5,             'tax_class' => 0, // Not taxable         ),     ), ) ); 
like image 39
LoicTheAztec Avatar answered Oct 14 '22 12:10

LoicTheAztec