Google Analytics server side ecommerce tracking

Saturday 14 November 2015

Google Tracking

Update 17th June 2016:

There is a new version of this code on http://www.briandorey.com/post/Google-Analytics-server-side-ecommerce-tracking-V2


A recurring issue we have on several of the ecommerce websites we manage is the Google Analytics Ecommerce Tracking system which often fails to save the customer’s order into the analytics account when the customers have completed their purchases.

This can be caused by the customer having ad blocking software installed or not returning to the online shop and viewing the order confirmation page which contains the Google tracking code.

Google have a server side system called Google Analytics Measurement Protocol API which allows you to post direct requests to the analytics servers to log events such as page views or other tracked events.

I found a basic C# wrapper for the Google Analytics Measurement Protocol API on github https://gist.github.com/0liver/11229128 and modified the code to allow me to track the items ordered in addition to the customers order as shown below.

I hope this code is useful for anyone trying to track ecommerce purchases using the Google Analytics Measurement Protocol API systems.

 try
        {

            var request = (HttpWebRequest)WebRequest.Create("http://www.google-analytics.com/collect");
            request.Method = "POST";
            request.KeepAlive = false;
            // the request body we want to send

            int x = 1;
            var postData = new Dictionary
                           {
                               { "v", "1" },
                               { "tid", "UA-000000000" }, // Replace with your Google tracking account number
                               { "cid", "555" },

                               { "dh","yourdomainname.com" },
                               { "dp", "/callback.aspx" },
                               { "dt", "Payment Complete" },

                              { "ti", "PP0001"}, // Transaction ID. Required.
                               { "ta", "Yoursitename" }, // Affiliation.
                               { "tr", 99.99" }, // Revenue.
                               { "tt", "0" }, // Tax.
                               { "ts", "5.99" }, // Shipping.
                               { "pa", "purchase" }, // purchase.

                           };
			// loop over ordered items to add to stats
            foreach (DataRow row in ds.Tables["ShopOrderDetails"].Rows)
            {
                postData.Add("pr" + x.ToString() + "id", Convert.ToString(row["ProductRef"]));
                postData.Add("pr" + x.ToString() + "nm", Convert.ToString(row["ProductName"]));
                postData.Add("pr" + x.ToString() + "ca", "CategoryName");
                postData.Add("pr" + x.ToString() + "br", "BrandName");
                postData.Add("pr" + x.ToString() + "va", "");
                postData.Add("pr" + x.ToString() + "ps", x.ToString());

                x++;
            }
            //  

            var postDataString = postData
                .Aggregate("", (data, next) => string.Format("{0}&{1}={2}", data, next.Key,
                                                             HttpUtility.UrlEncode(next.Value)))
                .TrimEnd('&');

            // set the Content-Length header to the correct value
            request.ContentLength = Encoding.UTF8.GetByteCount(postDataString);

            // write the request body to the request
            using (var writer = new StreamWriter(request.GetRequestStream()))
            {
                writer.Write(postDataString);
            }

            try
            {
                var webResponse = (HttpWebResponse)request.GetResponse();
                // Response.Write(webResponse.StatusCode);
                if (webResponse.StatusCode != HttpStatusCode.OK)
                {
                    throw new HttpException((int)webResponse.StatusCode,
                                            "Google Analytics tracking did not return OK 200");

                }
                webResponse.Close();
            }
            catch (Exception ex)
            {
                DoLog(ex.ToString());
            }
        }
        catch (Exception ex)
        {
            DoLog(ex.ToString());
           
        }