If your online shop analytics stops with the order, it is stopping short. Some product groups like Fashion tend to have high return rates, so looking at refunds can give you a different view of your shop and marketing performance. At siroop.ch, a new Swiss online marketplace, we tried to look at what happens after the order in both Google and Adobe Analytics. While Google’s imports may require a bit less setup time, they have major limitations. Adobe Analytics’ Transaction ID Data Sources gave us the full picture from Campaign to Cancellation.
What are Refunds?
In this article, I refer to Refunds as orders that were fully or partially refunded – either the customer returned one or all products of an order (Returns) or the order was cancelled (Cancellations) due to fraud, inability to deliver the product, change of mind by the customer, “no” by the bank, or other reasons.
Refunds for Finance vs. Refunds for Web Analytics
When talking about these terms with your finance team, note that they may handle Cancellations differently from your Web Analytics tool. In the billing system, Cancellations usually do not even get booked as revenue in the first place – the orders are treated as if they never happened. So “Refunds” for finance are only those orders which were paid by the customer (revenue was booked) and which later had to be refunded, usually because the customer returned a product.
But as your Analytics tool “books” orders as revenue in the moment they are completed on the website, you have to “refund” these “bookings” even if they are, financially speaking, cancellations.
How to Implement Refund Tracking
First, you need an export from your shop system with all Order IDs (also called Transaction IDs), the same product IDs that you use in your Analytics tools, the purchase price per product (for some reason, Google Analytics needs that for the Refund Import), the refunded revenue and, if you want to be able to distinguish Cancellations and Returns, the “Refund Reason”.
Here an example of what such an export may look like:
Before importing these into Analytics tools, make sure that you only import the Order IDs that the Analytics tools were able to track because ad blockers usually block some Analytics requests. That, in our case, happens just slightly more often with Google (seemingly blocked more often) than Adobe data.
Enable Enhanced E-Commerce and track purchases on your site. There are a gazillion articles out there on how to do that, so I won’t go into it here.
Then transform the export from your shop system into the format required for the GA Refund Import Template, a simple little CSV that you can either upload manually or via the API (as we are doing at siroop).
The Google Analytics Help on Refund Imports is just hard to top, so let me just point out one thing we stumbled over in our first test imports: Unlike Cost Data, you cannot remove imported refund data afterwards! Adobe allows you to remove imported data by importing it again with a minus sign in front of all the metrics numbers (tedious, but at least possible).
1. Track Purchases on your site with the standard E-Commerce variables (s.products, s.purchaseID, the “purchase” event) PLUS s.transactionID (contains the Order ID that identifies the Order ID in your refund imports, usually the same as s.purchaseID).
2. Tell Customer Care to activate “Transaction ID Recording”. It takes a day or two to do that. This hidden feature is so powerful that it is hard to believe that is not more popular. It allows you to tie any online action tracked with s.transactionID to any other off-site action (e.g. a refund, a brick-and-mortar store purchase after an online lead, approved bank account openings after online lead forms etc.). We will see later what this means in detail.
After activation, you should see this text in your Data Sources start screen (go to „Admin -> Data Sources“):
Regarding the metrics and dimensions to use, as is often the case with Adobe Analytics, it does not prescribe much. You can theoretically import any metrics and dimensions you would like to. The GA Refund template instead tells you exactly what columns to import and in which format. But there is no way to add more columns (like to track the refund reason or another metric to separate returns from cancellations). In Adobe instead, the only mandatory field is the TransactionID itself. As flexible as this is, it requires you to think first what exactly you need and in which format it should be.
In our case, the templates we created to import looked more or less like the following:
The first three rows you can download after going through the Data Source Creation Wizard, the rows after that with the data you have to fill in yourself of course. 🙂
- Date: When the transaction happened (in format MM/DD/YYYY)
- Refund Reason: cancel or return
- Prod SKU: unique product identifier
- Refunded Revenue: Total sum refunded for this product (not sum per product!)
- Refunded Orders: counts whenever an order had at least one product returned or cancelled so we can have a “Refunded Orders” metric in Analytics. No product data (product quantity or revenue) data is reported for this metric because that would count them twice (you see that the rows where the Refunded Orders is counted have only the Date, the Transaction ID and the Refunded Orders columns filled). It is not necessary to have this metric. We just wanted something that allows us to get a metric that quickly tells us how many percent of orders are affected by refunds (like Google’s “Refunds” metric). One reason for this is that looking at product quantities alone can be harder to interpret because it has to do a lot with the way products tend to be bought: For example, people rarely buy one beer, they tend to buy a box with 20 or 24 bottles, thus the quantity is 24. But people rarely by 24 iPhones at once. So “Refunded Orders” “normalizes” this effect a bit, but therefore you cannot break it down by product-based dimensions like product name, category or brand.
- Refunded Units: refunded quantity per product
- Order ID: Transaction ID (mandatory)
On to the Analysis!
After importing, you can start analyzing.
In Google Analytics, the standard E-Commerce and Product Performance reports allow you to analyze performance by category, brand, or whatever Enhanced Ecommerce product-based dimension you have implemented. You can of course use the standard Refund Metrics in Custom Reports as well. I recommend building Calculated Metrics like the Refund Rates for Revenue, Quantity, and Orders (you have to do this for every view in Google Analytics and you are limited to 5 Calculated Metrics per View in the free GA). This screenshot shows the refunds per product category (all data in all screenshots blurred and faked for privacy):
In the screenshot, you already see one of the major limitations of the standard Refund Import of Google Analytics: It accrues the Refunds all on the date when they were imported, not when they actually happened or on the date of the order. So when we started importing refunds, we started by importing some minor refunds from March – those showed up in July, and all on one day (July 4th), because that’s when we imported them. As a result, the refund rate is wrong because it will compare July purchase data with March refund data. We thought we could easily delete wrong refund imports like with campaign cost data, but as I mentioned, that is not possible.
If you import the refund data daily, the problems will not be as grave, but you still have the issue that refunds can come into your system several weeks after the purchase. So if you want to know how much revenue of a given week in a category was later refunded, you are in quite a problem that is not solvable without major exporting and spreadsheet work.
The new Query Time Import (currently in beta for GA 360 (Premium) users) could solve this and the other limitations following below, but we will see. For this you would need to create your own metrics and dimensions like in Adobe’s Transaction ID Processing Report (or Google should make the standard refund import query-time-import compatible).
In Adobe Analytics, refunds are counted as if they had happened at the same time as the order. Maybe that sounds counterintuitive, but it is a huge advantage in terms of reporting:
- You can analyze orders and refunds in the same time range even if the refunds happened later
- You can correlate any data from the order session (e.g. Visitor data, Campaign data) with refund data, e.g. to analyze the refund rates per Marketing Channel. To understand what this means, let’s look at how Google Analytics handles it one final time: Here, the Traffic Source for a Refund is that Traffic Source of the Refund import, i.e. there is no Traffic Source (“not set”). Same goes for any other dimension (Browser, City, Login Status etc.). Take a glance at this:
First, we see Transaction IDs which, for the selected time, have no Transaction Revenue (the last 3 lines), but Refunded Revenue (the processing time issue mentioned above).
Second, they are all attributed to the Traffic Source “(direct) / (none)”, even though (as you can see in the following screenshot) Transaction ID 0004-3244 was actually referred by “google / cpc” (AdWords). So if both refund and transaction time fall into the analyzed time range, you get two rows per Transaction ID – one for the refund and one for the order. Not that nice. Needless to say, Refunds will not appear in any Traffic-Source-based reports, they also won’t appear in segmented reports etc.
In Adobe, we can use the refund metrics just like any other and break them down by any dimension or segment. For example, here we look at Refund Rates by Campaign Source and we see, that, for a given day and a given Campaign Source, the refund rate for “Return Customers” (Customers with at least 2 Orders) was higher than for “New Customers”. Maybe it is the free refunds that siroop.ch offers that makes people buy (and return) again. 🙂
- When analyzing marketing campaigns, you may be stopping short if you don’t take refunds into account. Create a “ROAS incl. Refunds” (ROAS = (Return on Ad Spend)) metric that is based not only on the Revenue, but on the Revenue after Refunds, so it shows what effectively remained in your pockets after all was said and done. See the last two columns in the following screenshot:
- Lastly, in Adobe it is easy to differentiate Returns from Cancellations. Because we import the “Refund Reason” as a dimension, we can create Calculated Metrics based on the value of this dimension (no way to do that in Google Analytics btw).
Example: How to build the “Return Rate” (proceed analogously for the Cancellation Rate):
1. Create a Hit-based Segment for “Return Hits” with just one condition: Refund Reason equals “return”
Don’t worry that the Data Preview on the top right says 0, that is actually correct as the Refunds did not happen in any online Visit nor did they generate a Page View.
2. Then create the Calculated Metric (in our example, the “Return Rate” in terms of Revenue). Here you take the segment you have just created, put the Refunded Revenue Success Event (Custom Metric) from your Data import inside of that segment and divide the output by the Revenue:
This allows something that is very useful for a marketplace like siroop: Instead of just looking at Refund Rates, we can look at individual merchants’ Return and Cancellation Rates. That way, we can identify merchants who often cancel orders (some may just say yes at first to get as many orders as possible and later cancel), and reach out to those who encounter a high return rate (because we might be attracting them to the wrong customers):
What are your experiences with Refund Tracking? What is the greatest challenge when implementing Refund Tracking or when analyzing them?