Create an order programmatically with line items in Woocommerce

前端 未结 3 775
一个人的身影
一个人的身影 2020-12-01 04:00

I needed to create a Woocommerce order programatically, however using the \'old\' Woocommerce made this a very dirty procedure.

I had to insert all kind of database

3条回答
  •  盖世英雄少女心
    2020-12-01 04:12

    2017-2020 For WooCommerce 3 and Above

    Woocommerce 3 has introduced CRUD objects and there is lot of changes on Order items… Also some WC_Order methods are now deprecated like add_coupon().

    Here is a function that allow creating programmatically an order nicely with all required data in it, including the taxes:

    function create_wc_order( $data ){
        $gateways = WC()->payment_gateways->get_available_payment_gateways();
        $order    = new WC_Order();
    
        // Set Billing and Shipping adresses
        foreach( array('billing_', 'shipping_') as $type ) {
            foreach ( $data['address'] as $key => $value ) {
                if( $type === 'shipping_' && in_array( $key, array( 'email', 'phone' ) ) )
                    continue;
    
                $type_key = $type.$key;
    
                if ( is_callable( array( $order, "set_{$type_key}" ) ) ) {
                    $order->{"set_{$type_key}"}( $value );
                }
            }
        }
    
        // Set other details
        $order->set_created_via( 'programatically' );
        $order->set_customer_id( $data['user_id'] );
        $order->set_currency( get_woocommerce_currency() );
        $order->set_prices_include_tax( 'yes' === get_option( 'woocommerce_prices_include_tax' ) );
        $order->set_customer_note( isset( $data['order_comments'] ) ? $data['order_comments'] : '' );
        $order->set_payment_method( isset( $gateways[ $data['payment_method'] ] ) ? $gateways[ $data['payment_method'] ] : $data['payment_method'] );
    
        $calculate_taxes_for = array(
            'country'  => $data['address']['country'],
            'state'    => $data['address']['state'],
            'postcode' => $data['address']['postcode'],
            'city'     => $data['address']['city']
        );
    
        // Line items
        foreach( $data['line_items'] as $line_item ) {
            $args = $line_item['args'];
            $product = wc_get_product( isset($args['variation_id']) && $args['variation_id'] > 0 ? $$args['variation_id'] : $args['product_id'] );
            $item_id = $order->add_product( $product, $line_item['quantity'], $line_item['args'] );
    
            $item    = $order->get_item( $item_id, false );
    
            $item->calculate_taxes($calculate_taxes_for);
            $item->save();
        }
    
        // Coupon items
        if( isset($data['coupon_items'])){
            foreach( $data['coupon_items'] as $coupon_item ) {
                $order->apply_coupon(sanitize_title($coupon_item['code']));
            }
        }
    
        // Fee items
        if( isset($data['fee_items'])){
            foreach( $data['fee_items'] as $fee_item ) {
                $item = new WC_Order_Item_Fee();
    
                $item->set_name( $fee_item['name'] );
                $item->set_total( $fee_item['total'] );
                $tax_class = isset($fee_item['tax_class']) && $fee_item['tax_class'] != 0 ? $fee_item['tax_class'] : 0;
                $item->set_tax_class( $tax_class ); // O if not taxable
    
                $item->calculate_taxes($calculate_taxes_for);
    
                $item->save();
                $order->add_item( $item );
            }
        }
    
        // Set calculated totals
        $order->calculate_totals();
            
        if( isset($data['order_status']) ) {
            // Update order status from pending to your defined status and save data
            $order->update_status($data['order_status']['status'], $data['order_status']['note']);
            $order_id = $order->get_id();
        } else {
            // Save order to database (returns the order ID)
            $order_id = $order->save();
        }
        
        // Returns the order ID
        return $order_id;
    }
    

    Code goes in function.php file of your active child theme (or active theme) or in a plugin file.


    USAGE EXAMPLE from a data array:

    create_wc_order( array(
        'address' => array(
            'first_name' => 'Fresher',
            'last_name'  => 'StAcK OvErFloW',
            'company'    => 'stackoverflow',
            'email'      => 'test1@testoo.com',
            'phone'      => '777-777-777-777',
            'address_1'  => '31 Main Street',
            'address_2'  => '',
            'city'       => 'Chennai',
            'state'      => 'TN',
            'postcode'   => '12345',
            'country'    => 'IN',
        ),
        'user_id'        => '',
        'order_comments' => '',
        'payment_method' => 'bacs',
        'order_status'   => array(
            'status' => 'on-hold',
            'note'   => '',
        ),
        'line_items' => array(
            array(
                'quantity' => 1,
                'args'     => array(
                    'product_id'    => 37,
                    'variation_id'  => '',
                    'variation'     => array(),
                )
            ),
        ),
        'coupon_items' => array(
            array(
                'code'         => 'summer',
            ),
        ),
        'fee_items' => array(
            array(
                'name'      => 'Delivery',
                'total'     => 5,
                'tax_class' => 0, // Not taxable
            ),
        ),
    ) );
    

提交回复
热议问题