Skip to end of metadata
Go to start of metadata

You are viewing an old version of this page. View the current version.

Compare with Current View Page History

« Previous Version 29 Next »

Configuring Google Analytics

UltraCart has the ability to automatically inject Google Analytics tracking code into your catalog and checkout screen branding. 

The following tutorial will walk you through configuring your Google Analytics account information within your UltraCart account.

Storefronts 

Storefronts

For the storefronts integration, please navigate:

Main MenuStorefront → (pop out menu) Storefront host → (Storefront Menu) Conversion Tracking → Google (tab)

For Storefronts Documentation, see: Adding Google Tracking to your web site

StoreFront Conversion and Tracking

Legacy Screen Branding Themes

The configuration fields for Google Analytics are found in your Screen Branding configuration area.  This is also the same place for other supported and third party conversion and tracking configuration.

That being said, we need to navigate to:

Now scroll down to the Supported section. This section contains all of the different tracking systems that UltraCart has built in support for. In this list you will find "Google Analytics Account Number - Default" as shown below.

Enter your "UA-" value into this field.

Tracking Types

There are multiple tracking types supported by UltraCart. The table below describes the various types, the script Google uses, and whether they support asynchronous loading:

Domain Override

  By default the system is using secure.ultracart.com in the checkout then the GA tracking is set to use that host. If you have a custom SSL then secure.yourdomain.com is passed to the tracking script as .yourdomain.com. This field will provide advanced user the ability to override this on the Google analytics tracking script. 

Pro Tip - Use Custom SSL

Given that cookies are used to track the checkout progress, it's best if you use a custom SSL so that your checkout and website are on the same root domain.

So for example you would have:

www.yourdomain.com -> secure.yourdomain.com

Then in your GTM or GA tracking you would set the allow domain to ".yourdomain.com". This will allow the GA tracking cookies to be visible on both domains.

If you have two different root domains then on your www.yourdomain.com you're going to have to implement some of the techniques documented on this page.

https://support.google.com/analytics/answer/1034342?hl=en


Pricing Tiers

If you have pricing tiers configured on your account for wholesale customers then you can track them on a separate Google Analytics account if you would like. There will be an additional row in the configuration for each pricing tier on your store. If you leave these blank then UltraCart will use the default UA- account when tracking the customer even if they have a pricing tier.

Frequently Asked Questions

Q: I have Google Analytics configured and it's working fine for order placed from the website, but it's not being triggered for my auto orders?

A: The Google Analytic script is fired off based on cookies in the customer browser during the checkout. Since auto orders are generated without the additional involvement from the customer's browser, the GA script is not fired.

The following message from one of our merchants describes an *unofficial* (not directly supported by UltraCart basic support, troubleshooting only available through paid support $100/hr after review by Pro Service department) workaround that they have implemented to triggered the GA script using the XML Postback:

For the latest and greatest code, please visit this github site:

https://github.com/ryanjkelly/xml2ga

Ryan has made numerous improvements since the initial development which is listed below.



"Yes, I have been successfully tracking UC sales and refunds for the past few weeks through XML postback. I don't have a "template" I can send you, but this (link below) PHP code
will pretty much work out of the box if you just place your Google Analytics account ID in it. Note: the Google Analytics account must be the newer (Universal Analytics) type or else this won't work.

https://snipt.net/raw/72a876575e01ca300f34bd67fa26e0a3/?nice

Refunds are recorded into GA with "ref-" appended to the transaction ID so that you can then separate them easily in reports. I also plan to append "auto-" to auto orders to separate them in reports as well but haven't done that yet.

A few things to note when implementing this. Make sure the time zone in the Google Analytics property matches UltraCart's server time zone, which I think is EST. Also, merchants that get sales 24/7 will notice that daily revenue from GA and UC sometimes won't match up. This is because, for example, if a customer orders something from UC at 11:57pm, the order may not get recorded into GA until 12:02am, which it is then the following day." 


Sample Script
<?php

// ----------------------------------------------- //
//    Generate a unique ID for Google Analytics    //
// ----------------------------------------------- //

function gen_uuid() { // Generates a UUID. A UUID is required for the measurement protocol.
  return sprintf( '%04x%04x-%04x-%04x-%04x-%04x%04x%04x',
    // 32 bits for "time_low"
    mt_rand( 0, 0xffff ), mt_rand( 0, 0xffff ),
    // 16 bits for "time_mid"
    mt_rand( 0, 0xffff ),
    // 16 bits for "time_hi_and_version",
    // four most significant bits holds version number 4
    mt_rand( 0, 0x0fff ) | 0x4000,
    // 16 bits, 8 bits for "clk_seq_hi_res",
    // 8 bits for "clk_seq_low",
    // two most significant bits holds zero and one for variant DCE1.1
    mt_rand( 0, 0x3fff ) | 0x8000,
    // 48 bits for "node"
    mt_rand( 0, 0xffff ), mt_rand( 0, 0xffff ), mt_rand( 0, 0xffff )
  );
}


// -------------------- //
//     GA Post Data     //
// -------------------- //

$url = 'https://www.google-analytics.com/collect'; // This is the URL to which we'll be sending the post request.
$user_agent = 'UltraCart/1.0'; // User agent recorded into Google


// ---------------------------------- //
//    Get UltraCart post back data    //
// ---------------------------------- //

// Read in the XML document from the post data
$xml_document = file_get_contents('php://input');

// Parse the XML Document into a DOM Object
$doc = new DOMDocument();
$doc->loadXML($xml_document);

// Extract key fields
$exports = $doc->getElementsByTagName("export");
foreach ($exports as $export) {
	$orders = $export->getElementsByTagName("order");
	
	// Get order element
	foreach($orders as $order) {
		
		// Get order data
		$orderCS = $order->getElementsByTagName("current_stage")->item(0)->nodeValue;           // gets the current stage of the order
		$orderPS = $order->getElementsByTagName("payment_status")->item(0)->nodeValue;          // gets the payment status of the order
		$orderSM = $order->getElementsByTagName("shipping_method")->item(0)->nodeValue;         // gets the shipping method of the order
		$orderTI = $order->getElementsByTagName("order_id")->item(0)->nodeValue;                // gets the transaction ID
		$orderTR = $order->getElementsByTagName("total")->item(0)->nodeValue;                   // gets the transaction revenue
		$orderTS = $order->getElementsByTagName("shipping_handling_total")->item(0)->nodeValue; // gets the transaction shipping
		$orderTT = $order->getElementsByTagName("tax")->item(0)->nodeValue;                     // gets the transaction tax
		$customField1 = $order->getElementsByTagName("custom_field_1")->item(0)->nodeValue;     // gets the product
		$customField2 = $order->getElementsByTagName("custom_field_2")->item(0)->nodeValue;     // gets the product category
		$customField4 = $order->getElementsByTagName("custom_field_4")->item(0)->nodeValue;     // gets the GA client ID
		$customField5 = $order->getElementsByTagName("custom_field_5")->item(0)->nodeValue;     // gets the subid value
		$orderOTI = $order->getElementsByTagName("auto_order_original_order_id")->item(0)->nodeValue; // gets the original transaction ID
		$orderRTR = $order->getElementsByTagName("total_refunded")->item(0)->nodeValue;               // gets the refunded transaction revenue
		$orderRBU = $order->getElementsByTagName("refund_by_user")->item(0)->nodeValue;               // gets the user who processed the refund
		$orderRMN = $order->getElementsByTagName("merchant_notes")->item(0)->nodeValue;               // gets the merchant notes for refund

			// ----------------------------------------- //
			//    POST Order Data to GOOGLE ANALYTICS    //
			// ----------------------------------------- //

			// generate (or pass through) unique ID for GA CID
			if (empty($customField4) || $customField4 == 'undefined') { $orderCID = gen_uuid(); } else { $orderCID = $customField4; }

			$orderData = array( // This is an associative array that will contain all the parameters that we'll send to Google Analytics
			  'v' => 1, // The version of the measurement protocol
			  'tid' => 'UA-######-###', // Google Analytics account ID
			  'cid' => $orderCID, // The client ID or UUID
			  't' => 'transaction' // Hit Type
			);
				
				// ------------------------------------------------------------ //
				//    If order is in 'Completed Order' stage -AND- 'Processed'  //
				//       -AND- not coming from the 'Shipping Department'        //
				//                             -OR-                             //
				//        in the 'Shipping Department' -AND- 'Processed'        //
				// ------------------------------------------------------------ //
				
				if (($orderCS === 'CO' && $orderPS === 'Processed' && empty($orderSM)) || ($orderCS === 'SD' && $orderPS === 'Processed')) {
					$orderData['dh'] = 'secure.ultracart.com'; // Sets the document hostname for GA
					$orderData['dp'] = '/processed'; // Sets the document path for GA
					$orderData['dt'] = 'Order Processed'; // Sets the document title for GA
					$orderData['ti'] = $orderTI; // Sets the transaction ID for GA
					$orderData['tr'] = $orderTR; // Sets the transaction revenue for GA
					$orderData['ts'] = $orderTS; // Sets the transaction shipping for GA
					$orderData['tt'] = $orderTT; // Sets the transaction tax for GA
					$orderData['cd3'] = $customField2; // Sets a custom dimension (Product Category)
					$orderData['cd4'] = $customField5; // Sets a custom dimension (Subid)
				}

				// --------------------------------------------------- //
				//           If order has been refunded from           //
				//    'Completed Orders' -OR- 'Shipping Department'    //
				// --------------------------------------------------- //

				if (($orderCS === 'CO' && $orderPS === 'Refunded') || ($orderCS === 'SD' && $orderPS === 'Refunded')) {
					$orderData['dh'] = 'secure.ultracart.com'; // Sets the document hostname for GA
					$orderData['dp'] = '/refunded'; // Sets the document path for GA
					$orderData['dt'] = 'Order Refunded'; // Sets the document title for GA
					$orderData['ti'] = 'ref-'.$orderOTI; // Sets the transaction ID for GA
					$orderData['tr'] = '-'.$orderRTR; // Sets the transaction revenue for GA
					$orderData['cd11'] = $orderRBU; // Sets a custom dimension (Refund by User)
					$orderData['cd5'] = $orderRMN; // Sets a custom dimension (Merchant Notes)
					$orderData['cd3'] = $customField2; // Sets a custom dimension (Product Category)
					$orderData['cd4'] = $customField5; // Sets a custom dimension (Subid)
				}

			$orderContent = http_build_query($orderData); // The body of the post must include exactly 1 URI encoded payload and must be no longer than 8192 bytes. See http_build_query.
			$orderContent = utf8_encode($orderContent); // The payload must be UTF-8 encoded.

			$orderCH = curl_init();
			curl_setopt($orderCH,CURLOPT_USERAGENT, $user_agent);
			curl_setopt($orderCH,CURLOPT_URL, $url);
			curl_setopt($orderCH,CURLOPT_HTTPHEADER,array('Content-type: application/x-www-form-urlencoded'));
			curl_setopt($orderCH,CURLOPT_HTTP_VERSION,CURL_HTTP_VERSION_1_1);
			curl_setopt($orderCH,CURLOPT_POST, TRUE);
			curl_setopt($orderCH,CURLOPT_POSTFIELDS, $orderContent);
			curl_exec($orderCH);
			curl_close($orderCH);

	} // END foreach($orders as $order)

		// Get item element/s
		$items = $order->getElementsByTagName("item");
		$i = 0; // set increment number
		foreach($items as $item) {

			// Get item data
			$itemIN = $item->getElementsByTagName("item_id")->item(0)->nodeValue;                  // gets the item name
			$itemIP = $item->getElementsByTagName("total_cost_with_discount")->item(0)->nodeValue; // gets the item price
			$itemIQ = $item->getElementsByTagName("quantity")->item(0)->nodeValue;                 // gets the item quantity
			
			// ------------------------------------------------------------ //
			//    If order is in 'Completed Order' stage -AND- 'Processed'  //
			//       -AND- not coming from the 'Shipping Department'        //
			//                             -OR-                             //
			//        in the 'Shipping Department' -AND- 'Processed'        //
			// ------------------------------------------------------------ //
			
			if (($orderCS === 'CO' && $orderPS === 'Processed' && empty($orderSM)) || ($orderCS === 'SD' && $orderPS === 'Processed')) { 

			// ---------------------------------------- //
			//    POST Item Data to GOOGLE ANALYTICS    //
			// ---------------------------------------- //

			$i++; // increase number for each $item
			$itemData = 'itemData'.$i; // append increment number to $itemData variable
			$itemContent = 'itemContent'.$i; // append increment number to $itemContent variable
			$itemCH = 'itemCH'.$i; // append increment number to $itemContent variable
			$itemCID = 'itemCID'.$i; // append increment number to $itemCID variable

			${$itemCID} = $orderCID; // use $orderCID as the GA CID

			${$itemData} = array( // This is an associative array that will contain all the parameters that we'll send to Google Analytics
			  'v' => 1, // The version of the measurement protocol
			  'tid' => 'UA-######-###', // Google Analytics account ID
			  'cid' => ${$itemCID}, // The client ID or UUID
			  't' => 'item' // Hit Type
			);

			${$itemData}['ti'] = $orderTI; // Sets the transaction ID for GA
			${$itemData}['in'] = $itemIN; // Sets the item name for GA
			${$itemData}['ip'] = $itemIP; // Sets the item price for GA
			${$itemData}['iq'] = $itemIQ; // Sets the item quantity for GA
			${$itemData}['cd3'] = $customField2; // Sets a custom dimension (Product Category)
			${$itemData}['cd4'] = $customField5; // Sets a custom dimension (Subid)

			${$itemContent} = http_build_query(${$itemData}); // The body of the post must include exactly 1 URI encoded payload and must be no longer than 8192 bytes. See http_build_query.
			${$itemContent} = utf8_encode(${$itemContent}); // The payload must be UTF-8 encoded.

			${$itemCH} = curl_init();
			curl_setopt(${$itemCH},CURLOPT_USERAGENT, $user_agent);
			curl_setopt(${$itemCH},CURLOPT_URL, $url);
			curl_setopt(${$itemCH},CURLOPT_HTTPHEADER,array('Content-type: application/x-www-form-urlencoded'));
			curl_setopt(${$itemCH},CURLOPT_HTTP_VERSION,CURL_HTTP_VERSION_1_1);
			curl_setopt(${$itemCH},CURLOPT_POST, TRUE);
			curl_setopt(${$itemCH},CURLOPT_POSTFIELDS, ${$itemContent});
			curl_exec(${$itemCH});
			curl_close(${$itemCH});
			
			} // END IF ORDER IS COMPLETED/SHIPPING AND PROCESSED

		} // END foreach($items as $item)
			
} // END foreach ($exports as $export)



// BEGIN $order/$export
foreach ($exports as $export) { foreach($orders as $order) {

	// ---------------------------------------------- //
	//    POST #1 to GOOGLE ANALYTICS (Event Data)    //
	// ---------------------------------------------- //

// ------------------------------------------------------------ //
//    If order is in 'Completed Order' stage -AND- 'Processed'  //
//       -AND- not coming from the 'Shipping Department'        //
//                             -OR-                             //
//        in the 'Shipping Department' -AND- 'Processed'        //
// ------------------------------------------------------------ //

if (($orderCS === 'CO' && $orderPS === 'Processed' && empty($orderSM)) || ($orderCS === 'SD' && $orderPS === 'Processed')) { 

	$data1 = array( // This is an associative array that will contain all the parameters that we'll send to Google Analytics
	  'v' => 1, // The version of the measurement protocol
	  'tid' => 'UA-######-###', // Google Analytics account ID
	  'cid' => $orderCID, // The client ID or UUID
	  't' => 'event' // Hit Type
	);
	
	$data1['dh'] = 'secure.ultracart.com'; // The GA document host name
	$data1['ec'] = 'Sales'; // The GA event category
	$data1['ea'] = 'Order Processed'; // The GA event action
	$data1['el'] = (isset($orderTI) ? $orderTI : 'No Order ID'); // The GA event label
	$data1['cd3'] = $customField2; // Sets a custom dimension (Product Category)
	$data1['cd4'] = $customField5; // Sets a custom dimension (Subid)
	
	$content1 = http_build_query($data1); // The body of the post must include exactly 1 URI encoded payload and must be no longer than 8192 bytes. See http_build_query.
	$content1 = utf8_encode($content1); // The payload must be UTF-8 encoded.
	
	$ch1 = curl_init();
	curl_setopt($ch1,CURLOPT_USERAGENT, $user_agent);
	curl_setopt($ch1,CURLOPT_URL, $url);
	curl_setopt($ch1,CURLOPT_HTTPHEADER,array('Content-type: application/x-www-form-urlencoded'));
	curl_setopt($ch1,CURLOPT_HTTP_VERSION,CURL_HTTP_VERSION_1_1);
	curl_setopt($ch1,CURLOPT_POST, TRUE);
	curl_setopt($ch1,CURLOPT_POSTFIELDS, $content1);
	curl_exec($ch1);
	curl_close($ch1);
	
} // END IF ORDER IS COMPLETED/SHIPPING AND PROCESSED

}} // END $order/$export


//
// NOTICES
//

foreach ($exports as $export) {
	foreach($orders as $order) {
		// Notice: Order processed and placed into 'Completed Orders'.
		if ($orderCS === 'CO' && $orderPS === 'Processed' && empty($orderSM)) { echo 'Order has been processed and placed into Completed Orders. ID is '.$orderTI.', CID is '.$orderCID.' and total is '.$orderTR.'. '; }
		// Notice: Order processed and placed into 'Shipping Department'.
		if ($orderCS === 'SD' && $orderPS === 'Processed') { echo 'Order has been processed and placed into Shipping Department. ID is '.$orderTI.', CID is '.$orderCID.' and total is '.$orderTR.'. '; }
		// Notice: Duplicate order ignored.
		if ($orderCS === 'CO' && $orderPS === 'Processed' && !empty($orderSM)) { echo 'Order from Shipping Department has been ignored. ID is '.$orderTI.' and total is '.$orderTR.'. '; }
		// Notice: Order refunded from 'Completed Orders'.
		if ($orderCS === 'CO' && $orderPS === 'Refunded') { echo 'Order from Completed Orders has been refunded. ID is '.$orderOTI.' and amount refunded is '.$orderRTR.'. Merchant Notes by '.$orderRBU.': '.$orderRMN.'. '; }
		// Notice: Order refunded from 'Shipping Department'.
		if ($orderCS === 'SD' && $orderPS === 'Refunded') { echo 'Order from shipping department has been refunded. ID is '.$orderOTI.' and amount refunded is '.$orderRTR.'. Merchant Notes by '.$orderRBU.': '.$orderRMN.'. '; }
	}
	foreach($items as $item) {
		// Get item data
		$itemIN = $item->getElementsByTagName("item_id")->item(0)->nodeValue;                  // gets the item name
		$itemIP = $item->getElementsByTagName("total_cost_with_discount")->item(0)->nodeValue; // gets the item price
		$itemIQ = $item->getElementsByTagName("quantity")->item(0)->nodeValue;                 // gets the item quantity
		// Notice: Items ordered.
		if ($orderCS === 'CO' && $orderPS === 'Processed' && empty($orderSM) || $orderCS === 'SD' && $orderPS === 'Processed') {echo 'Ordered '.$itemIQ.' of '.$itemIN.' for '.$itemIP.' each. ';}
	} 
}

?>

Q: How do I support Google Analytics Display Network Tracking?

A: UltraCart supports Google Analytics Display Network tracking (DoubleClick.net) already. In the Tracking Type drop down select "Display Network".  This will automatically change the tracking code snippet to conform with Google's document Update Your Analytics Tracking Code to Support Display Advertising.

Q: Which "tracking Types" is the Universal Analytics?

A: Choose "E-Commerce" from the tracking type drop-down menu, which corresponds to the Universal Analytics (UA) with the e-commerce plugin.

Q: Are there any tools for testing my google analytics?

A: The Google Analytics Debugger tool can be used to test and troubleshoot your google analytics configuration.
https://chrome.google.com/webstore/detail/google-analytics-debugger/jnkmfdileelhofjcijamephohjechhna?hl=en 

Q: How do I configure goals and funnels tracking?

A: The conversion page (screen) to use for the Google Analytics Goals and Funnels is:

https://secure.ultracart.com/checkout/receiptLoad.do

(NOTE: For storefronts replace "secure.ultracart.com" with the storefronts hostname.)

Please read and follow the Google Analytics Knowledge Base Article URL below) on integration with a 3rd party shopping cart.  It's critical to do the URL linking properly:

http://support.google.com/analytics/bin/answer.py?hl=en&answer=1034148


NOTE: If you utilize a custom SSL domain then you'll need to replace secure.ultracart.com with your custom SSL domain (URL).

***We strongly recommend the following company for advanced Google Analytics integration:

http://www.tribalcore.com/services/ultracart-support-services/

Their expertise will allow you to get the most from Google Analytics.

Advanced Google Analytics Consultation

If you are having trouble with Google Analytics tracking traffic from your sites end-to-end through the checkout then we recommend hiring a consultant to assist you with the proper site linking and conversion code. 

https://www.ultracart.com/resources/partners/seo_and_analytics/tribal_core/

https://www.ultracart.com/resources/partners/seo_and_analytics/tech-guys-who-get-marketing/

Related Resources

Introduction to Google Analytics in UltraCart

Custom Google Analytics Conversion Pixel

Upgrading to Asynchronous Google Analytics Tracking Code in a Catalog Template

  • No labels