Skip to main content
These patterns combine multiple EF.click() / EF.conversion() calls or add custom logic around them. They build on the basics in Click Tracking and the Tracking Recipes.

Click and conversion on the same page

When a single page load needs to record both a click and a conversion — for example a Meta “PageView” that should attribute the click and immediately convert — fire the conversion inside the click’s .then(), so it runs only after the click resolves with a transaction ID. A short setTimeout adds a safety margin.
<script type="text/javascript"
    src="https://INSERT_TRACKING_DOMAIN/scripts/main.js"></script>

<script type="text/javascript">
EF.click({
    offer_id: EF.urlParameter('oid'),
    affiliate_id: EF.urlParameter('affid'),
    sub1: EF.urlParameter('sub1'),
    sub2: EF.urlParameter('sub2'),
    sub3: EF.urlParameter('sub3'),
    sub4: EF.urlParameter('sub4'),
    sub5: EF.urlParameter('sub5'),
    uid: EF.urlParameter('uid'),
    source_id: EF.urlParameter('source_id'),
    transaction_id: EF.urlParameter('_ef_transaction_id'),
}).then(function(transactionId) {
    setTimeout(function() {
        EF.conversion({
            aid: INSERT_ADVERTISER_ID,
            adv_event_id: INSERT_ADVERTISER_EVENT_ID,
            transaction_id: transactionId,
        });
    }, 500);
});
</script>
Chaining the conversion inside .then() already guarantees it runs after the click is recorded (the promise resolves with the transaction ID). The setTimeout is an extra safeguard so the conversion never races ahead of the click on slow connections.

Chaining across multiple Everflow accounts

This extends the EF-to-EF recipe to more than two accounts. Each hop fires a click against its own tracking_domain; the transaction ID returned by one hop is passed into the next hop’s sub5 (or sub2), which the downstream account reads back via a Partner Postback.

Three accounts deep (Advertiser → Partner → Sub-Partner)

The chain fires inside-out: the sub-partner click resolves first, its transaction ID becomes the partner click’s sub2, and the partner’s transaction ID becomes the advertiser click’s sub5.
<script type="text/javascript"
    src="https://INSERT_ADVERTISER_DOMAIN/scripts/main.js"></script>

<script type="text/javascript">
if (EF.urlParameter('affid3')) {
  EF.click({
    tracking_domain: "https://INSERT_SUB_PARTNER_DOMAIN",
    offer_id: EF.urlParameter('oid3'),
    affiliate_id: EF.urlParameter('affid3'),
  }).then(function(transaction_id) {
    EF.click({
      tracking_domain: "https://INSERT_PARTNER_DOMAIN",
      offer_id: EF.urlParameter('oid2'),
      affiliate_id: EF.urlParameter('affid2'),
      sub2: transaction_id,
    }).then(function(transaction_id2) {
      EF.click({
        tracking_domain: "https://INSERT_ADVERTISER_DOMAIN",
        offer_id: EF.urlParameter('oid'),
        affiliate_id: EF.urlParameter('affid'),
        sub5: transaction_id2,
      });
    });
  });
} else if (EF.urlParameter('affid2')) {
  // Two-account chain (Advertiser → Partner)
  EF.click({
    tracking_domain: "https://INSERT_PARTNER_DOMAIN",
    offer_id: EF.urlParameter('oid2'),
    affiliate_id: EF.urlParameter('affid2'),
  }).then(function(transaction_id) {
    EF.click({
      tracking_domain: "https://INSERT_ADVERTISER_DOMAIN",
      offer_id: EF.urlParameter('oid'),
      affiliate_id: EF.urlParameter('affid'),
      sub5: transaction_id,
    });
  });
} else {
  // Direct advertiser click
  EF.click({
    tracking_domain: "https://INSERT_ADVERTISER_DOMAIN",
    offer_id: EF.urlParameter('oid'),
    affiliate_id: EF.urlParameter('affid'),
    transaction_id: EF.urlParameter('_ef_transaction_id'),
  });
}
</script>
Each downstream account recovers the upstream transaction ID with a Partner Postback macro:
  • Partner Postback (advertiser account): &transaction_id={sub5}
  • Sub-Partner Postback (partner account): &transaction_id={sub2}
Each hop reserves a sub-placement (sub5, then sub2) to carry the upstream transaction ID. Plan your sub usage so the chain doesn’t overwrite a sub you need for reporting.

Parallel partners

When one advertiser works with several independent partners on the same page (Partner A via affid2, Partner B via affid3) rather than a nested chain, the structure is the same if / else if / else shape — each branch fires the matching partner’s click, then chains the advertiser click with the partner’s transaction ID in sub5. Use whichever partner parameter (affid2, affid3, …) is present on the inbound URL to select the branch.

Preventing duplicate clicks with a global script

When the click script is placed globally (on every page) and the landing page’s URL parameters are “sticky” (persist across navigation), the same partner’s click can fire more than once — so the last-touch transaction may not be the one that converts. Deduplicate by comparing the inbound affid against the ef_affid first-party cookie the SDK writes on every successful click, and only fire when they differ. Logic:
  • Direct linking — if affid (URL) ≠ ef_affid (cookie) → fire the click; if they match → skip it.
  • Redirect — always fire.
<script type="text/javascript"
    src="https://INSERT_TRACKING_DOMAIN/scripts/main.js"></script>

<script type="text/javascript">
function getCookie(name) {
    var decodedCookie = decodeURIComponent(document.cookie);
    var cookieArray = decodedCookie.split('; ');
    var prefix = name + "=";
    for (var i = 0; i < cookieArray.length; i++) {
        var cookie = cookieArray[i];
        while (cookie.charAt(0) === ' ') {
            cookie = cookie.substring(1);
        }
        if (cookie.indexOf(prefix) === 0) {
            return cookie.substring(prefix.length);
        }
    }
    return null;
}

if (EF.urlParameter('affid')) {
    var aff_cookie = getCookie('ef_affid');
    var param = EF.urlParameter('affid');
    if (aff_cookie != param) {
        EF.click({
            offer_id: EF.urlParameter('oid'),
            affiliate_id: EF.urlParameter('affid'),
            sub1: EF.urlParameter('sub1'),
            sub2: EF.urlParameter('sub2'),
            sub3: EF.urlParameter('sub3'),
            sub4: EF.urlParameter('sub4'),
            sub5: EF.urlParameter('sub5'),
            uid: EF.urlParameter('uid'),
            source_id: EF.urlParameter('source_id'),
            transaction_id: EF.urlParameter('_ef_transaction_id'),
        });
    }
} else {
    EF.click({
        offer_id: EF.urlParameter('oid'),
        affiliate_id: EF.urlParameter('affid'),
        sub1: EF.urlParameter('sub1'),
        sub2: EF.urlParameter('sub2'),
        sub3: EF.urlParameter('sub3'),
        sub4: EF.urlParameter('sub4'),
        sub5: EF.urlParameter('sub5'),
        uid: EF.urlParameter('uid'),
        source_id: EF.urlParameter('source_id'),
        transaction_id: EF.urlParameter('_ef_transaction_id'),
    });
}
</script>
This prevents duplicate clicks within the same partner. If Partner A’s link is clicked and then Partner B’s, Partner B still gets a fresh transaction ID — last-touch attribution is preserved across different partners.