Follow the steps below to install the Serverside Hybrid Universal Integration script on your website.
The ProfitMetrics Serverside Hybrid Universal Integration is a universal integration which allows for ProfitMetrics to be implemented into any e-commerce platform that is not supported natively. The integration consists of two parts. Part 1 of the integration refers to the sending of orders to ProfitMetrics according to our documentation. Part 2 is to implement the tracking script to capture statistical and marketing-related tracking parameters from the browser and pair these with the orders.
Alternatively, you can set it up via Google Tag Manager.
How to install the Serverside Hybrid Universal Integration script in Google Tag Manager.
See this article if you haven't built your integration with ProfitMetrics yet: Sending orders to profitmetrics serverside
Part 1: Implement script on All pages
Part 2: Implement setEmail event to capture email when using a third-party checkout.
Part 3: Complete code for known CMP's
Part 3: Confirm the integration
Part 1: Implement script on All pages
When implementing the tracking script on your website it is important that you know which Consent Management Platform (CMP) you are using. ProfitMetrics script automatically supports the following platforms:
Supported Consent Management Platforms (CMP):
- Cookieinformation.com
- Cookiebot.com
- DanDomain / SmartWeb / ScanNet / WannaFind / HostedShop
-
Copy the following script and place it the <head></head> section of your website. Remember to replace PUBLIC_ID with your Public ID found in ProfitMetrics under Websites and replace .class-name as described in the next step.
<!-- Start ProfitMetrics - Script -->
<script>
window.profitMetrics = {
pid: 'PUBLIC_ID', // Your Public ID
}
</script>
<script src="https://cdn1.profitmetrics.io/PUBLIC_ID/bundle.js"
defer></script>
<!-- End ProfitMetrics - Script --> - The next step is to add the emailInputSelector field like this:
<!-- Start ProfitMetrics - Script -->
Replace ".class-name" with a comma-separated list of the CSS selectors of those email input fields. You can right-click and inspect the field or you can use a tool like Selector gadget to quickly click and identify the correct CSS selctor.
<script>
window.profitMetrics = {
pid: 'PUBLIC_ID', // Your Public ID
emailInputSelector: '.class-name', // Email input CCS selector
}
</script>
<script src="https://cdn1.profitmetrics.io/PUBLIC_ID/bundle.js"
defer></script>
<!-- End ProfitMetrics - Script -->
Final Example:<!-- Start ProfitMetrics - Script -->
<script>
window.profitMetrics = {
pid: 'PUBLIC_ID', // Your Public ID
emailInputSelector: '.email, .signup_email, #newsletter-input-email', // Email input CCS selector
}
</script>
<script src="https://cdn1.profitmetrics.io/PUBLIC_ID/bundle.js"
defer></script>
<!-- End ProfitMetrics - Script --> -
If you do not use any of the natively support Consent Management Platforms (CMP) or wish to manually control consent you can add the following two lines and replace true/false with a boolean value depending on the consent state. This script can also be loaded multiple times as consent change but remember to load the bundle.js every time.
<!-- Start ProfitMetrics - Script -->
<script>
window.profitMetrics = {
pid: 'PUBLIC_ID', // Your Public ID
emailInputSelector: '.class-name', // Email input CCS selector
cookieStatisticsConsent: true/false, // Replace with boolean value
cookieMarketingConsent: true/false, // Replace with boolean value
}
</script>
<script src="https://cdn1.profitmetrics.io/PUBLIC_ID/bundle.js"
defer></script>
<!-- End ProfitMetrics - Script --> - OPTIONAL: Set cookieDomain to your TLD (Top-level domain) to enable cross-domain tracking for headless implementations and third-party checkouts. Remember to add a '.' before the domain.
Warning: Enableing this might cause issues if your site uses a subdomain structure for different countries or languages like en.example.com
<!-- Start ProfitMetrics - Script -->
<script>
window.profitMetrics = {
pid: 'PUBLIC_ID', // Your Public ID
emailInputSelector: '.class-name', // Email input CCS selector
cookieStatisticsConsent: true/false, // Replace with boolean value
cookieMarketingConsent: true/false, // Replace with boolean value
cookieDomain: null, // Your top-level domain
}
</script>
<script src="https://cdn1.profitmetrics.io/PUBLIC_ID/bundle.js"
defer></script>
<!-- End ProfitMetrics - Script -->Example: cookieDomain: '.example.com',
- Copy and paste the onLoad event and paste it into the script on pages where the customer email is available. This usually includes order confirmation, login, and newsletter signup.
onLoad event:onLoad: () => {
const email = 'EMAIL'; // Replace with customer email
if (email && /^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(email)) {
profitMetrics.setEmail(email);
}
}Example:
<!-- Start ProfitMetrics - Script -->
<script>
window.profitMetrics = {
pid: 'PUBLIC_ID', // Your Public ID
emailInputSelector: '.class-name', // Email input CCS selector
cookieStatisticsConsent: true/false, // Replace with boolean value
cookieMarketingConsent: true/false, // Replace with boolean value
cookieDomain: null, // Your top-level domain
onLoad: () => {
const email = 'EMAIL'; // Replace with customer email
if (email && /^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(email)) {
profitMetrics.setEmail(email);
}
}
}
</script>
<script src="https://cdn1.profitmetrics.io/PUBLIC_ID/bundle.js"
defer></script>
<!-- End ProfitMetrics - Script --> - FOR KLARNA: Add the following code to the checkout pages or all pages in order to ensure we can get the email from within Klarna Checkout
<!-- Start ProfitMetrics - Klarna Checkout (v2) -->
<script>
(function(){function r(){var x=document.querySelector(".klarna-checkout-container");if(!x)return;function i(){window._klarnaCheckout(function(a){a.on({change:function(d){d.email&&profitMetrics.setEmail(d.email)}})})}
typeof window._klarnaCheckout=="function"?i():new MutationObserver(function(m,o){if(typeof window._klarnaCheckout=="function"){o.disconnect();i()}}).observe(x,{childList:!0,subtree:!0})}
document.readyState=="loading"?document.addEventListener("DOMContentLoaded",r):r()})();
</script>
<!-- End ProfitMetrics - Script -->Example:
<!-- Start ProfitMetrics - Script -->
<script>
window.profitMetrics = {
pid: 'PUBLIC_ID', // Your Public ID
emailInputSelector: '.class-name', // Email input CCS selector
cookieStatisticsConsent: true/false, // Replace with boolean value
cookieMarketingConsent: true/false, // Replace with boolean value
cookieDomain: null, // Your top-level domain
onLoad: () => {
const email = 'EMAIL'; // Replace with customer email
if (email && /^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(email)) {
profitMetrics.setEmail(email);
}
}
}
</script>
<script src="https://cdn1.profitmetrics.io/PUBLIC_ID/bundle.js"
defer></script>
<!-- End ProfitMetrics - Script -->
<!-- Start ProfitMetrics - Klarna Checkout (v2) -->
<script>
(function(){function r(){var x=document.querySelector(".klarna-checkout-container");if(!x)return;function i(){window._klarnaCheckout(function(a){a.on({change:function(d){d.email&&profitMetrics.setEmail(d.email)}})})}
typeof window._klarnaCheckout=="function"?i():new MutationObserver(function(m,o){if(typeof window._klarnaCheckout=="function"){o.disconnect();i()}}).observe(x,{childList:!0,subtree:!0})}
document.readyState=="loading"?document.addEventListener("DOMContentLoaded",r):r()})();
</script>
<!-- End ProfitMetrics - Script -->
Part 2: OPTIONAL: Implement setEmail event to capture email when using a third-party checkout.
- Copy the following script and paste it AFTER the main script on the order confirmation page and replace example@example.com with a variable containing the customer email. The script will retry to set the customer email every 500 milliseconds ontil the email becomes available.
<!-- Start ProfitMetrics - setEmail -->
<script>
function _pm_tryemailorderconfirmation() {
if (null != window.profitMetrics && null != window.profitMetrics.setEmail && typeof window.profitMetrics.setEmail === 'function') {
window.profitMetrics.setEmail('example@example.com');
} else {
setTimeout(_pm_tryemailorderconfirmation, 500);
}
}
_pm_tryemailorderconfirmation();
</script>
<!-- End ProfitMetrics - setEmail -->
Part 3: Special code for known CMP's
Cookiebot
Native support. No additional changes are needed.
CookieInforation
Native support. No additional changes are needed.
CookieYes
<!--Start ProfitMetrics - Script for CookieYes -->
<script>
// Configuration
let pmPublicID = ''; // Replace with your Public ID
let pmEmailInputSelector = '.class-name'; // Email input CCS selector
let pmCookieDomain = ''; // Your top-level domain for cross-subdomain tracking
let pmEmail = ''; // Dynamically fetch email if available
// Default consent
let cc_statistics = true;
let cc_marketing = true;
// Function to load the ProfitMetrics script
function pmLoadScript() {
window.profitMetrics = {
pid: pmPublicID,
cookieStatisticsConsent: cc_statistics,
cookieMarketingConsent: cc_marketing,
emailInputSelector: pmEmailInputSelector,
onLoad: () => {
if (pmEmail && /^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(pmEmail)) {
profitMetrics.setEmail(pmEmail);
}
}
};
if (pmCookieDomain) {
window.profitMetrics.cookieDomain = pmCookieDomain.startsWith('.') ? pmCookieDomain : `.${pmCookieDomain}`;
}
const script = document.createElement('script');
script.src = `https://cdn1.profitMetrics.io/${pmPublicID}/bundle.js`;
script.defer = true;
script.onerror = () => console.error('Failed to load ProfitMetrics script.');
document.head.appendChild(script);
}
// CookieYes - Get consent
if (typeof getCkyConsent !== 'undefined' && getCkyConsent()?.categories) {
cc_statistics = getCkyConsent().categories.performance;
cc_marketing = getCkyConsent().categories.advertising;
pmLoadScript();
}
// CookieYes - Add event listener
document.addEventListener("cookieyes_consent_update", (event) => {
cc_statistics = event.detail.accepted.includes("analytics");
cc_marketing = event.detail.accepted.includes("advertisement");
pmLoadScript();
});
// CookieYes - Fallback
if (typeof getCkyConsent === 'undefined') {
pmLoadScript();
}
</script>
<!-- End ProfitMetrics - Script for CookieYes -->
CookieFirst
<!--Start ProfitMetrics - Script for CookieFirst -->
<script>
// Configuration
let pmPublicID = ''; // Replace with your Public ID
let pmEmailInputSelector = '.class-name'; // Email input CCS selector
let pmCookieDomain = ''; // Your top-level domain for cross-subdomain tracking
let pmEmail = ''; // Dynamically fetch email if available
// Default consent
let cc_statistics = true;
let cc_marketing = true;
// Function to load the ProfitMetrics script
function pmLoadScript() {
window.profitMetrics = {
pid: pmPublicID,
cookieStatisticsConsent: cc_statistics,
cookieMarketingConsent: cc_marketing,
emailInputSelector: pmEmailInputSelector,
onLoad: () => {
if (pmEmail && /^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(pmEmail)) {
profitMetrics.setEmail(pmEmail);
}
}
};
if (pmCookieDomain) {
window.profitMetrics.cookieDomain = pmCookieDomain.startsWith('.') ? pmCookieDomain : `.${pmCookieDomain}`;
}
const script = document.createElement('script');
script.src = `https://cdn1.profitMetrics.io/${pmPublicID}/bundle.js`;
script.defer = true;
script.onerror = () => console.error('Failed to load ProfitMetrics script.');
document.head.appendChild(script);
}
// CookieFirst
function updateConsent(consent) {
cc_statistics = consent.performance;
cc_marketing = consent.advertising;
pmLoadScript();
}
// CookieFirst - Get consent
if (typeof CookieFirst !== 'undefined' && !!CookieFirst?.consent) {
updateConsent(CookieFirst.consent);
}
// CookieFirst - Add event listener
window.addEventListener('cf_consent', (event) => updateConsent(event.detail));
window.addEventListener('cf_consent_loaded', (event) => updateConsent(event.detail));
// CookieFirst - Fallback
function checkAndLoadCookieFirst() {
if (typeof CookieFirst === 'undefined') {
setTimeout(() => {
if (typeof CookieFirst === 'undefined') {
pmLoadScript(); // Load the script if still undefined
}
}, 500); // Wait 500 milliseconds and check again
}
}
</script>
<!-- End ProfitMetrics - Script for CookieFirst -->
CookieScript
<!--Start ProfitMetrics - Script for CookieScript -->
<script>
// Configuration
let pmPublicID = ''; // Replace with your Public ID
let pmEmailInputSelector = '.class-name'; // Email input CCS selector
let pmCookieDomain = ''; // Your top-level domain for cross-subdomain tracking
let pmEmail = ''; // Dynamically fetch email if available
// Default consent
let cc_statistics = true;
let cc_marketing = true;
// Function to load the ProfitMetrics script
function pmLoadScript() {
window.profitMetrics = {
pid: pmPublicID,
cookieStatisticsConsent: cc_statistics,
cookieMarketingConsent: cc_marketing,
emailInputSelector: pmEmailInputSelector,
onLoad: () => {
if (pmEmail && /^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(pmEmail)) {
profitMetrics.setEmail(pmEmail);
}
}
};
if (pmCookieDomain) {
window.profitMetrics.cookieDomain = pmCookieDomain.startsWith('.') ? pmCookieDomain : `.${pmCookieDomain}`;
}
const script = document.createElement('script');
script.src = `https://cdn1.profitMetrics.io/${pmPublicID}/bundle.js`;
script.defer = true;
script.onerror = () => console.error('Failed to load ProfitMetrics script.');
document.head.appendChild(script);
}
// CookieScript - Update
function updateConsent(consent) {
cc_statistics = consent.includes('performance');
cc_marketing = consent.includes('targeting');
pmLoadScript();
}
// CookieScript - Get consent
if (typeof CookieScript !== 'undefined' && CookieScript?.instance?.currentState()?.categories) {
updateConsent(CookieScript.instance.currentState().categories);
}
// CookieScript - Add event listener
window.addEventListener('CookieScriptCategory-strict', () => {
updateConsent(CookieScript.instance.currentState().categories);
});
// CookieFirst - Fallback
if (typeof CookieScript === 'undefined') {
pmLoadScript();
}
</script>
<!--End ProfitMetrics - Script for CookieScript -->
OneTrust
<!--Start ProfitMetrics - Script for OneTrust -->
<script>
// Configuration
let pmPublicID = ''; // Replace with your Public ID
let pmEmailInputSelector = '.class-name'; // Email input CCS selector
let pmCookieDomain = ''; // Your top-level domain for cross-subdomain tracking
let pmEmail = ''; // Dynamically fetch email if available
// Default consent
let cc_statistics = true;
let cc_marketing = true;
// Function to load the ProfitMetrics script
function pmLoadScript() {
window.profitMetrics = {
pid: pmPublicID,
cookieStatisticsConsent: cc_statistics,
cookieMarketingConsent: cc_marketing,
emailInputSelector: pmEmailInputSelector,
onLoad: () => {
if (pmEmail && /^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(pmEmail)) {
profitMetrics.setEmail(pmEmail);
}
}
};
if (pmCookieDomain) {
window.profitMetrics.cookieDomain = pmCookieDomain.startsWith('.') ? pmCookieDomain : `.${pmCookieDomain}`;
}
const script = document.createElement('script');
script.src = `https://cdn1.profitMetrics.io/${pmPublicID}/bundle.js`;
script.defer = true;
script.onerror = () => console.error('Failed to load ProfitMetrics script.');
document.head.appendChild(script);
}
// OneTrust - Update
function updateConsent(consent) {
cc_statistics = consent.includes("2");
cc_marketing = consent.includes("4");
pmLoadScript();
}
// OneTrust - Get consent
if (typeof OneTrust !== "undefined" && typeof OnetrustActiveGroups !== "undefined") {
updateConsent(OnetrustActiveGroups);
}
// OneTrust - Add event listener
window.addEventListener("OneTrustGroupsUpdated", (event) => {
updateConsent(event.detail || []);
});
// OneTrust - Fallback
if (typeof OneTrust === "undefined") {
pmLoadScript();
}
</script>
<!-- End ProfitMetrics - Script for OneTrust -->
Part 4: Confirm the integration
- Check if the pmStorage cookie exists.
- Create a test order and complete it. On the order confirmation page, check if the pmStorage cookie has an "etid" value and / or if the "em" value contains you email. The cookie value should look like this:
{"etid":172978336,"pid":"A1B2C3D4E5F6G7H8","referer":null,"cc_statistics":true,"cc_marketing":true,"gacid":"GA1.1.1608251768.1705563035","gacid_source":"gacookie","uid":null,"gclid":null,"fbp":"fb.1.1705563034698.1103141032","fbc":null,"cip":"0.0.0.0","gbraid":"","wbraid":"","ga4SessionId":"5DP76XVKEZ:1705568293","ga4SessionNumber":"DP76XVKEZ5:2","em_md5":null,"em_sha256":null,"em":"example@example.com"}