This is a very interesting question. I think you are getting a lot of down votes and criticism because this is a hard question to answer but not because it is bad question. Fundamentally, you want to create a line item in the cart and a line item in an order directly from data entered on a form. I know this can be done because I have done something very similiar. The difficulty is that the API for WC_Cart requires a WC_Product object to create line items. I circumvented this by providing a proxy product object for WC_Cart to work with. Normally the properties of a product object would be populated from data in the database but I used actions and filters to populate the properties of the proxy object. Since, the invoice is generated from the order there is nothing to do as the line item would now exists in the order. For me this solution required a significant amount of advanced code, i.e., it took a lot of time and effort and advanced knowledge of WooCommerce.
Now for my rant. This is a very ugly solution and would not be necessary if WooCommerce was implemented differently. WooCoomerce (and WordPress) primarily use actions and filters to modify the default behavior of code. But, in object oriented programming classes are extended to modify the default behavior of a class. E.g. the class WC_Cart has the method:
public function add_to_cart( $product_id = 0, $quantity = 1, $variation_id = 0, $variation = array(), $cart_item_data = array() )
where either $product_id or $variation_id must be valid. Ideally, you would extend class WC_Cart with a new function add_to_cart() that can create a line item from only $cart_item_data. However, you cannot extend the class WC_Cart because the cart is created in the class WooCommerce by:
public function initialize_cart() {
...
$this->cart = new WC_Cart();
...
}
Conversely, the use of class WC_Order is implemented so that it can be extended because order objects are created by a factory:
class WC_Order_Factory {
public static function get_order( $order_id = false ) {
...
// Filter classname so that the class can be overridden if extended.
$classname = apply_filters( 'woocommerce_order_class', $classname, $order_type, $order_id );
return new $classname( $order_id );
}
}
So you can use the filter 'woocommerce_order_class' to extend the class WC_Order.