This guide outlines the procedure for integrating Retention.com scripts into a WooCommerce setup within WordPress. The integration facilitates capturing identity, specific user interactions, and order details within the platform.
The R! code snippet includes several functions:
We’ve provided guidance on adding the full script with all functions (recommended) as well as breakdowns for how each function is created in the event you want to make your own edits.
WooCommerce Hooks: https://woocommerce.com/document/introduction-to-hooks-actions-and-filters/
Get these values from your Retention.com Implementation Manager - they are used in the code below.
Please note that the value shown in the screenshot is just a placeholder, you will need to get your unique identifier from your Implementation Manager.
Retention.com’s Script is is added as a Snippet in WordPress Admin view as follows:
Code: Retention Code Snippet (Complete Version) - found below
Confirmation: You should see something like this on the Snippet page when complete.
The following represents the code required for setting up Retention.com with WooCommerce that you can copy and paste into WooCommerce. Copying all of the code in this section into WooCommerce will result in enabling all of Retention’s script functionality. However, your scripts will not go live until your Implementation Manager signs off on your implementation phase.
NOTE: Anything below highlighted in yellow requires updates based on your specific set-up. Keep an eye out for the following sections in the document below:
//Get this from your dedicated Implementation Manager
NOTE: Once the script has been installed and tested on your website, we advise removing the console.log commands.
function geq_script_function() {
echo "<script type='text/javascript'>!function(){var geq=window.geq=window.geq||[];if(geq.initialize||geq.invoked){if(window.console)console.error('GE snippet included twice.');return;}
//Get this from your dedicated Implementation Manager
var retention_account_id ='**GET FROM Implementation Manager**';
geq.invoked=true;var methods=['page','suppress','trackOrder','identify','addToCart','callBack','event'];for(var i=0;i<methods.length;i++){var key=methods[i];geq[key]=function(method){return function(){var args=Array.prototype.slice.call(arguments);args.unshift(method);geq.push(args);return geq;};}(key);}geq.load=function(key){var script=document.createElement('script');script.type='text/javascript';script.async=true;script.src='https://s3-us-west-2.amazonaws.com/jsstore/a/'+key+'/ge.js'+(location.href.includes('vge=true')?'?v='+Math.random():'');var firstScript=document.getElementsByTagName('script')[0];firstScript.parentNode.insertBefore(script,firstScript);};
//Get this from your EPIP Implementation Manager
geq.SNIPPET_VERSION='1.6.1';
geq.load(retention_account_id);}();</script>";
echo "<script>geq.page()</script>";
}
add_action('wp_head', 'geq_script_function');
function my_enqueue_scripts() {
wp_enqueue_script('my-ajax-handle', get_template_directory_uri().'/js/myscript.js', array('jquery'), null, true);
wp_localize_script('my-ajax-handle', 'the_ajax_script', array('ajaxurl'=>admin_url('admin-ajax.php')));
}
add_action('wp_enqueue_scripts', 'my_enqueue_scripts');
function geq_atc_button_listeners_function() {
echo '<script>if (window.location.href.includes("vge=true")) {console.log("Triggered geq_atc_button_listeners_function");}</script>';
// Script to handle ATC button event listeners
$atcScriptListeners = "
<script type='text/javascript'>
// Check if 'vpitem' is defined; otherwise, try using 'item' or define a new one.
var atc_item = typeof vpitem !== 'undefined' ? vpitem : (typeof item !== 'undefined' ? item : {});
// Check if 'item' has a 'Name' property; if not, try to set it if 'Title' exists.
if (!atc_item.hasOwnProperty('Name')) {
if (atc_item.hasOwnProperty('Title')) { // Assuming 'Title' is the relevant property.
atc_item.Name = atc_item.Title;
if (window.location.href.includes('vge=true')) {console.log('The item uses Title property');}
} else {
// Handle the case when neither 'Name' nor 'Title' property exists.
if (window.location.href.includes('vge=true')) {console.error('The item does not have a Name or Title property. This may result in an issue.');}
}}
var classNames = ['single_add_to_cart_button', 'add_to_cart_button'];
classNames.forEach(function(className) {
var atcButtons = document.getElementsByClassName(className);
if (atcButtons && atcButtons.length > 0) {
for (var i = 0; i < atcButtons.length; i++) {
atcButtons[i].addEventListener('click', function() {
if (atc_item && Object.keys(atc_item).length > 0) {
console.log('Add To Cart Reclaim', atc_item);
geq.addToCart(atc_item);
} else {
if (window.location.href.includes('vge=true')) {console.log('HAS NO item for Add To Cart Reclaim - Getting Last Cart Item');}
// Calling the PHP function via AJAX
var data = {'action': 'geq_atc_from_cart_action'};
// the_ajax_script.ajaxurl is a variable that will contain the URL to the ajax processing file in the WordPress backend.
//console.log('Calling the server');
$.post(the_ajax_script.ajaxurl, data, function(response) {
//console.log('Got this from the server: ' + response);
// Create a script tag and set its HTML to the response text
var script = document.createElement('script');
script.type = 'text/javascript';
script.innerHTML = response; // Assuming 'response' is the JavaScript code you received
// Append the script to the DOM so it gets executed
document.body.appendChild(script);
});}});}
} else {if (window.location.href.includes('vge=true')) {console.error('No Add To Cart buttons found for class ' + className);}}
});
</script>";
echo $atcScriptListeners;
}
add_action('wp_footer', 'geq_atc_button_listeners_function');
function viewed_product_reclaim() {
global $product;
echo '<script>if (window.location.href.includes("vge=true")) {console.log("Triggered viewed_product_reclaim --> $product",'. json_encode($product) .');}</script>';
// Check if the global product object is set
if (isset($product) && is_object($product)) {
// Fetch product details
$product_id = $product->get_id();
$product_name = $product->get_name();
$product_brand = $product->get_attribute('brand'); // Assuming 'brand' is your attribute for brands
$product_price = $product->get_price();
$product_image = wp_get_attachment_image_url($product->get_image_id(), 'full');
$product_categories = wp_get_post_terms($product_id, 'product_cat', array('fields' => 'names')); // Get product categories
if (!empty($product_categories) && is_array($product_categories)) {
$first_category = $product_categories[0]; // Get the first category
}
// Prepare the script with product details
$vpScript = "<script type='text/javascript'>
if (window.location.href.includes('vge=true')) {
console.log('Viewed Product ID: {$product_id}');
}
var vpitem = {
Name: " . json_encode($product_name) . ",
Price: " . json_encode($product_price) . ",
ProductID: " . json_encode($product_id) . ",
Categories: " . json_encode($first_category) . ",
ImageURL: " . json_encode($product_image) . ",
URL: window.location.href,
Brand: " . json_encode($product_brand) . "
};
if (window.location.href.includes('vge=true')) {
console.log('Viewed Product Reclaim', vpitem);
}
// Trigger the event with the product data
if (typeof geq !== 'undefined' && typeof geq.event === 'function') {
geq.event('Viewed Product Reclaim', vpitem);
}
</script>";
echo $vpScript;
} else {
echo '<script>if (window.location.href.includes("vge=true")) {console.log("Global product object is not set.");}</script>';
}
}
add_action('woocommerce_after_single_product', 'viewed_product_reclaim');
function geq_atc_from_cart_function() {
//echo '<script>if (window.location.href.includes("vge=true")) {console.log("Triggered geq_atc_from_cart_function");}</script>';
// Get the last item added to the cart
$cart = WC()->cart->get_cart();
$cart_items = array_reverse($cart);
$latest_cart_item = reset($cart_items); // Gets the first item from the reversed array, which is the latest item added to cart
$latest_atc_product = isset($latest_cart_item['data']) ? $latest_cart_item['data'] : null;
// Check if the product object is set
if ($latest_atc_product && is_object($latest_atc_product)) {
// Fetch product details
$product_id = $latest_atc_product->get_id();
$product_name = $latest_atc_product->get_name();
$product_brand = $latest_atc_product->get_attribute('brand');
$product_price = $latest_atc_product->get_price();
$product_image = wp_get_attachment_image_url($latest_atc_product->get_image_id(), 'full');
$product_categories = wp_get_post_terms($product_id, 'product_cat', array('fields' => 'names'));
$first_category = !empty($product_categories) && is_array($product_categories) ? $product_categories[0] : '';
// Prepare the script with product details
$atcScript = "var atcitem = {
Name: " . json_encode($product_name) . ",
Price: " . json_encode($product_price) . ",
ProductID: " . json_encode($product_id) . ",
Categories: " . json_encode($first_category) . ",
ImageURL: " . json_encode($product_image) . ",
URL: window.location.href,
Brand: " . json_encode($product_brand) . "
};
if (window.location.href.includes('vge=true')) {
console.log('Add To Cart Item:', atcitem);
}
// Trigger the addToCart event with the latest product data
if (typeof geq !== 'undefined' && typeof geq.addToCart === 'function') {
geq.addToCart(atcitem);
}";
echo $atcScript;
} else {}
wp_die();
}
add_action('wp_ajax_geq_atc_from_cart_action', 'geq_atc_from_cart_function');
add_action('wp_ajax_nopriv_geq_atc_from_cart_action', 'geq_atc_from_cart_function');
function geq_track_order_function($order_id) {
$georder = wc_get_order($order_id);
// Check if the order object exists and is an instance of WC_Order
if (!($georder instanceof WC_Order)) {
return;
}
// Retrieve order details with error checking
$order_details = [
'order_number' => $georder->get_order_number(),
'order_amount' => $georder->get_total(),
'order_email' => $georder->get_billing_email(),
];
// Check for missing order details
if (in_array(null, $order_details, true)) {
return;
}
// Embed the JavaScript for order tracking
$order_json = json_encode($order_details);
echo "<script type='text/javascript'>
geq.trackOrder($order_json);
if (window.location.href.includes('vge=true')) {
console.log('Triggered geq_track_order_function with order ID: $order_id');
console.log('Called geq.trackOrder:', $order_json);
}
</script>";
}
// Hook the function to run after an order is placed
add_action('woocommerce_thankyou', 'geq_track_order_function');
NOTE: Anything below highlighted in yellow requires updates based on your specific set-up. Keep an eye out for the following sections in the document below:
//Get this from your dedicated Implementation Manager
Here, we create a new function, geq_script_function
, to house the new script. This function needs to run on every page you want Retention.com’s services to operate. The rest of the functions require this section in order to operate.
This function is triggered by the hook: wp_head. This Hook runs on every page and inserts the following code snippet into the header section. Note that this will not affect your website performance.
function geq_script_function() {
echo "<script type='text/javascript'>!function(){var geq=window.geq=window.geq||[];if(geq.initialize||geq.invoked){if(window.console)console.error('GE snippet included twice.');return;}
//Get this from your dedicated Implementation Manager
var retention_account_id ='FROM R!';
geq.invoked=true;var methods=['page','suppress','trackOrder','identify','addToCart','callBack','event'];for(var i=0;i<methods.length;i++){var key=methods[i];geq[key]=function(method){return function(){var args=Array.prototype.slice.call(arguments);args.unshift(method);geq.push(args);return geq;};}(key);}geq.load=function(key){var script=document.createElement('script');script.type='text/javascript';script.async=true;script.src='https://s3-us-west-2.amazonaws.com/jsstore/a/'+key+'/ge.js'+(location.href.includes('vge=true')?'?v='+Math.random():'');var firstScript=document.getElementsByTagName('script')[0];firstScript.parentNode.insertBefore(script,firstScript);};
//Get this from your EPIP Implementation Manager
geq.SNIPPET_VERSION='1.6.1';
geq.load(retention_account_id);}();</script>";
echo "<script>geq.page()</script>";
}
add_action('wp_head', 'geq_script_function');
function my_enqueue_scripts() {
wp_enqueue_script('my-ajax-handle', get_template_directory_uri().'/js/myscript.js', array('jquery'), null, true);
wp_localize_script('my-ajax-handle', 'the_ajax_script', array('ajaxurl'=>admin_url('admin-ajax.php')));
}
add_action('wp_enqueue_scripts', 'my_enqueue_scripts');
function viewed_product_reclaim() {
global $product;
echo '<script>if (window.location.href.includes("vge=true")) {console.log("Triggered viewed_product_reclaim --> $product",'. json_encode($product) .');}</script>';
// Check if the global product object is set
if (isset($product) && is_object($product)) {
// Fetch product details
$product_id = $product->get_id();
$product_name = $product->get_name();
$product_brand = $product->get_attribute('brand'); // Assuming 'brand' is your attribute for brands
$product_price = $product->get_price();
$product_image = wp_get_attachment_image_url($product->get_image_id(), 'full');
$product_categories = wp_get_post_terms($product_id, 'product_cat', array('fields' => 'names')); // Get product categories
if (!empty($product_categories) && is_array($product_categories)) {
$first_category = $product_categories[0]; // Get the first category
}
// Prepare the script with product details
$vpScript = "<script type='text/javascript'>
if (window.location.href.includes('vge=true')) {
console.log('Viewed Product ID: {$product_id}');
}
var vpitem = {
Name: " . json_encode($product_name) . ",
Price: " . json_encode($product_price) . ",
ProductID: " . json_encode($product_id) . ",
Categories: " . json_encode($first_category) . ",
ImageURL: " . json_encode($product_image) . ",
URL: window.location.href,
Brand: " . json_encode($product_brand) . "
};
if (window.location.href.includes('vge=true')) {
console.log('Viewed Product Reclaim', vpitem);
}
// Trigger the event with the product data
if (typeof geq !== 'undefined' && typeof geq.event === 'function') {
geq.event('Viewed Product Reclaim', vpitem);
}
</script>";
echo $vpScript;
} else {
echo '<script>if (window.location.href.includes("vge=true")) {console.log("Global product object is not set.");}</script>';
}
}
add_action('woocommerce_after_single_product', 'viewed_product_reclaim');
function geq_atc_button_listeners_function() {
echo '<script>if (window.location.href.includes("vge=true")) {console.log("Triggered geq_atc_button_listeners_function");}</script>';
// Script to handle ATC button event listeners
$atcScriptListeners = "
<script type='text/javascript'>
var classNames = ['single_add_to_cart_button', 'add_to_cart_button'];
// Check if 'vpitem' is defined; otherwise, try using 'item' or define a new one.
var atc_item = typeof vpitem !== 'undefined' ? vpitem : (typeof item !== 'undefined' ? item : {});
// Check if 'item' has a 'Name' property; if not, try to set it if 'Title' exists.
if (!atc_item.hasOwnProperty('Name')) {
if (atc_item.hasOwnProperty('Title')) { // Assuming 'Title' is the relevant property.
atc_item.Name = atc_item.Title;
if (window.location.href.includes('vge=true')) {console.log('The item uses Title property');}
} else {
// Handle the case when neither 'Name' nor 'Title' property exists.
if (window.location.href.includes('vge=true')) {console.error('The item does not have a Name or Title property. This may result in an issue.');}
}}
classNames.forEach(function(className) {
var atcButtons = document.getElementsByClassName(className);
if (atcButtons && atcButtons.length > 0) {
for (var i = 0; i < atcButtons.length; i++) {
atcButtons[i].addEventListener('click', function() {
if (atc_item && Object.keys(atc_item).length > 0) {
console.log('Add To Cart Reclaim', atc_item);
geq.addToCart(atc_item);
} else {
if (window.location.href.includes('vge=true')) {console.log('HAS NO item for Add To Cart Reclaim - Getting Last Cart Item');}
// Calling the PHP function via AJAX
var data = {'action': 'geq_atc_from_cart_action'};
// the_ajax_script.ajaxurl is a variable that will contain the URL to the ajax processing file in the WordPress backend.
//console.log('Calling the server');
$.post(the_ajax_script.ajaxurl, data, function(response) {
//console.log('Got this from the server: ' + response);
// Create a script tag and set its HTML to the response text
var script = document.createElement('script');
script.type = 'text/javascript';
script.innerHTML = response; // Assuming 'response' is the JavaScript code you received
// Append the script to the DOM so it gets executed
document.body.appendChild(script);
});}});}
} else {if (window.location.href.includes('vge=true')) {console.error('No Add To Cart buttons found for class ' + className);}}
});
</script>";
echo $atcScriptListeners;
}
add_action('wp_footer', 'geq_atc_button_listeners_function');
function geq_atc_from_cart_function() {
//echo '<script>if (window.location.href.includes("vge=true")) {console.log("Triggered geq_atc_from_cart_function");}</script>';
// Get the last item added to the cart
$cart = WC()->cart->get_cart();
$cart_items = array_reverse($cart);
$latest_cart_item = reset($cart_items); // Gets the first item from the reversed array, which is the latest item added to cart
$latest_atc_product = isset($latest_cart_item['data']) ? $latest_cart_item['data'] : null;
// Check if the product object is set
if ($latest_atc_product && is_object($latest_atc_product)) {
// Fetch product details
$product_id = $latest_atc_product->get_id();
$product_name = $latest_atc_product->get_name();
$product_brand = $latest_atc_product->get_attribute('brand');
$product_price = $latest_atc_product->get_price();
$product_image = wp_get_attachment_image_url($latest_atc_product->get_image_id(), 'full');
$product_categories = wp_get_post_terms($product_id, 'product_cat', array('fields' => 'names'));
$first_category = !empty($product_categories) && is_array($product_categories) ? $product_categories[0] : '';
// Prepare the script with product details
$atcScript = "var atcitem = {
Name: " . json_encode($product_name) . ",
Price: " . json_encode($product_price) . ",
ProductID: " . json_encode($product_id) . ",
Categories: " . json_encode($first_category) . ",
ImageURL: " . json_encode($product_image) . ",
URL: window.location.href,
Brand: " . json_encode($product_brand) . "
};
if (window.location.href.includes('vge=true')) {
console.log('Add To Cart Item:', atcitem);
}
// Trigger the addToCart event with the latest product data
if (typeof geq !== 'undefined' && typeof geq.addToCart === 'function') {
geq.addToCart(atcitem);
}";
echo $atcScript;
} else {}
wp_die();
}
add_action('wp_ajax_geq_atc_from_cart_action', 'geq_atc_from_cart_function');
add_action('wp_ajax_nopriv_geq_atc_from_cart_action', 'geq_atc_from_cart_function');
function geq_track_order_function($order_id) {
$georder = wc_get_order($order_id);
// Check if the order object exists and is an instance of WC_Order
if (!($georder instanceof WC_Order)) {
return;
}
// Retrieve order details with error checking
$order_details = [
'order_number' => $georder->get_order_number(),
'order_amount' => $georder->get_total(),
'order_email' => $georder->get_billing_email(),
];
// Check for missing order details
if (in_array(null, $order_details, true)) {
return;
}
// Embed the JavaScript for order tracking
$order_json = json_encode($order_details);
echo "<script type='text/javascript'>
geq.trackOrder($order_json);
if (window.location.href.includes('vge=true')) {
console.log('Triggered geq_track_order_function with order ID: $order_id');
console.log('Called geq.trackOrder:', $order_json);
}
</script>";
}
// Hook the function to run after an order is placed
add_action('woocommerce_thankyou', 'geq_track_order_function');
General:
These scripts attempt to utilize the hook capabilities offered by WooCommerce, and are intended to be lightweight and perform well in the majority of scenarios. We understand that every website is unique and as such, variations may be required by your team.