Search code examples
phpwordpresswoocommerceorderswoocommerce-subscriptions

Creating a WooCommerce Order programmatically for a subscription product


With woocommerce I am using WooCommerce Subscriptions plugin. I have created a function that can create an order based on the product SKU using wc_get_product_id_by_sku() function, from a Subscription product.

This is my function at the moment:

function create_new_order() {
    global $woocommerce;

    $address = array(
        'first_name' => 'Zakup',
        'last_name'  => 'Sklepowy',
        'email'      => '[email protected]',
        'phone'      => '123',
        'address_1'  => 'ul. Przykladowa 1',
        'address_2'  => 'm. 2',
        'city'       => 'Wroclaw',
        'postcode'   => '50-123',
    );


    $order = wc_create_order();

    $product = new WC_Product( wc_get_product_id_by_sku( 'wpoh-prof-webshop' ) );
    $order->add_product( $product, 1 );
    $order->set_address( $address, 'billing' );

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

    // Calculate totals
    $order->calculate_totals();
    $order->update_status( 'completed', 'In Store ', true );
}

With this line:

$product = new WC_Product (wc_get_product_id_by_sku ('wpoh-prof-webshop'));

I pick up the product to be placed with the order. I have hardcoded the customer billing address in this function as its's required.

When I run the function, an empty order is created that does not have any product or address attached to it.

order created without personal information or product:

order created without personal information or product

Can someone help me and tell me where it goes wrong?


Solution

  • 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'      => '[email protected]',
            '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