Index: payment/uc_authorizenet/uc_authorizenet.module
===================================================================
--- payment/uc_authorizenet/uc_authorizenet.module	(revision 3)
+++ payment/uc_authorizenet/uc_authorizenet.module	(working copy)
@@ -448,15 +448,6 @@
 function _uc_authorizenet_charge($order, $amount, $data) {
   global $user;
 
-  // Build a description of the order for logging in Auth.Net.
-  $description = array();
-  foreach ((array) $order->products as $product) {
-    $description[] = $product->qty .'x '. $product->model;
-  }
-
-  $billing_country = uc_get_country_data(array('country_id' => $order->billing_country));
-  $delivery_country = uc_get_country_data(array('country_id' => $order->delivery_country));
-
   $context = array(
     'revision' => 'formatted-original',
     'type' => 'amount',
@@ -466,12 +457,49 @@
     'thou' => FALSE,
     'dec' => '.',
   );
+  // Build a description of the order for logging in Auth.Net.
+  $description = array();
+  foreach ((array) $order->products as $product) {
+    /*
+    * lineitems cause the data back from quickbooks to be more useful
+    * they need to be dealt with outside of the normal $submit_data routine as the standard
+    * is for several items. I did think about making them an array but I also wanted to handle the 
+    * length (mostly because the title field is only 31 & there is a high chance of fields being that long &
+    * being blown out over it when url_encode is done - ie a space becomes 3 characers not one) using the function tidyStringforXML but didn't know if that would be 'approved' 
+    */
+ 
+    /* 
+    * A.net fields
+    * x_line_item=item1<|>title<|><|>2<|>18.95<|>Y&x_line_item=
+    * item2<|>golf bag<|>Wilson golf carry bag, red<|>1<|>39.99<|>Y&
+    * x_line_item=item3<|>book<|>Golf for Dummies<|>1<|>21.99<|>Y&
+    *
+    * Item ID<|> Up to 31 characters The ID assigned to an item.
+    * item name<|>Up to 31 characters A short description of an item.
+    * item description<|>Up to 255 characters A detailed description of an item.
+    * itemX quantity<|>Up to two decimal places Must be a positive number The quantity of an item.
+    * item price (unit cost)<|>Up to two decimal places Must be a positive number Cost of an item per unit, excluding tax, freight, and duty.The dollar sign ($) is not allowed when submitting delimited information.
+    * itemX taxable
+    */
+    $lineitems .= "&x_line_item="._uc_authorize_tidyStringforXML($product->model,31)
+               ."<|>"._uc_authorize_tidyStringforXML($product->title,31)
+               ."<|>" ._uc_authorize_tidyStringforXML($product->title,255)             
+               ."<|>".uc_price($product->qty, $context, $options)
+               ."<|>".uc_price($product->price,  $context, $options)."<|>"
+               ."N";//it seems taxes are always listed @ the end not included in line item
+    $description[] = $product->qty .'x '. $product->model;
+  }
+  /*
+   * setting tax & shipping improves Quickbooks downloads
+   */
   $tax = 0;
   if (module_exists('uc_taxes')) {
     foreach (uc_taxes_calculate($order) as $tax_item) {
       $tax += $tax_item->amount;
     }
   }
+
+  
   $shipping = 0;
   if (is_array($order->line_items)) {
     foreach ($order->line_items as $item) {
@@ -480,6 +508,13 @@
       }
     }
   }
+
+
+  $billing_country = uc_get_country_data(array('country_id' => $order->billing_country));
+  $delivery_country = uc_get_country_data(array('country_id' => $order->delivery_country));
+
+
+
   // Build the POST data for the transaction.
   $submit_data = array(
     // Merchant Information
@@ -567,7 +602,7 @@
   curl_setopt($ch, CURLOPT_URL, $post_url);
   curl_setopt($ch, CURLOPT_VERBOSE, 0);
   curl_setopt($ch, CURLOPT_POST, 1);
-  curl_setopt($ch, CURLOPT_POSTFIELDS, implode('&', $post_fields));
+  curl_setopt($ch, CURLOPT_POSTFIELDS, implode('&', $post_fields) . $lineitems);
   curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
   curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, 0);
   curl_setopt($ch, CURLOPT_NOPROGRESS, 1);
@@ -1255,3 +1290,19 @@
 
   return $data;
 }
+/*
+ *  helper function to encode to url while ensuring string length is correct    
+ *  the xml is posted to a url so must not contain spaces etc. It also needs to be cut off at a certain
+ *   length to match the processor's field length. The cut needs to be made after spaces etc are 
+ *   transformed but must not include a partial transformed character e.g. %20 must be in or out not half-way
+ */
+
+ function _uc_authorize_tidyStringforXML($value,$fieldlength)
+    {
+        $xmlString   = substr(rawurlencode($value),0,$fieldlength);
+        $lastPercent = 	strrpos($xmlString,'%');
+        if ($lastPercent >  $fieldlength- 3) {
+            $xmlString = substr($xmlString,0,$lastPercent);
+        }
+        return $xmlString;
+    }
\ No newline at end of file
