# JS adapter

Keitaro doesn't support landing pages natively, so we must apply several changes. This JavaScript code is intended to work with URL parameters, cookies, and tracker elements on landing pages. That solution is compatible with:

The code allows for the following actions:

# Setting up the code

For each page:

  1. Find <head> .... </head> tags.
  2. Copy and paste that code:
<!-- JS adapter start -->
<script type="application/javascript">
function getCookie (name) {
    var v = document.cookie.match('(^|;) ?' + name + '=([^;]*)(;|$)')
    var value = v ? v[2] : null
    return value && value !== 'undefined' ? value : null
}

function setCookie (name, value, days) {
    var d = new Date()
    d.setTime(d.getTime() + 24 * 60 * 60 * 1000 * days)
    document.cookie = name + '=' + value + ';path=/;expires=' + d.toUTCString()
}

function getSubId () {
    var params = new URLSearchParams(window.location.search)
    var clientSubid = '<?php echo isset($client) ? $client->getSubid() : "" ?>'
    if (clientSubid && !/>/.test(clientSubid)) {
        return clientSubid
    }
    return params.get('subid') || params.get('_subid') || getCookie('subid') || getCookie('_subid') || null
}

function getToken () {
    var params = new URLSearchParams(window.location.search)
    var clientToken = '<?php echo isset($client) ? $client->getToken() : "" ?>'
    if (clientToken && !/>/.test(clientToken)) {
        return clientToken
    }
    return params.get('token') || params.get('_token') || getCookie('token') || null
}

function getPixel () {
    var params = new URLSearchParams(window.location.search)
    return params.get('pixel') || getCookie('pixel') || null
}

function sendPostback (element, event, status, payout = 0, tid = '', sub_id_1 = '', sub_id_2 = '') {
    var subId = getSubId() || ''
    var postbackUrl = 'POSTBACK_URL/postback?subid=' + subId + '&status=' + status + '&payout=' + payout + '&tid=' + tid + '&sub_id_1=' + sub_id_1 + '&sub_id_2=' + sub_id_2
    var redirectUrl = element.getAttribute('href')
    event.preventDefault()
    fetch(postbackUrl)
            .then(response => {
                if (response.ok) {
                    console.log('Postback sent successfully')
                } else {
                    console.error('Error sending postback')
                }
                if (redirectUrl) {
                    window.location.href = redirectUrl
                }
            })
            .catch(error => {
                console.error('Error sending request:', error)
                if (redirectUrl) {
                    window.location.href = redirectUrl
                }
            })
}

document.addEventListener('DOMContentLoaded', function () {
    var params = new URLSearchParams(window.location.search)
    var subid = getSubId()
    var token = getToken()
    var pixel = getPixel()
    params.set('_token', token)
    setCookie('pixel', pixel)
    setCookie('token', token)
    setCookie('subid', subid)
    document.querySelectorAll('a').forEach(function (link) {
        try {
            var url = new URL(link.href)
            params.forEach(function (v, k) {
                url.searchParams.append(k, v)
            })
            link.href = url.toString()
        } catch (e) {
            console.error(`[Exception] Bad params: unexpected link '${link.href}' for new Url()`);
        }
    })
    var subIdRegExp = new RegExp(`\{subid\}`, 'g')
    var tokenRegExp = new RegExp(`\{token\}`, 'g')
    var pixelRegExp = new RegExp(`\{pixel\}`, 'g')
    document
            .querySelectorAll('input[type="hidden"]')
            .forEach(function (input) {
                if (subIdRegExp.test(input.value)) {
                    input.value = input.value.replaceAll(subIdRegExp, subid)
                }
                if (tokenRegExp.test(input.value)) {
                    input.value = input.value.replaceAll(tokenRegExp, token)
                }
                if (pixelRegExp.test(input.value)) {
                    input.value = input.value.replaceAll(pixelRegExp, pixel)
                }
            })
    document.querySelectorAll('form').forEach(function (form) {
        params.forEach(function (v, k) {
            var input = document.createElement('input')
            input.type = 'hidden'
            input.name = k
            input.value = v
            form.append(input)
        })
    })
})
</script>
<!-- JS adapter end -->
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
  1. Save changes.
  1. Set up JS Adapter on every page of the landing page.

  2. Create offer link using the following constructions:

# Sending postback

  1. Set up JS Adapter in either index.html or index.php of your landing page.
  2. Insert a postback sending code on thank_you_page (or on the handler of your landing page) using the following constructs:
  1. Replace the Postback URL with the URL of your tracker. See in Maintenance - Postback URL. Important: for correct postback sending, replace the IP address in the URL with any domain added to the tracker directly (without Cloudflare proxying).
  • To receive conversion from remote offer, you must pass subid={subid} as offer parameter.

# Sending Postback from a Button

# Sending a postback from the offer button

  1. Install the JS adapter code on index.html or index.php of your landing page.

  2. Add the code to send a postback and transition to an offer in the campaign flow:

<a href="{offer}" onclick="sendPostback(this, event, 'replace', 2);">Click me</a>
1

Where replace represents the conversion status, and 2 — the desired conversion income.

  1. Replace the Postback URL in the JS adapter code with your tracker URL. See Maintenance - Postback URL. Important: for correct postback sending, replace the IP address in the URL with any domain added to the tracker directly (without Cloudflare proxying).

# Sending postback from any button

  1. Install the JS adapter code on index.html or index.php of your landing page.

  2. Add the code to send a postback:

<button onclick="sendPostback(this, event, 'replace', 2, Date.now());">Add to cart</button>
1

Where replace represents the conversion status, and 2 — the desired conversion income.

  1. Replace the Postback URL in the JS adapter code with your tracker URL. See Maintenance - Postback URL. Important: for correct postback sending, replace the IP address in the URL with any domain added to the tracker directly (without Cloudflare proxying).

WARNING

Please note that passing the parameters sub_id_1='', sub_id_2='' in the postback can erase the data from the source. You need to replace the parameters in the postback with any free ones in your campaign sub_id_1-sub_id_30, or remove them from the postback.

# FB Pixel

  1. Set up JS Adapter on all pages where you want to use FB pixel.
  2. Add the pixel code to the necessary pages. Use function getPixel() to get saved pixel value:
<!-- Facebook Pixel Code -->
<script>
(function () {
    let match = document.cookie.match(/pixel=([^;]+)/);
    let pixel = match ? match[1] : null;

    if (!pixel) return;

    const img = document.createElement('img')
    img.setAttribute('height', '1')
    img.setAttribute('width', '1')
    img.setAttribute('src', 'https://www.facebook.com/tr?id=' + pixel + '&ev=Lead&noscript=1')
    if (document.body) {
        document.body.appendChild(img);
    } else {
        window.onload = () => document.body.appendChild(img);
    }
})();
</script>
<!-- End Facebook Pixel Code -->
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20

That pixel also works on any secondary page.

It's also compatible with solution mentioned on FB Pixel.