1/** 2 * Affiliate Program Handling File 3 * This script is responsible for tracking affiliate visits, appending affiliate tokens, 4 * and handling reference data for registrations. 5 */ 6 7jQuery(document).ready(function ($) { 8 // ------------------------------------------------------------------------- 9 // Utility Functions 10 // ------------------------------------------------------------------------- 11 12 /** 13 * Set a cookie value with a specific expiration in days. 14 */ 15 function setCookie(cname, cvalue, exdays) { 16 var d = new Date(); 17 d.setTime(d.getTime() + exdays * 24 * 60 * 60 * 1000); 18 var expires = "expires=" + d.toUTCString(); 19 document.cookie = cname + "=" + cvalue + "; " + expires + ";path=/"; 20 } 21 22 /** 23 * Retrieve a cookie by name. 24 */ 25 function getCookie(cname) { 26 var name = cname + "="; 27 var ca = document.cookie.split(";"); 28 for (var i = 0; i < ca.length; i++) { 29 var c = ca[i].trim(); 30 if (c.indexOf(name) === 0) { 31 return c.substring(name.length, c.length); 32 } 33 } 34 return ""; 35 } 36 37 /** 38 * Check if a cookie exists. 39 */ 40 function checkCookie(cname) { 41 return getCookie(cname) !== ""; 42 } 43 44 /** 45 * Check if the current page is a specific Shopify-related page 46 * where we should NOT append the usual affiliate registration links. 47 */ 48 function isShopifyExcludedPage() { 49 var excludedClasses = [ 50 "page-shopify-integration", 51 "page-shopify-cart-trigger", 52 "page-shopify-cart-targeting", 53 "page-shopify-login-status-targeting", 54 "page-shopify-order-history-targeting", 55 "page-shopify-customer-tag-targeting", 56 ]; 57 58 return excludedClasses.some(function (className) { 59 return $("body").hasClass(className); 60 }); 61 } 62 63 /** 64 * Push the token to any forms on the current page. 65 */ 66 function appendTokenToForms(token) { 67 $("form").append( 68 '<input type="hidden" name="poptin_affiliate_token" value="' + token + '" />' 69 ); 70 } 71 72 /** 73 * Update the registration links (Try Free, Register, etc.) to include the affiliate token. 74 * Preserves existing query params (e.g. plan, contact_limit) on each link. 75 */ 76 function updateRegistrationLinks(token) { 77 if (!token || isShopifyExcludedPage()) { 78 return; 79 } 80 81 $("a[href*='https://app.popt.in/register']").each(function () { 82 var href = $(this).attr("href"); 83 84 try { 85 var url = new URL(href); 86 url.searchParams.set("poptin_apt", token); 87 $(this).attr("href", url.toString()); 88 } catch (e) { 89 var separator = href.indexOf("?") >= 0 ? "&" : "?"; 90 $(this).attr( 91 "href", 92 href + separator + "poptin_apt=" + encodeURIComponent(token) 93 ); 94 } 95 }); 96 } 97 98 // ------------------------------------------------------------------------- 99 // Affiliate Tracking Logic 100 // ------------------------------------------------------------------------- 101 102 /** 103 * Initialize affiliate tracking based on token existence in cookie or URL. 104 */ 105 function initAffiliate() { 106 var token = ""; 107 var urlParams = new URLSearchParams(window.location.search); 108 var urlToken = urlParams.get("poptin_apt"); 109 110 if (checkCookie("poptin_affiliate_token")) { 111 // Priority 1: Use existing affiliate token from cookies 112 token = getCookie("poptin_affiliate_token"); 113 } else if (urlToken) { 114 // Priority 2: Set new affiliate token from URL parameters 115 token = urlToken; 116 setCookie("poptin_affiliate_token", token, 90); 117 } 118 119 if (token) { 120 appendTokenToForms(token); 121 } 122 123 updateRegistrationLinks(token); 124 setupRefererTracking(); 125 } 126 127 // ------------------------------------------------------------------------- 128 // Referer & Landing Page Tracking 129 // ------------------------------------------------------------------------- 130 131 /** 132 * Determine and store where the user landed from and which page they landed on. 133 * Appends hidden forms and tracking pixels as necessary. 134 */ 135 function setupRefererTracking() { 136 var referrerUrl = document.referrer; 137 var landingUrl = window.location.href; 138 139 var storedReferrer = getCookie("poptin_front_register_referrer_url"); 140 var storedLanding = getCookie("poptin_front_register_landing_url"); 141 142 // Use stored values if they exist, otherwise fallback to current context 143 var finalReferrerUrl = storedReferrer ? storedReferrer : referrerUrl; 144 var finalLandingUrl = storedLanding ? storedLanding : landingUrl; 145 146 // If a referrer exists, setup the hidden form to submit upon clicking register 147 if (referrerUrl.length > 1 || storedReferrer) { 148 var options = { 149 ruc: finalReferrerUrl, 150 luc: finalLandingUrl, 151 redirect_url: "" 152 }; 153 154 var $form = $("<form>", { 155 id: "handlePoptinReferer", 156 action: "https://app.popt.in/handleReferer.php", 157 method: "POST" 158 }); 159 160 $.each(options, function (key, value) { 161 $("<input>", { 162 type: "hidden", 163 name: key, 164 value: encodeURI(value) 165 }).appendTo($form); 166 }); 167 168 $form.appendTo("body"); 169 } 170 171 // If there are no tracking cookies, set them and append the tracking pixel 172 if (!storedLanding || !storedReferrer) { 173 var trackLanding = window.location.href; 174 var trackReferrer = referrerUrl.length <= 1 ? window.location.href : referrerUrl; 175 176 $("body").append( 177 '<img alt="Affiliates Progrem Image" class="affimg" src="https://app.popt.in/cookies.php?luc=' + 178 encodeURIComponent(trackLanding) + 179 "&ruc=" + 180 encodeURIComponent(trackReferrer) + 181 '" style="display:none;" />' 182 ); 183 184 setCookie("poptin_front_register_landing_url", trackLanding, 90); 185 setCookie("poptin_front_register_referrer_url", trackReferrer, 90); 186 } 187 } 188 189 // ------------------------------------------------------------------------- 190 // Execution 191 // ------------------------------------------------------------------------- 192 193 // Start checking for an affiliate token as soon as DOM is ready 194 initAffiliate(); 195 196 // Intercept clicks on registration or login links to log referer data first 197 $(document).on("click", "a", function (e) { 198 var $link = $(this); 199 var registerLink = $link.attr("href"); 200 var $refererForm = $("#handlePoptinReferer"); 201 202 if ( 203 !registerLink || 204 !/https:\/\/app\.popt\.in\/(register|login)/i.test(registerLink) || 205 !$refererForm.length 206 ) { 207 return; 208 } 209 210 e.preventDefault(); 211 212 var target = ($link.attr("target") || "").toLowerCase(); 213 var openInNewTab = target === "_blank" || target === "blank"; 214 215 $refererForm.find("input[name='redirect_url']").val(registerLink); 216 217 if (openInNewTab) { 218 $refererForm.attr("target", "_blank"); 219 } else { 220 $refererForm.removeAttr("target"); 221 } 222 223 $refererForm.submit(); 224 }); 225});
Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.