Prerequiste:
Make sure your SynXis configuration Content-Security Policy allows *.shopmy.us. This can be done under Manage Settings > Allow Domains then adding a new domain.
Step One: Add click tracking to marketing website
If adding directly onto the website, place it just before the closing tag. If adding through Google Tag Manager then add this tag to trigger on every page view of the hotel website:
<script
async
src="https://static.shopmy.us/Affiliates/sms_aff_clicktrack.js?expires=30&splitcookies=1&decoratehosts=be.synxis.com"
></script>Step 2: Add the click tracker to SynXis in GTM
- In Google Tag Manager
- Title the tag "Shop My Shelf Click Tracking"
- Set the Tag Type to Custom HTML
- Set the HTML to the script provided below.
- Set the Triggering field to Fire on a "Page View" on "All Pages"
- Press Save
<script
async
src="https://static.shopmy.us/Affiliates/sms_aff_clicktrack.js?expires=30&splitcookies=1"
></script>Step 3: Add the order confirmation script
- Create a new Custom HTML tag in the SynXis tag manager to trigger on order confirmation.
- Paste the provided code below without editing it.
- Set the tag to trigger on order confirmation.
- Press Save
<script>
/*
Order confirmation pixel for hotels on the SynXis Booking Engine (SBE).
*/
(function() {
var POLL_INTERVAL_MS = 1000;
var POLL_TIMEOUT_MS = 30000;
var reported = false;
var requestInFlight = false;
function toIsoDate(raw) {
if (!raw) return null;
var str = String(raw);
if (/^\d{4}-\d{2}-\d{2}/.test(str)) return str.slice(0, 10);
var mdy = str.match(/^(\d{1,2})\/(\d{1,2})\/(\d{4})$/);
if (mdy) return mdy[3] + '-' + ('0' + mdy[1]).slice(-2) + '-' + ('0' + mdy[2]).slice(-2);
return null;
}
function reportOrderIfConfirmed() {
if (reported || requestInFlight) return;
var globalTracking = window._globalTracking || {};
var cartReservation = (globalTracking.Cart && globalTracking.Cart[0]) || {};
var confirmedReservation = (globalTracking.ConfirmedReservations && globalTracking.ConfirmedReservations[0]) || {};
var reservation = cartReservation.ConfirmNo ? cartReservation : confirmedReservation;
var hotelId = String(globalTracking.HOTEL_ID || (window.location.search.match(/[?&]hotel=([^&]+)/i) || [])[1] || '');
var orderAmount = globalTracking.TotalCost || reservation.TotalCost;
if (!hotelId || !reservation.ConfirmNo || !orderAmount) return;
var cookies = {};
var cookiesList = document.cookie.split(';');
for (var i = 0; i < cookiesList.length; i++) {
if (cookiesList[i]) {
cookies[(cookiesList[i].split('=')[0] || '').trim()] = (cookiesList[i].split('=')[1] || '').trim();
}
}
var clickId = cookies['sms_click_id_' + hotelId];
if (!clickId) {
try { clickId = sessionStorage.getItem('sms_click_id_' + hotelId); } catch (_e) { /* blocked */ } // eslint-disable-line no-unused-vars
}
var payload = {
orderAmount: orderAmount,
orderId: reservation.ConfirmNo,
currency: reservation.CurrCode || globalTracking.CurrCode || 'USD',
is_returning_customer: false,
page_url: window.location.href,
propertyId: hotelId,
returnWindowClosesAt: toIsoDate(reservation.ArrivalDt || globalTracking.ArrivalDt)
};
if (clickId) payload.clickId = clickId;
requestInFlight = true;
fetch('https://api.shopmy.us/api/order_confirmation', {
method: 'POST',
headers: {
'Content-Type': 'application/json'
},
body: JSON.stringify(payload)
})
.then(function(r) {
reported = true;
if (!r.ok) throw new Error('Invalid order request sent');
return r.json();
})
.then(function() {
var now = new Date();
document.cookie = 'sms_click_id_' + hotelId + '=;expires=' + now.toUTCString() + ';path=/;';
document.cookie = 'sms_click_time_' + hotelId + '=;expires=' + now.toUTCString() + ';path=/;';
try { sessionStorage.removeItem('sms_click_id_' + hotelId); } catch (_e) { /* blocked */ } // eslint-disable-line no-unused-vars
})
.catch(function(e) {
console.warn('ShopMy: order confirmation failed', e);
})
.then(function() {
requestInFlight = false;
});
}
try {
// The engine only shows a completed reservation on its /confirm route — skip every other
// page, and poll because the SPA populates _globalTracking after the page loads.
if (window.location.pathname.indexOf('/confirm') === -1) {
return;
}
reportOrderIfConfirmed();
if (!reported) {
var pollStartedAt = new Date().getTime();
var poll = setInterval(function() {
try {
if (new Date().getTime() - pollStartedAt >= POLL_TIMEOUT_MS) return clearInterval(poll);
reportOrderIfConfirmed();
if (reported) clearInterval(poll);
} catch (pollError) {
clearInterval(poll);
console.warn('We had an issue with the ShopMy order confirmation', pollError);
}
}, POLL_INTERVAL_MS);
}
} catch (error) {
console.warn('We had an issue with the ShopMy order confirmation', error);
}
})();
</script>Step 4: Publish changes
Whenever making changes to the Google Tag Manager scripts, make sure to press Publish at the top-right of the page.
