Adding Google Ads and Microsoft Advertising Conversion Tags to WooCommerce

Adding Google Ads and Microsoft Advertising conversion tracking tags to WooCommerce powered E-commerce shops can seem confusing at first: WooCommerce templates are like a huge Russian nesting doll and it’s unclear where to put the tags. On top of that Google wants their tags as close to the top of the document as possible, but many tutorials suggest using the woocommerce_thankyou hook, which dumps its output right in the middle of the body.

Use Any WordPress Hook

Luckily we can just use WordPress hooks to insert conversion tags where we need them, so long as we make sure we’re on the “Thanks for your order” page, and check that the order is a status that we want to count as a conversion. Here’s how we can do that:

/**
 * This function can be hooked onto any normal WordPress hook. Maybe wp_head,
 * or wp_footer, or even a sidebar if you really want.
 * @return [type] [description]
 */
function jb_do_stuff_on_order_complete_page() {
	// is_order_received_page() is part of WooCommerce
	// if there's a possibility that the page is loaded without WooCommerce
	// you could check to make sure it exists:
	if(!function_exists('is_order_received_page')) return;

	if(is_order_received_page()) {
		global $wp;
		$order = wc_get_order($wp->query_vars['order-received']);
		if($order && !$order->has_status( 'failed' )) {
			// Do what we need here.
		}
	}	
}

Set Up Conversion Tracking

Both Google and Microsoft have two parts to their tracking tag: a global tag that goes on every page of the website, (Microsoft calls this a UET tag, for “Universal Event Tracking“), and a conversion snippet. Both companies ask that that the global tag appears first in the document’s source. For Google this is because the gtag() function used by the conversion snippet is defined by the global tag.

Google Ads

Google really likes their global tag to be as high in the page’s source as possible – right after the opening <head> tag if possible. Because of this I often put the global tag right into header.php. A more portable solution is to use the wp_head hook so we’ll do that here:


function jb_set_up_google_tags() {

	// Start with the global tag.
?>
<script async src="https://www.googletagmanager.com/gtag/js?id=UA-XXXXXXX-1"></script>
<script>
  window.dataLayer = window.dataLayer || [];
  function gtag(){dataLayer.push(arguments);}
  gtag('js', new Date());
  gtag('config', 'UA-XXXXXXX-1');	// sets up Google Analytics - Google will give you the exact value
  gtag('config', 'AW-XXXXXXX');		// added for the conversion - Google will give you the exact value

  if (window.performance) {
    var timeSincePageLoad = Math.round(performance.now());
    gtag('event', 'timing_complete', {
      'name': 'load',
      'value': timeSincePageLoad,
      'event_category': 'JS Dependencies'
    });
  }
</script>
<?php

	// Add the conversion tag IF this is an Order Complete page.
	if(is_order_received_page()) {
		global $wp;
		$order = wc_get_order($wp->query_vars['order-received']);
		if($order && !$order->has_status( 'failed' )) {
?>		
<!-- Event snippet for Sales conversion page -->
<script>
  gtag('event', 'conversion', {
      'send_to': 'AW-XXXXXXX/XXXXXXXXX__XXXXX',		// Google will provide this value.
      'value': <?php echo $order->get_subtotal(); ?>,
      'currency': 'USD',							// Change you deal with a different currency. Or set it dynamically.
      'transaction_id': '<?php echo $order->get_order_number(); ?>'
  }); 
</script>
<?php
		}
	}
}

// Set priority 1 to appear as soon as possible in the wp_head.
add_action( 'wp_head', 'jb_set_up_google_tags', 1 );

Boom! That’s it for Google.

Microsoft Advertising

Microsoft advertising is very similar, except they seem to suggest that they want the conversion snippet before the closing </body> tag, and don’t seem to mind about the UET tag, so let’s just put them both in the wp_footer:

function jb_add_microsoft_advertising_tags() {

	// Start with the UET tag that goes on every page.
?>
<script>(function(w,d,t,r,u){var f,n,i;w[u]=w[u]||[],f=function(){var o={ti:"XXXXXXX"};o.q=w[u],w[u]=new UET(o),w[u].push("pageLoad")},n=d.createElement(t),n.src=r,n.async=1,n.onload=n.onreadystatechange=function(){var s=this.readyState;s&&s!=="loaded"&&s!=="complete"||(f(),n.onload=n.onreadystatechange=null)},i=d.getElementsByTagName(t)[0],i.parentNode.insertBefore(n,i)})(window,document,"script","//bat.bing.com/bat.js","uetq");</script>
<?php

	// Then add the conversion tag IF this is an Order Complete page.
	if(is_order_received_page()) {
		global $wp;
		$order = wc_get_order($wp->query_vars['order-received']);
		if($order && !$order->has_status( 'failed' )) {

			$order_info = [
				'revenue_value' => $order->get_subtotal(),
				'currency' => 'USD'
			];
?>
<script>
   window.uetq = window.uetq || [];
   window.uetq.push('event', '', <?php echo json_encode($order_info); ?>);  
</script>
<?php
		}
	} // end if this is an order received page.		

}
add_action( 'wp_footer', 'jb_add_microsoft_advertising_tags', 90 ); // Priority 90 to appear near the end.

Microsoft’s documentation on adding the conversion snippet is somewhat confusing. It talks about adding extra Javascript functions to supply the conversion value and doesn’t say what data type the conversion value should be, (let me know if you know). A Javascript function to extract the conversion value from the DOM might be a good idea when there’s no server-side access to the purchase data, but if you’re developing a WooCommerce theme or plugin you have the access you need to just print the conversion value in the tag with PHP, (as we did above).

Conclusion

That’s it. I heard that some people have trouble getting Bing working, (probably because of the extra-confusing directions from Microsoft), and I had trouble finding resources on adding conversion tags to the header for Google Ads. Hopefully this helps people with one, (or both), of the same questions.

Accidental Exclusion

I often listen to the Accidental Tech Podcast while washing dishes, and this week they had a discussion sparked in part by a tweet by John Siracusa about what they can do to get more women to listen to the show. One of the responses to John’s tweet discussed on the show is that the sponsor reads sometimes feel like they cater exclusively to men, and John and Marco discussed the merits of dropping sponsors that cater only to men vs. trying to modify the ad read in a way that it’s inclusive, even if the sponsor sells a male-focused product.

The discussion was mostly about Harry’s, a shaving company, and the most obviously male-oriented recurring sponsor of the show, and in the discussion Marco stated that he felt the script was pretty neutral, with the exact words “I don’t think the script is really the problem.” Because Marco seems like a considerate man who genuinely wants to include everyone I’m pointing out how last week’s seemingly-innocent sponsor read for Harry’s excludes women.

Numerous comparisons, in quality, price, and comfort, to the Fusion line of razors, suggesting the style is Mad Men-inspired, and, and the statement that Harry’s “was started by two guys who wanted a better product” leave no doubt that these are razors being made for men, not women. Saying that the blades provide “a better shave that respects your face” leaves little doubt that Marco is speaking to the men in the audience, not the women.

The short phrase “respects your face” excludes women. If it read “a better shave that respects your skin” or “a better shave that respects the face” then women would not be excluded. John suggests going even further and trying to include women, but the point of this post is to show how easy it is to exclude a group without even realizing it.

Does anyone use PayPal integration in Appointment Booking WordPress Plugins?

I’m working on my own branch of an appointment booking plugin for WordPress for a client site. It works great, but there’s more to do.

The original plugin has an option to require payment via PayPal when someone books an appointment. I want to know if people use this feature.

For those of you who use a plugin to accept appointment bookings through your WordPress site, (or one you develop), do you use PayPal integration to accept payment for those appointments?

Bonus Questions: Do you use some other payment provider to accept payments for appointments? Which appointment booking plugin do you use?

Please leave a comment below, or E-mail me via my contact form.

Thanks!

Demoing Drape: a Multiple URL Shortener

One of the projects that I’ve been involved with has a new product out: Drape. Drape is a multiple URL shortener, and I’ve prepared a demo. Here’s a drape that I created of some interesting blogs about living with less impact on the planet.

And, here’s what the cut & paste button looks like:

Interesting Living on the way to Living Green

Switching to an External DNS Provider

The other day I discovered, and tweeted, that Bell Canada, my ISP, has started doing DNS Redirection.  That is, if I try to visit a domain that does not exist, they send me to a page of search results for whatever I typed.  This can be considered convenient, but it is kind of like connecting you to 411 if you misdial a telephone number – not exactly what I want.  Bell offers an “opt-out”, but despite the name it it’s not an opt-out.  They simply set a cookie in your browser that redirects you to yet another webpage that they attempted to make look like the error page from your browser, (and failed).

This wouldn’t really be a problem if I wasn’t developing a program for BonzoBox right now that checks to see if user-entered URLs really exist.  All of the sudden I can’t test my work because no matter what domain name a URL starts with, it resolves, and returns a 200 status code to boot!  This will not do.

I needed a new DNS provider, however, who do you trust?  I tried out OpenDNS, but they do the same thing as Bell just started doing, (except, they’ve been doing it for a while, maybe always, and they’re up front about it).  I read about how Level3 has great DNS servers, but if you look at level3.com it doesn’t mention it anywhere, (it’s not exactly what they’re known for).

I did run across some Level3 DNS Server addresses on DSLReports.com, but are they really Level3’s servers, or are they some hacker’s servers that has seeded the forum with some bogus info in order to capture my banking info?  Well, a whois lookup told me that they do belong to Level3, so my new DNS servers are now 4.2.2.1 – 4.2.2.4.  They’re even easy to type!

FYI:  This does not appear to be a paid service from Level3, but if it was, it is something that I would be willing to pay a few dollars a year for.

Bell, on the other hand, is barely hanging on to my business.  The only reasons I am still with them is 1) I am too lazy to research the alternatives, and 2) I have an old account with no monthly bandwidth cap.  If I can find another service that is reliable and has no bandwidth cap, I may very well consider switching.