HTTP Cookie — Server-Side Implementation

Step 01

Customer clicks affiliate link

via publisher

Step 02

URL arrives with cjevent

?cjevent=...

Step 03

Server writes cje cookie

Set-Cookie: cje=...

Step 04

Customer completes purchase

confirmation page

Step 05

Tag reads cookie & transmits

→ CJ servers

Persistence note: Each new cjevent value overwrites the existing cookie so the most recent click is credited. If no cjevent parameter is present in the inbound URL, the existing cookie value is preserved.

To complete the integration, your server must set a first-party cookie named cje that captures the cjevent value appended to inbound affiliate links. This cookie is the persistent storage layer for CJ's attribution signal — the Universal Tag reads its value at conversion and transmits it back to CJ's servers to credit the originating publisher.

The cookie must be set on the server-side (via the HTTP Set-Cookie response header) on every page of your site that can serve as an affiliate landing page. Each time a new cjevent value arrives in the URL, the cookie value must be overwritten so that the most recent click is correctly attributed.

Cookie Specification

AttributeRequired Value
Namecje
ValueThe cjevent parameter passed in the inbound URL
Duration13 months from the date of last update
DomainSet on the registrable parent domain (e.g., .example.com) rather than a single subdomain (e.g., www.example.com)
PathSet to / to make the cookie available across your entire site.
SecureSecure attribute set to true
HttpOnlyHttpOnly attribute set to false
Set-Cookie sourceServer-side response header (not JavaScript)

Example

The examples below show how to capture the cjevent parameter and set the cje cookie. Replace .example.com with your actual domain.

<?php
    $cookie_name = "cje";
    $domain = ".example.com"; // use your domain, for instance ".example.com"
    $_GET_lower = array_change_key_case($_GET, CASE_LOWER);
    $cjevent = $_GET_lower["cjevent"];
    if ($cjevent) {
        setcookie($cookie_name, $cjevent, time() + (86400 * 395), "/", $domain, true, false);
    }
?>
public class CJCookieServletFilter implements Filter {

    @Override
    public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
        try {
            if (response instanceof HttpServletResponse) {
                HttpServletResponse httpServletResponse = (HttpServletResponse)response;
                String cjevent = getCJEventValue(request);
                if (cjevent != null && !cjevent.isEmpty()) {
                    long expirationInSeconds = 395L * 24 * 60 * 60;
                    StringBuilder cookieString = new StringBuilder("cjevent_sc=" + cjevent + "; ");
                    appendToCookie(cookieString, "Path", "/");
                    appendToCookie(cookieString, "Domain", "localhost"); // use your domain, for instance ".example.com"
                    appendToCookie(cookieString, "Expires", getExpirationDate(expirationInSeconds * 1000));
                    appendToCookie(cookieString, "Max-Age", String.valueOf(expirationInSeconds));
                    cookieString.append("Secure; SameSite=None");
                    httpServletResponse.addHeader("Set-Cookie", cookieString.toString());
                }
            }
        } catch(Throwable ignored) {
        }

        chain.doFilter(request, response);
    }

    private String getCJEventValue(ServletRequest request) {
        for (Map.Entry<String, String[]> entry : request.getParameterMap().entrySet()) {
            if ("cjevent".equals(entry.getKey().toLowerCase())) {
                if (entry.getValue().length > 0) {
                    return entry.getValue()[0];
                }
            }
        }
        return null;
    }

    private void appendToCookie(StringBuilder cookie, String key, String value) {
        cookie.append(key + "=" + value + "; ");
    }

    private String getExpirationDate(long expirationInMilliseconds) {
        Date expirationDate= new Date();
        expirationDate.setTime (expirationDate.getTime() + expirationInMilliseconds);
        DateFormat df = new SimpleDateFormat("EEE, dd MMM yyyy HH:mm:ss zzz", java.util.Locale.US);
        df.setTimeZone(TimeZone.getTimeZone("GMT"));
        return df.format(expirationDate);
    }

    @Override
    public void init(FilterConfig filterConfig) { }

    @Override
    public void destroy() { }
}
<web-app xmlns="http://java.sun.com/xml/ns/javaee"
         version="2.5">

    <filter>
        <filter-name>CJCookieServletFilter</filter-name>
        <filter-class>CJCookieServletFilter</filter-class>
    </filter>

    <filter-mapping>
        <filter-name>CJCookieServletFilter</filter-name>
        <url-pattern>/*</url-pattern>
    </filter-mapping>

</web-app>
📘

This sample code is provided as a courtesy and is meant for your reference only. When implementing code for your specific shopping cart or website please ensure that the correct contact is implementing and testing accurate code. CJ does not guarantee the accuracy of any coding examples.