Programmatically Creating New Order in Woocommerce

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.

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

WooCommerce create an order programmatically and redirect to payment

This did it for me:

if (isset($_POST['isOrder']) && $_POST['isOrder'] == 1) {
$address = array(
'first_name' => $_POST['notes']['domain'],
'last_name' => '',
'company' => $_POST['customer']['company'],
'email' => $_POST['customer']['email'],
'phone' => $_POST['customer']['phone'],
'address_1' => $_POST['customer']['address'],
'address_2' => '',
'city' => $_POST['customer']['city'],
'state' => '',
'postcode' => $_POST['customer']['postalcode'],
'country' => 'NL'
);

$order = wc_create_order();
foreach ($_POST['product_order'] as $productId => $productOrdered) :
$order->add_product( get_product( $productId ), 1 );
endforeach;

$order->set_address( $address, 'billing' );
$order->set_address( $address, 'shipping' );

$order->calculate_totals();

update_post_meta( $order->id, '_payment_method', 'ideal' );
update_post_meta( $order->id, '_payment_method_title', 'iDeal' );

// Store Order ID in session so it can be re-used after payment failure
WC()->session->order_awaiting_payment = $order->id;

// Process Payment
$available_gateways = WC()->payment_gateways->get_available_payment_gateways();
$result = $available_gateways[ 'ideal' ]->process_payment( $order->id );

// Redirect to success/confirmation/payment page
if ( $result['result'] == 'success' ) {

$result = apply_filters( 'woocommerce_payment_successful_result', $result, $order->id );

wp_redirect( $result['redirect'] );
exit;
}
}

Programmatically created WooCommerce order - set customer based on email instead of user ID

Function get_user_by() returns WP_User object, so you only need to take the ID from the object and substitute it into the function set_customer_id() from $order:

// $user - it is WP_User object
$user = get_user_by( 'email', $email );
$order->set_customer_id( $user->ID );

Creating a WooCommerce Order programmatically for a subscription product

To get one of the following subscription product objects:

  • WC_Product_Subscription (a subscription product type, a simple subscription),
  • WC_Product_Variable_Subscription (a variable-subscription product type),
  • WC_Product_Subscription_Variation (a subscription_variation product type).

You can not use new WC_Product() as it will throw an error.

Instead you should use wc_get_product() function.

Now global $woocommerce; is not required and doesn't do anything.

SKU: Get the product object from a product ID using wc_get_product_id_by_sku() function:

The SKU should always be from a simple subscription or a variation subscription, but never from a variable subscription product…

Try the following lightly modified function:

function create_new_order() {
$sku = 'wpoh-prof-webshop';
$address = array(
'first_name' => 'Zakup',
'last_name' => 'Sklepowy',
'email' => 'test@test.pl',
'phone' => '123',
'address_1' => 'ul. Przykladowa 1',
'address_2' => 'm. 2',
'city' => 'Wroclaw',
'postcode' => '50-123',
);

$order = wc_create_order(); // Create a WC_Order object and save it.

$order->set_address( $address, 'billing' ); // Set customer billing adress

$product = wc_get_product( wc_get_product_id_by_sku( $sku ) );
$order->add_product( $product, 1 ); // Add an order line item

// Set payment gateway
$payment_gateways = WC()->payment_gateways->payment_gateways();
$order->set_payment_method( $payment_gateways['cod'] );

$order->calculate_totals(); // Update order taxes and totals
$order->update_status( 'completed', 'In Store ', true ); // Set order status and save
}

Tested and works.

Related answer: Get the product object from sku and update the price in WooCommerce

Set an external order ID when creating programmatically a WooCommerce order

In WooCommerce, the order Id is the post Id, so you can't insert an external reference Id as you are trying to do. WooCommerce orders are a custom post type and order Id (the post Id) is generated from last post Id used in wp_posts database table…

Now you can set instead an Order number using the filter hook woocommerce_order_number, to set your own order reference number as order number, which is not the WooCommerce Order Id (post Id).

So your code will be:

$insert_marketplace_order_id = 1234567890;

$order = new WC_Order();
$order->set_date_created($date_here);

// $order-> etc. etc.

$order->update_meta_data('_order_number', $insert_marketplace_order_id); // <== Here
$order->save();

Then you will add the following hooked function to be able to get and display the correct order number:

add_filter( 'woocommerce_order_number', 'wc_set_order_number', 10, 2 );
function wc_set_order_number( $order_id, $order ) {

// Get the order number (custom meta data)
$order_number = $order->get_meta('_order_number');

return empty($order_number) ? $order_id : $order_number;
}

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

Now when using the WC_Order method get_order_number() WooCommerce will get/display the correct order number.

Note: As you don't use any arguments with wc_create_order() function is better to use $order = new WC_Order(); instead, which gives an empty WC_Order instance object without using save() method 2 times (so much lighter).

Related: Dynamic custom order numbers based on payment method

Programmatically created WooCommerce order have no tax for new users

Updated

I have revisited your code completely as there was different missing things and some mistakes. But I can't really test the code as this is related to a Gform plugin and custom form (not reproducible with the provided code and information):

add_action( 'gform_after_submission_16', 'post_to_third_party', 10, 2 );
function post_to_third_party( $entry, $form ) {
// var_dump($entry);

$order = wc_create_order();
$username = rgar( $entry, '20.3' );
$user_id = username_exists( $username );

// 1. User doesn't exist - Create it - send email - set address and define
if ( ! $user_id && $user_id == false ) {
$email = rgar( $entry, '10' );
$password = wp_generate_password( 12, false );
$first_name = rgar( $entry, '20.3' )
$last_name = rgar( $entry, '20.6' )

$user_data = array(
'user_login' => $username,
'user_pass' => $password,
'user_email' => $email,
'first_name' => $first_name,
'last_name' => $last_name,
'role' => 'customer',
);

$user_id = wp_insert_user( $user_data );

$address = array(
'first_name' => $first_name,
'last_name' => $last_name,
'email' => $email,
'phone' => rgar( $entry, '16' ),
'address_1' => rgar( $entry, '24.1' ),
'address_2' => rgar( $entry, '24.2' ),
'city' => rgar( $entry, '24.3' ),
'state' => rgar( $entry, '24.4' ),
'postcode' => rgar( $entry, '24.5' ),
'country' => rgar( $entry, '24.6' ),
);


// Update Billing and shipping user data
foreach( $address as $key => $value ) {
update_user_meta( $user_id, 'billing_' . $key, $value ); // Billing user data

if( ! in array( $key, array('phone', 'email') ) ) {
update_user_meta( $user_id, 'shipping_' . $key, $value ); // Shipping user data
}
}

// Send Customer new account notification
WC()->mailer()->get_emails()['WC_Email_Customer_New_Account']->trigger( $user_id, $password, true );

$order->set_address( $address, 'billing' ); // set billing addresses fields

unset( $address['phone'], $address['email'] ); // removing email and phone from array (for shipping)

$order->set_address( $address, 'shipping' ); // set shipping addresses fields

// For calculating taxes on items
$calculate_taxes_for = array(
'country' => $address['country'],
'state' => $address['state'],
'postcode' => $address['postcode'],
'city' => $address['city'],
);

}
// 2. User exist
else {
$user = get_user_by( 'ID', $user_id ); // Get the WP_User Object

$billing_address = array(
'first_name' => $user->billing_first_name,
'last_name' => $user->billing_last_name,
'email' => $user->billing_email,
'phone' => $user->billing_phone,
'address_1' => $user->billing_address_1,
'address_2' => $user->billing_address_2,
'city' => $user->billing_city,
'state' => $user->billing_postcode,
'postcode' => $user->billing_country,
'country' => $user->billing_state,
);

$shipping_address = array(
'first_name' => $user->shipping_first_name,
'last_name' => $user->shipping_last_name,
'address_1' => $user->shipping_address_1,
'address_2' => $user->shipping_address_2,
'city' => $user->shipping_city,
'state' => $user->shipping_postcode,
'postcode' => $user->shipping_country,
'country' => $user->shipping_state,
);

$order->set_address( $billing_address, 'billing' );
$order->set_address( $shipping_address, 'shipping' );

// For calculating taxes on items
$calculate_taxes_for = array(
'country' => ! empty($shipping_address['country']) ? $shipping_address['country'] : $billing_address['country'],
'state' => ! empty($shipping_address['state']) ? $shipping_address['state'] : $billing_address['state'],
'postcode' => ! empty($shipping_address['postcode']) ? $shipping_address['postcode'] : $billing_address['postcode'],
'city' => ! empty($shipping_address['city']) ? $shipping_address['city'] : $billing_address['city'],
);

}
$order->set_customer_id( $user_id );

$order->set_currency( get_woocommerce_currency() );
$order->set_prices_include_tax( 'yes' === get_option( 'woocommerce_prices_include_tax' ) );

$product = wc_get_product( rgar( $entry, '21' ) );

$item_id = $order->add_product( $product, 1 );
$line_item = $order->get_item( $item_id, false ); // Get the WC_Order_Item_Product Object instance from the Item Id
$line_item->calculate_taxes($calculate_taxes_for); // <== Calculating taxes
$line_item->save(); // Save data to WC_Order_Item_Product Object

$note = rgar( $entry, '5' );
$order->add_order_note( $note );
$order->set_customer_note( $note );

$order->calculate_totals();
$order->update_status('autoquote', true); // $order->save() is already included with update_status() method
}

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

Based on: Create an order programmatically with line items in Woocommerce



Related Topics



Leave a reply



Submit