Many Magento users report that their store's traffic and ecommerce conversions is not properly tracked by Google Analytics. That's because Magento's integration with the Google Analytics API is actually incorrect and incomplete.

Here's a quick way to fix these issues (Magento CE 1.5.1):

In Magento, the file responsible for parsing the Google Analytics code is located here:

app/code/core/Mage/GoogleAnalytics/Block/Ga.php
Scroll down to line 142 and you'll see the function that renders Google Analytic tracking scripts:

    /**
     * Render GA tracking scripts
     *
     * @return string
     */
    protected function _toHtml()
    {
        if (!Mage::helper('googleanalytics')->isGoogleAnalyticsAvailable()) {
            return '';
        }
        $accountId = Mage::getStoreConfig(Mage_GoogleAnalytics_Helper_Data::XML_PATH_ACCOUNT);
        return '
<!-- BEGIN GOOGLE ANALYTICS CODE -->
<script type="text/javascript">
//<![CDATA[
(function() {
var ga = document.createElement(\'script\'); ga.type = \'text/javascript\'; ga.async = true;
ga.src = (\'https:\' == document.location.protocol ? \'https://ssl\' : \'http://www\') + \'.google-analytics.com/ga.js\';
(document.getElementsByTagName(\'head\')[0] || document.getElementsByTagName(\'body\')[0]).appendChild(ga);
})();

var _gaq = _gaq || [];
' . $this->_getPageTrackingCode($accountId) . '
' . $this->_getOrdersTrackingCode() . '
//]]>
</script>
<!-- END GOOGLE ANALYTICS CODE -->';
    }
}
First of all we can see that the order of the script is not correct - the function should come after the variables and not the other way around. Second, the last line in the function differs from Google Analytics' instructions. After fixing these 2 issues, we get the following function:

    /**
     * Render GA tracking scripts
     *
     * @return string
     */
    protected function _toHtml()
    {
        if (!Mage::helper('googleanalytics')->isGoogleAnalyticsAvailable()) {
            return '';
        }
        $accountId = Mage::getStoreConfig(Mage_GoogleAnalytics_Helper_Data::XML_PATH_ACCOUNT);
        return '
<!-- BEGIN GOOGLE ANALYTICS CODE -->
<script type="text/javascript">
//<![CDATA[
var _gaq = _gaq || [];
' . $this->_getPageTrackingCode($accountId) . '
' . $this->_getOrdersTrackingCode() . '

(function() {
var ga = document.createElement(\'script\'); ga.type = \'text/javascript\'; ga.async = true;
ga.src = (\'https:\' == document.location.protocol ? \'https://ssl\' : \'http://www\') + \'.google-analytics.com/ga.js\';
var s = document.getElementsByTagName(\'script\')[0]; s.parentNode.insertBefore(ga, s);
})();
//]]>
</script>
<!-- END GOOGLE ANALYTICS CODE -->';
    }
}
That should already fix most issues. Except for one:

Tracking across sub domains

If your Magento store runs across multiple sub domains, you'll experience problems with Google Analytics tracking because Magento is not prepared for such scenarios.

So for example if your secure pages are set on a sub domain (such as secure.mydomain.com for example) while your unsecure pages use the main URL (such as mydomain.com), you will encounter several issues with Google Analytic tracking.

To fix this problem we need to do 2 things - first we need to add this line to the Google Analytics script:

_gaq.push(["_setAllowHash", false]);
And second we need to set the domain name. For this let's create a small function that will strip the main domain from the sub domains:

	/**
	 * Added to fix cross sub-domain tracking issue
	 */
	public function getDomainName()
	{
	$removepre = array ("http://","/","www","secure");
	if (!$this->hasData('domain_name')) {
		$this->setDomainName(str_replace($removepre, "", Mage::getBaseUrl()));
	}
	return $this->getData('domain_name');
	} 
Note that in this case I included "www" and "secure" to be removed but you should list there all the prefixes of the sub domains you are using (i.e. "store", "webshop", etc).

We can now use this function in the Google Analytics script like so:

_gaq.push(["_setDomainName", "' . $this->getDomainName() . '"]);
The end result is simple - the native "Render GA tracking scripts" Magento function should be replaced by the following:

	/**
	 * Added to fix cross sub-domain tracking issue
	 */
	public function getDomainName()
	{
	$removepre = array ("http://","/","www","secure");
	if (!$this->hasData('domain_name')) {
		$this->setDomainName(str_replace($removepre, "", Mage::getBaseUrl()));
	}
	return $this->getData('domain_name');
	} 

    /**
     * Render GA tracking scripts
     *
     * @return string
     */
    protected function _toHtml()
    {
        if (!Mage::helper('googleanalytics')->isGoogleAnalyticsAvailable()) {
            return '';
        }
        $accountId = Mage::getStoreConfig(Mage_GoogleAnalytics_Helper_Data::XML_PATH_ACCOUNT);
        return '
<!-- BEGIN GOOGLE ANALYTICS CODE -->
<script type="text/javascript">
//<![CDATA[
var _gaq = _gaq || [];
' . $this->_getPageTrackingCode($accountId) . '
_gaq.push(["_setDomainName", "' . $this->getDomainName() . '"]);
_gaq.push(["_setAllowHash", false]);
' . $this->_getOrdersTrackingCode() . '

(function() {
var ga = document.createElement(\'script\'); ga.type = \'text/javascript\'; ga.async = true;
ga.src = (\'https:\' == document.location.protocol ? \'https://ssl\' : \'http://www\') + \'.google-analytics.com/ga.js\';
var s = document.getElementsByTagName(\'script\')[0]; s.parentNode.insertBefore(ga, s);
})();
//]]>
</script>
<!-- END GOOGLE ANALYTICS CODE -->';
    }
}
That's it ;).

To not overwrite the core Ga.php file, you can either copy it over to the local folder and make the changes there, or create an extension to overwrite the block - sorry I don't have time to do it right now but I could if I get enough requests ;).

For reference here's the entire Ga.php file with the changes discussed above:

<?php
/**
* Magento
*
* NOTICE OF LICENSE
*
* This source file is subject to the Open Software License (OSL 3.0)
* that is bundled with this package in the file LICENSE.txt.
* It is also available through the world-wide-web at this URL:
* http://opensource.org/licenses/osl-3.0.php
* If you did not receive a copy of the license and are unable to
* obtain it through the world-wide-web, please send an email
* to license@magentocommerce.com so we can send you a copy immediately.
*
* DISCLAIMER
*
* Do not edit or add to this file if you wish to upgrade Magento to newer
* versions in the future. If you wish to customize Magento for your
* needs please refer to http://www.magentocommerce.com for more information.
*
* @category    Mage
* @package     Mage_GoogleAnalytics
* @copyright   Copyright (c) 2010 Magento Inc. (http://www.magentocommerce.com)
* @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
*/


/**
* GoogleAnalitics Page Block
*
* @category   Mage
* @package    Mage_GoogleAnalytics
* @author     Magento Core Team <core@magentocommerce.com>
*/
class Mage_GoogleAnalytics_Block_Ga extends Mage_Core_Block_Text
{
    /**
     * @deprecated after 1.4.1.1
     * @see self::_getOrdersTrackingCode()
     * @return string
     */
    public function getQuoteOrdersHtml()
    {
        return '';
    }

    /**
     * @deprecated after 1.4.1.1
     * self::_getOrdersTrackingCode()
     * @return string
     */
    public function getOrderHtml()
    {
        return '';
    }

    /**
     * @deprecated after 1.4.1.1
     * @see _toHtml()
     * @return string
     */
    public function getAccount()
    {
        return '';
    }

    /**
     * Get a specific page name (may be customized via layout)
     *
     * @return string|null
     */
    public function getPageName()
    {
        return $this->_getData('page_name');
    }

    /**
     * Render regular page tracking javascript code
     * The custom "page name" may be set from layout or somewhere else. It must start from slash.
     *
     * @link http://code.google.com/apis/analytics/docs/gaJS/gaJSApiBasicConfiguration.html#_gat.GA_Tracker_._trackPageview
     * @link http://code.google.com/apis/analytics/docs/gaJS/gaJSApi_gaq.html
     * @param string $accountId
     * @return string
     */
    protected function _getPageTrackingCode($accountId)
    {
        $pageName   = trim($this->getPageName());
        $optPageURL = '';
        if ($pageName && preg_match('/^\/.*/i', $pageName)) {
            $optPageURL = ", '{$this->jsQuoteEscape($pageName)}'";
        }
        return "
_gaq.push(['_setAccount', '{$this->jsQuoteEscape($accountId)}']);
_gaq.push(['_trackPageview'{$optPageURL}]);
";
    }

    /**
     * Render information about specified orders and their items
     *
     * @link http://code.google.com/apis/analytics/docs/gaJS/gaJSApiEcommerce.html#_gat.GA_Tracker_._addTrans
     * @return string
     */
    protected function _getOrdersTrackingCode()
    {
        $orderIds = $this->getOrderIds();
        if (empty($orderIds) || !is_array($orderIds)) {
            return;
        }
        $collection = Mage::getResourceModel('sales/order_collection')
            ->addFieldToFilter('entity_id', array('in' => $orderIds))
        ;
        $result = array();
        foreach ($collection as $order) {
            if ($order->getIsVirtual()) {
                $address = $order->getBillingAddress();
            } else {
                $address = $order->getShippingAddress();
            }
            $result[] = sprintf("_gaq.push(['_addTrans', '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s']);",
                $order->getIncrementId(), Mage::app()->getStore()->getFrontendName(), $order->getBaseGrandTotal(),
                $order->getBaseTaxAmount(), $order->getBaseShippingAmount(),
                $this->jsQuoteEscape($address->getCity()),
                $this->jsQuoteEscape($address->getRegion()),
                $this->jsQuoteEscape($address->getCountry())
            );
            foreach ($order->getAllVisibleItems() as $item) {
                $result[] = sprintf("_gaq.push(['_addItem', '%s', '%s', '%s', '%s', '%s', '%s']);",
                    $order->getIncrementId(),
                    $this->jsQuoteEscape($item->getSku()), $this->jsQuoteEscape($item->getName()),
                    null, // there is no "category" defined for the order item
                    $item->getBasePrice(), $item->getQtyOrdered()
                );
            }
            $result[] = "_gaq.push(['_trackTrans']);";
        }
        return implode("\n", $result);
    }

	/**
	 * Added by noam to fix cross sub-domain tracking issue
	 */
	public function getDomainName()
	{
	$removepre = array ("http://","/","get","secure");
	if (!$this->hasData('domain_name')) {
		$this->setDomainName(str_replace($removepre, "", Mage::getBaseUrl()));
	}
	return $this->getData('domain_name');
	} 

    /**
     * Render GA tracking scripts
     *
     * @return string
     */
    protected function _toHtml()
    {
        if (!Mage::helper('googleanalytics')->isGoogleAnalyticsAvailable()) {
            return '';
        }
        $accountId = Mage::getStoreConfig(Mage_GoogleAnalytics_Helper_Data::XML_PATH_ACCOUNT);
        return '
<!-- BEGIN GOOGLE ANALYTICS CODE -->
<script type="text/javascript">
//<![CDATA[
var _gaq = _gaq || [];
' . $this->_getPageTrackingCode($accountId) . '
_gaq.push(["_setDomainName", "' . $this->getDomainName() . '"]);
_gaq.push(["_setAllowHash", false]);
' . $this->_getOrdersTrackingCode() . '

(function() {
var ga = document.createElement(\'script\'); ga.type = \'text/javascript\'; ga.async = true;
ga.src = (\'https:\' == document.location.protocol ? \'https://ssl\' : \'http://www\') + \'.google-analytics.com/ga.js\';
var s = document.getElementsByTagName(\'script\')[0]; s.parentNode.insertBefore(ga, s);
})();
//]]>
</script>
<!-- END GOOGLE ANALYTICS CODE -->';
    }
}
Hope this helps someone!