I have been working on integrating the Chamber Dashboard plugins with WooCommerce (WC) to give our users payment options other than PayPal. As part of this WC integration, I have had to create products, orders and add line items to the orders to show the custom information coming in from our plugins. Although there is a ton of documentation when it comes to WC, I had to struggle to get the line items added correctly. This was especially difficult because the orders were being created from the admin side and not by the user.

There is a front end form that comes with the Member Manager plugin that users use to either register their business for the first time or renew their businesses with the Chambers. Either way, when they fill out the form, there is an invoice being created on the back end which gets sent to the user who would pay with either a check or using PayPal.

Since we are replacing PayPal with whatever payment options are set in WC, the users will be taken to the order page when they submit the form. When the chambers decide to use WC payments, an order gets created along with the invoice when the form is filled. But this order by default only has the product information (products here are the membership levels that have been already set).

Why are line items needed here?

The chambers can choose to add processing fee, tax, or donation amount fields to the front end form, which need to be added to the WC order as well. These numbers usually change for each order, so they have to be added to the order when the order is created (when the front end form is filled out). Fortunately, WC has an easy way of adding line items to the orders using the function wc_add_order_item().

Below is the function used to add an order in WC. As part of that process, wc_add_order_item() is called which creates the line items with the information from the form.

Creating a new order in WooCommerce

//Create a new order in WooCommerce
function cdashmm_create_wc_order($address, $product_id, $total, $customer_id, $donation, $tax, $processing_fee){
	if(cdashmm_check_mm_connected_to_wc()){
		global $woocommerce;
        $args = array(
            'customer_id'   => $customer_id,
            'created_via'   => 'Chamber Dashboard Recurring Payments',
            'add_order_note' => 'Created via Chamber Dashboard Member Manager');

        // Now we create the order
        $order = wc_create_order($args);

        // The add_product() function below is located in /plugins/woocommerce/includes/abstracts/abstract_wc_order.php
        $order->add_product( wc_get_product($product_id), 1); // This is an existing SIMPLE product
        $order->set_address( $address, 'billing' );
        $order->set_created_via(  $args['created_via'] );
        $order->add_order_note( $args['add_order_note'] );
	$order->set_total( $total );
	$order->update_status("Completed", 'Imported order', TRUE);
      	$order_id = $order->get_id();

        if($donation){
	    $item_id = wc_add_order_item($order_id, array('order_item_name'	=>	__('Donation', 'cdashmm'), 'order_item_type'	=>	'fee'));
	    if ($item_id) {
	 	wc_add_order_item_meta($item_id, '_line_total', $donation);
	 	wc_add_order_item_meta($item_id, '_line_tax', 0);
	 	wc_add_order_item_meta($item_id, '_line_subtotal', $donation);
	 	wc_add_order_item_meta($item_id, '_line_subtotal_tax', 0);
	 	//wc_add_order_item_meta($item_id, '_tax_class', 'zero-rate');
	 }
}
		if($processing_fee){
		      $item_id = wc_add_order_item($order_id, array('order_item_name'	=>	__('Processing Fee', 'cdashmm'), 'order_item_type'	=>	'fee'));
		if ($item_id) {
	 	       wc_add_order_item_meta($item_id, '_line_total', $processing_fee);
	 		wc_add_order_item_meta($item_id, '_line_tax', 0);
	 		wc_add_order_item_meta($item_id, '_line_subtotal', $processing_fee);
	 		wc_add_order_item_meta($item_id, '_line_subtotal_tax', 0);
	 		//wc_add_order_item_meta($item_id, '_tax_class', 'zero-rate');
	 		}
}
       if($tax){
         $item_id = wc_add_order_item($order_id, array('order_item_name' => __('Tax', 'cdashmm'), 'order_item_type' => 'fee'));
 			if ($item_id) {
 			        wc_add_order_item_meta($item_id, '_line_total', $tax);
 				wc_add_order_item_meta($item_id, '_line_tax', 0);
 				wc_add_order_item_meta($item_id, '_line_subtotal', $tax);
 				wc_add_order_item_meta($item_id, '_line_subtotal_tax', 0);
 				//wc_add_order_item_meta($item_id, '_tax_class', 'zero-rate');
 			 }
      }
	}
    return $order_id;
}

In the function above, the wc_add_order_item() is called for each line item that needs to be created.
For example, if there is a donation field enabled on the front end form, I would like to include the donation amount as a line item in the order.

if($donation){
     $item_id = wc_add_order_item($order_id, array('order_item_name'	=>	__('Donation', 'cdashmm'), 'order_item_type'	=>	'fee'));
     if ($item_id) {
	wc_add_order_item_meta($item_id, '_line_total', $donation);
	wc_add_order_item_meta($item_id, '_line_tax', 0);
	wc_add_order_item_meta($item_id, '_line_subtotal', $donation);
	wc_add_order_item_meta($item_id, '_line_subtotal_tax', 0);
	}
}

So, this creates a line item with the value of donation from the user submitted form. The same is done for Processing Fee and the tax. Here is a screenshot of the WC order on the back end with processing fee and the tax added as items to the order. The donation was disabled on the site. So, it was not added to the order.

Adding line items to WooCommerce order

This enables us to store all the order information in one place and the total now correctly reflects the items in the order.

Leave a Reply

%d bloggers like this: