Create an Order Programmatically with Line Items in Woocommerce 3+

Create an order programmatically with line items in Woocommerce 3+

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

$address = array(
'first_name' => 'Fresher',
'last_name' => 'StAcK OvErFloW',
'company' => 'stackoverflow',
'email' => 'test@test.com',
'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

Create a Woocommerce order programmatically and apply payment method

Try this

$payment_gateways = WC()->payment_gateways->payment_gateways();
$order->set_payment_method($payment_gateways['stripe']);

This is my working code
Thanks

Add a free product programmatically on WooCommerce specific order status change

There are some mistakes and missing things, Use the following instead:

add_action( 'woocommerce_order_status_changed', 'add_free_product_on_order_enquiry_status', 20, 4 );
function add_free_product_on_order_enquiry_status( $order_id, $old_status, $new_status, $order ){
if ( "enquiry" === $new_status ) {
$product_id = '155185';
$product = wc_get_product( $product_id );
$order->add_product( $product );
$order->calculate_totals(); // calculate taxes, totals and save (method includes save() method)
// $order->save();
}
}

Code goes in functions.php file of the active child theme (or active theme). Tested and works.


Addition 1

You could also flag this action with custom meta data, to avoid adding multiple products if you change order status multiple times with the following:

add_action( 'woocommerce_order_status_changed', 'add_free_product_on_order_enquiry_status', 20, 4 );
function add_free_product_on_order_enquiry_status( $order_id, $old_status, $new_status, $order ){
if ( "enquiry" === $new_status && ! $order->get_meta('_free_product_added') ) {
$product_id = '155185';
$product = wc_get_product( $product_id );
$order->add_product( $product );
$order->update_meta_data('_free_product_added', 'yes'); // Flag the order
$order->calculate_totals(); // calculate taxes, totals and save (method includes save() method)
}
}

Code goes in functions.php file of the active child theme (or active theme). Tested and works.


Addition 2 - Check if the product has been already added to the order (avoiding adding the product multiple times):

function order_has_specific_product( $product_id, $order ) {
// Loop through order items to check if a product is on the current order
foreach ( $order->get_items() as $item ) {
if ( in_array( $product_id, array($item->get_product_id(), $item->get_variation_id()) ) ) {
return true;
}
}
return false;
}

add_action( 'woocommerce_order_status_changed', 'add_free_product_on_order_enquiry_status', 20, 4 );
function add_free_product_on_order_enquiry_status( $order_id, $old_status, $new_status, $order ){
$product_id = '155185'; // Free product to be added only once

if ( "enquiry" === $new_status && ! order_has_specific_product( $product_id, $order ) ) {
$product = wc_get_product( $product_id );
$order->add_product( $product );
$order->calculate_totals(); // calculate taxes, totals and save (method includes save() method)
}
}

Code goes in functions.php file of the active child theme (or active theme). Tested and works.

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' => '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.

Add a shipping to an order programmatically in Woocommerce 3

To handle this in Woocommerce 3+ use the following (from a WC_Order Order object $order):

## ------------- ADD SHIPPING PROCESS ---------------- ##

// Get the customer country code
$country_code = $order->get_shipping_country();

// Set the array for tax calculations
$calculate_tax_for = array(
'country' => $country_code,
'state' => '', // Can be set (optional)
'postcode' => '', // Can be set (optional)
'city' => '', // Can be set (optional)
);

// Optionally, set a total shipping amount
$new_ship_price = 5.10;

// Get a new instance of the WC_Order_Item_Shipping Object
$item = new WC_Order_Item_Shipping();

$item->set_method_title( "Flat rate" );
$item->set_method_id( "flat_rate:14" ); // set an existing Shipping method rate ID
$item->set_total( $new_ship_price ); // (optional)
$item->calculate_taxes($calculate_tax_for);

$order->add_item( $item );

$order->calculate_totals();

$order->update_status('on-hold');

// $order->save(); // If you don't update the order status

Tested an works.

Create programmatically a completed order without sending email to customer in WooCommerce

Note that the function get_product() is obsolete and replaced by wc_get_product() instead.

To avoid notifications to customer, you can set user ID to 0 first, then after updating order status to "complete", you can set the user address and the real user ID as follows:

$order = wc_create_order();
$order->set_customer_id(0);

foreach($_POST['basket'] as $prod){
$order->add_product( wc_get_product($prod['id']), $prod['count']);
}

$order->calculate_totals();
$order->update_status("completed", 'TEST', TRUE);

$order->set_address($address, 'billing'); // set address
$order->set_customer_id($userId); // Set user ID
$order_id = $order->save(); // Save to database (get order ID)

// Allow resending new order email
add_filter('woocommerce_new_order_email_allows_resend', '__return_true' );

// Resend new order email
WC()->mailer()->get_emails()['WC_Email_New_Order']->trigger( $order_id );

// Disable resending new order email
add_filter('woocommerce_new_order_email_allows_resend', '__return_false' );

Tested and works.

The only thing is that you will get 2 times "New order" notification sent to the admin (The second email will be set with the correct customer address details).

Related:

  • Allow re-sending New Order Notification in WooCommerce 5+
  • Create an order programmatically with line items in Woocommerce


Related Topics



Leave a reply



Submit