Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

WooCommerce: Creating an order programmatically with a variable product

I'm trying to create an order programmatically. Using wc_create_order() this is pretty straightforward:

$myProduct = new WC_Product(100);
$order = wc_create_order();
$order->add_product($myProduct, 1);
$order->calculate_totals();

This works as expected, and an order is created for a simple product with ID 100 for the correct amount.

However, if I try to do this with a variation, it doesn't seem to behave correctly. After much trial and error, I got it to sort-of work this way:

$membershipProduct = new WC_Product_Variable(100);
$theMemberships = $membershipProduct->get_available_variations();

$trueProduct = new WC_Product(100);

$variationsArray = array();

foreach ($theMemberships as $membership) {
    if ($membership['sku'] == $chosenVariation) {
        $variationID = $membership['variation_id'];
        $variationsArray = $membership['attributes'];
    }
}

if ($variationID) {
    $trueProduct->variation_id = $variationID;
}

$order = wc_create_order();
$order->add_product($trueProduct, 1, $variationsArray);
$order->calculate_totals();

However, although it does create the order with the correct product and the correct variation ID, the total for the order is always 0 (which, coincidentally, is the price of the first variation).

Originally I was trying $order->add_product() with the object created from new WC_Product_Variable(), but that resulted in no products being added to the order at all, which leads me to believe it's an issue with creating orders programmatically with variable products. However, following the WooCommerce source code for these calls, I can't see what I'm doing wrong.

Is there something I'm missing, or a better way to create an order with a variable product?

like image 941
indextwo Avatar asked Sep 12 '15 19:09

indextwo


People also ask

How do I place an order in WooCommerce programmatically?

We can use the WC function to create the order programmatically, also we can set the order number. You can add the following codes to the functions. php file. You can also change the get_product( 1061 ) ID to add the product number of orders.


2 Answers

Solved it.

Even though I could have sworn I'd tried (and failed) doing it this way, the answer was to not add the parent product ($trueProduct in the example), but to add the variation product by its ID.

This may have failed previously because, as @helgatheviking noted, my $variationsArray was formatted incorrectly according to the source; I needed an array with a ['variation'] key to send the correct variation array of attributes.

In total, my working code now looks like this:

$membershipProduct = new WC_Product_Variable(100);
$theMemberships = $membershipProduct->get_available_variations();

$variationsArray = array();

foreach ($theMemberships as $membership) {
    if ($membership['sku'] == $chosenVariation) {
        $variationID = $membership['variation_id'];
        $variationsArray['variation'] = $membership['attributes'];
    }
}

if ($variationID) {
    $varProduct = new WC_Product_Variation($variationID);

    $order = wc_create_order();
    $order->add_product($varProduct, 1, $variationsArray);
    $order->calculate_totals();
}
like image 143
indextwo Avatar answered Oct 21 '22 04:10

indextwo


if you already have the variation_id you can just do this

$product_variation = new WC_Product_Variation($variation_id);
$order = wc_create_order();
$args=array();
foreach($product_variation->get_variation_attributes() as $attribute=>$attribute_value){
        $args['variation'][$attribute]=$attribute_value;
}
$order->add_product($product_variation, $product['quantity'], $args);
like image 34
abhinav penmetsa Avatar answered Oct 21 '22 06:10

abhinav penmetsa