Marketing is Broken: The Problem With Promo Codes

The promo code is one of the most commonly-used forms of measuring marketing effectiveness, but it's not a silver bullet and has lots of issues.

Marketing is Broken: The Problem With Promo Codes
Photo by Mark Kรถnig / Unsplash

Ah, the promo code. One of the simpliest forms of marketing "attribution" that exists and perhaps the most commonly-used form of measuring marketing "effectiveness" in verticals like ecommerce.

Like most singular forms of attribution, the promo code is no silver bullet. In fact, heavily or solely relying on it introduces a lot of issues. Let's dive in.

๐Ÿคฆ The Most Extreme Form of Last-Touch Attribution โš ๏ธ

I'll start with a story. When I was working at one company, that company โ€“ and its competitors โ€“ distributed promo codes continually. Those promo codes had slight discounts on product subscriptions and their main purpose was for tracking the effectiveness of marketing โ€“ so much so that the company was willing to sacrifice margin to "know" the last referral source.

The logic was simple. The company created promo codes, distributed them and then had a table with a column that said, "This promo code is tied to this referral source."

Anything without a promo code was considered as being referred or influenced by the brand or brand marketing. And, as I noted, all their competitors adopted a similar tactic.

It's OK to use promo codes, but this should not be the reason why.

In marketing, you'll often hear about last-touch or last-click attribution, e.g., the last click's referral source before a conversion is captured as the only driver for a conversion (or, at least, gets the bulk of credit). Well, promo codes go one step beyond that and are the most extreme form of last touch attribution.

Why? For a substantial chunk of customers, as soon as they see that promo code box on your website, they're going to:

  • Use a browser extension like Honey or Rakuten to auto-fill that form field with as many promo codes as possible until the greatest (or any) discount is triggered. (This is why products like cleanCart were made โ€“ to block injections of promo codes.)
  • Be prompted to do a search for "{{Brand name}} promo codes".

Regardless of the source of the converting session โ€“ it could be Google or Facebook Ads, direct or organic search โ€“ the promo code not only steals attribution, but also (potential) margin, too.

๐Ÿ“ˆ Promo Codes Tend to Overvalue Direct Response Channels ๐Ÿ“ฎ

It's very common to see brands gauge success of marketing efforts by querying which promo codes are used most often. And due to that incorrect alignment on a success KPI, channels like direct mail and email, where the promo code is physically seen, scanned or embedded in a URL, get more credit than channels like display, linear TV, radio, Meta, podcasts, etc., where the person is exposed to the marketing, but either the promo code is not available or is not remembered by the potential customer.

Often this deficit of promo code-based tracking in that last bucket of channels (like radio and podcasts) is "corrected" by repeatedly saying the promo code or a vanity URL specific to a campaign or sponsor. ย 

The true way to tease out if single channels or omnichannel approaches are driving incremental, say, revenue, regardless of promo code or vanity URLs used? Do treated and control cells like this:

Control Treated Cell #1 Treated Cell #2 Treated Cell #3
No Marketing Direct Mail Linear TV Direct Mail + Linear TV

By using a test-and-control setup like above, you can not only tease out the lift and incrementality of no marketing vs. marketing (and layering channels or tactics), but also if see if you have promo code leakage (attribution and margin robbery) between cells and if additional touches and frequencies improve your KPI(s).

What's more actionable? Knowing where to put your marketing efforts (and dollars) or getting a potential false read on attribution by only relying on promo codes?

For example, at an agency I worked at, it was very common that if we did priming of our eventual direct mail audience with some form of digital advertising, then sent direct mail and further followed up with more digital for about a week โ€“ while maintaining at least 5x frequency on digital โ€“ we'd see a lift of 25+% in direct mail + digital vs. direct mail-only cells โ€“ and we didn't have to get lost in conversations about promo code redemptions.

๐Ÿช„ They Give The Illusion of Accurate Measurement ๐Ÿ“Š

In both sections I already touched on this, but it bears repeating and warrants additional emphasis: promo codes should not be your single source of truth for marketing attribution and effectiveness, nor be the main (or only) factor in doing your media-mix planning or allocation.

Querying promo codes does not actually tell me if a channel's campaign (or the channel itself) drove incrementality of a KPI โ€“ rather, it's merely one signal (among many) of a user's journey, which may or may not be correct.

And if you keep going down the attribution rabbit hole of trusting the promo codes 100%, then you end up planning your media mix in a way to get the most promo code redemptions possible โ€“ not the most revenue, conversions or relevant KPIs.

Promo codes are especially problematic for planning marketing investments โ€“ like paid media mix โ€“ as they reduce attribution down to the last touch and give little-to-no insight into incrementality.

Promo codes are a particular issue for influencer or affiliate marketing, as payouts are either done by brands on cookie capture, click parameters or the promo code itself, but if promo codes are being shared widely, it doesn't actually tell me that the affiliate drove a sale and you may end up relying on certain affiliates too much or over-investing in affiliates.

Also, to the example above, you may fall victim to cookie stuffing, a process where affiliates and fraudsters direct as much traffic as possible to your site in the hopes that sheer volume of traffic tagged will result in sales and then that sale will be tied an affiliate's cookie for a payout. Rocky Moss at DeepSee has an excellent explainer article on the subject.

If you're still relying on promo codes for attribution, here are some things you can do to get a better analytical lay of that land.

๐Ÿ” Track Pasted vs. Typed Promo Codes ๐Ÿ“Š

The way this works is you setup an JavaScript event listener for a clipboard paste event in promo code form field. You then compare the number of converting and non-converting sessions and users that typed a promo code vs. pasted it.

We can do this quite easily by piggy-backing on a modified version of Simo Ahava's custom HTML event listener tag in your tag manager:

<script> 
    (function() { 
    var eventName = 'paste'; 
                 
     // Attach listener directly to form field for promo codes. 
     var el = document.querySelector('form#textInput-0') || document; 
     
     var useCapture = true; 
     el.addEventListener(eventName, 
     {{JS - Generic Event callback}}, useCapture); })(); 
</script>

After that, implement Simo's {{JS - Generic Event callback}} variable, set up your trigger and then send your paste event when the trigger is satisfied.

Comparing the promo code submitted vs. the actual referral source(s) is a good way to see the promo code's campaign or channel was the only factor in a conversion. You can use a cookie to reconstruct a user-level journey.

For example, this table shows you what you may see querying only a promo code vs. the quick hack we're going to implement:

Promo Code Only Referral-Tracking Cookie
Affiliate A Google Ads>Direct>Facebook Ads>Affiliate A

The initial steps are:

  • Create variables for all query parameters you want to track. Common ones are utm_source, utm_medium, msclid (for Bing Ads) and gclid (for Google Ads). You can see in the code below the first step is to check the document.referrer property to verify the referring domain and append it if our other criteria is not satisfied. ย 
  • Set up page view triggers for whether conditions you just set up are present, e.g., a page view tag for where {{URL - gclid}} does not equal undefined.
  • The most important page view trigger is one to filter out pages on your own website as you donโ€™t want each page on the website to clog up the journey youโ€™re about to construct โ€“ use the logic of {{Referrer}} does not contain yourdomain.com.

Leveraging various cookie scripts from Analytics Mania, we can create our cookie as a variable:

<script> 
//get referrer info and shorten it
  var ref = {{Referrer}}
  function extractDomain(url) {
    var domain;
    //find & remove protocol (http, ftp, etc.) and get domain
    if (url.indexOf("://") > -1) {
        domain = url.split('/')[2];
    }
    else {
        domain = url.split('/')[0];
    }

    //find & remove port number
    domain = domain.split(':')[0];

    return domain;
}
  ref = extractDomain(ref);
  
//create cookie  
 
    function createCookie(name,value,days) {
		if (days) {
		var date = new Date();
		date.setTime(date.getTime()+(days*24*60*60*1000));
		var expires = "; expires="+date.toGMTString();
		}
		else var expires = "";
		document.cookie = name+"="+value+expires+";
        path=/;domain=.yourdomain.com";
    }
  
  var cookie = "";
  //check if the source cookie is already present and append >
  if({{Cookie - Source}}){cookie = {{Cookie - Source}} + ">"};
  
  //check if msclkid is present and set cookie content to Bing Ads
  if({{URL - msclkid}}){
    createCookie("source",cookie+"Bing Ads",1000)
  //check if utm_source=paidsocial and set cookie content to Facebook Ads  
  }else if({{URL - UTM Campaign Medium}} == "paidsocial"){
    createCookie("source",cookie+"Facebook Ads",1000)
  //check if utm_source is present and set cookie content to the source utm
  }else if({{URL - UTM Campaign Source}}){
  createCookie("source",cookie+{{URL - UTM Campaign Source}},1000)
  //check if gclid is present and set cookie content to Google Ads
  }else if({{URL - gclid}}){
    createCookie("source",cookie+"Google Ads",1000)
  //check if referrer is present and set cookie content to the referrer
  }else if({{Referrer}}){
    createCookie("source",cookie+{{Referrer}},1000)
  //check if referrer is empty, null or undefined and set cookie content to direct
  }else if({{Referrer}} == ""){
    createCookie("source",cookie+"Direct",1000)
  };
  </script>

That's it! You can fire an event to capture the values when a user converts and pass it as a user-level custom dimension to query later.

๐Ÿ›‘ Fixing Overreliance on Promo Codes โœ…

Please, if you're in ecommerce, stop doing things like this:

Margin: Here today, gone in three seconds.โ€Œ

The example above is super common. It was my first visit to this website and in three, yes, three seconds, I was offered a 20% off promo code. I barely have time to see what's available, browse around or learn more about the brand, and they're already giving away margin.

The only excuse for something like you see above is if well-done A/B tests have been run to show that sacrificing margin hurts overall revenue less than lower or no discounts, or that losing that initial margin, but getting that email signup, leads to higher LTV (vs. no promo code or getting email signups later, e.g., post order).

Promo codes are a valid way of measuring some marketing efforts, but they must be balanced against results of structured tests, qualitative feedback, e.g., is the promo code value different from the customer-supplied, "How did you hear about us?" value, and efforts like multi-touch attribution (MTA) and marketing mix modeling (MMM).