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
Convert Number to Letter with PHP
How to Solve Error 404 When Deploying Laravel Project to Cpanel
PHP Password_Verify() Hash and Pass Won't Match
How to Escape Single-Quote (Apostrophe) in String Using PHP
Rest API Authorization & Authentication (Web + Mobile)
PHP Composer Update "Cannot Allocate Memory" Error (Using Laravel 4)
What Is Normalized Utf-8 All About
How to Query All the Graphql Type Fields Without Writing a Long Query
Reconnection of Client When Server Reboots in Websocket
How to Password-Protect PHP Page
How to Set Up Use Httponly Cookies in PHP
Running a Zend Framework Action from Command Line
Avoid Public Folder of Laravel and Open Directly the Root in Web Server
Multiple Excerpt Lengths in Wordpress