# Consent and cookies

> What tracking stores in the customer's browser, for how long – and how the script can wait for consent to marketing.

Tracking stores only a click ID: the ID that links a later purchase to the click that led to it. It sits in a first-party cookie on your domain – not on ours – and there is no tracking across sites or devices.

## What is stored

The tracking script (track.js) stores:

| Name | Where | Contents | Lifetime |
|---|---|---|---|
| `af_click` | Cookie and localStorage | The click ID from the affiliate link | 90 days from the click |
| `af_store` | Cookie and localStorage | Your store ID | 90 days from the click |
| `af_aff` | Cookie and localStorage | The affiliate's ID – older links only | 90 days from the click |
| `af_t` | Cookie | When the click happened, in seconds | 90 days from the click |
| `af_srv` | Cookie – only set by your own server | `1` when your server has set the click cookie | 90 days from the click |
| `af_sent` | localStorage | Up to 20 order numbers that have already been reported | 30 days |
| `af_sent_s`, `af_lead_[store]` | sessionStorage | Guards against counting the same purchase or lead twice | Until the tab is closed |
| `_af_d` | Cookie | Tests which domain the cookie can be set on | Deleted immediately |

The script rewrites the cookie on every visit, but never beyond 90 days from the click. The program's own cookie period – between 14 and 90 days – is enforced on our server, based on when the click happened.

`af_t` lets your own server renew the cookie without extending it beyond the 90 days. The script never sets `af_srv` itself: it's only set when you let [your own server store the click](https://www.affilyflow.com/en/docs/store/server-side-tracking), and then the script no longer writes `af_click` and `af_t`.

### The landing report

When a customer lands with a click ID, the script reports it to Affilyflow – again once the click has been stored, and if the customer actively declines marketing. The report contains only the click ID, your store ID and the state of consent – nothing about the visitor. The landing report itself stores nothing in the browser, so it is sent before there is consent too. It is the basis for **Tracking coverage** in Setup, which shows, among other things, how many customers from affiliates declined marketing or didn't respond.

The WooCommerce plugin sets `af_click`, `af_t` and `af_srv` from your own server (90 days). With **Last click wins** turned on, it also sets `afw_last_network` (90 days), which only holds the name of the network that had the customer's most recent affiliate click.

The cookies belong in your own cookie information. Our [cookie policy](/en/cookie-policy) describes them, so you can refer to it.

## The cookie domain

The cookie is set on the broadest domain the browser allows – `yourshop.com` rather than `www.yourshop.com` – so the click survives if the order confirmation is on another subdomain. To choose the domain yourself, add `data-cookie-domain`:

```html title="<head> · every page"
<script src="https://app.affilyflow.com/track.js" data-store="DIN_BUTIK" data-cookie-domain="dinbutik.dk" async></script>
```

## Waiting for consent

With `data-consent="required"`, the script stores nothing in the browser – no cookie, nothing in localStorage or sessionStorage and no test cookie – until the visitor has consented to marketing:

```html title="<head> · every page · with consent"
<script src="https://app.affilyflow.com/track.js" data-store="DIN_BUTIK" data-consent="required" async></script>
```

The attribute is optional – without it, the script behaves as it always has. On a [custom-built store](https://www.affilyflow.com/en/docs/store/custom-built) it's controlled by the **Cookie banner** setting in Setup: the scan chooses *Wait for consent* when it finds Cookiebot, Cookie Information, or the built-in banner in DanDomain Classic or Smartweb, and our server adds the setting to the store's own script (`/t/DIN_BUTIK.js`), so the line on the site doesn't have to change. On the other platforms you add `data-consent="required"` yourself – it works on both `/t/DIN_BUTIK.js` and `track.js`.

If you choose *Wait for consent* under **Cookie banner** without the scan having found a banner the script can read on its own (the list below), Setup asks you to confirm that your developer calls `affilyflow.consent(true)` when the customer accepts marketing. Without that call, no click is stored and no sales are counted.

Until there is consent, the click ID is only held in memory, and a sale waits for the consent answer. Without consent nothing is attributed – not even on the same page.

### How the script reads consent

The script reads these cookie solutions on its own:

- **Cookiebot** – consent to marketing.
- **Cookie Information** – the `cookie_cat_marketing` category.
- **IAB TCF v2** – publisher consent to purposes 1 and 7.
- **Shoporama's own cookie banner** – consent to marketing.
- **DanDomain Classic's built-in banner** – `CookiePolicy` on the page, when marketing is allowed.
- **Smartweb/HostedShop's built-in banner** – the `cookie_consent` cookie with `MARKETING`.
- **Google Consent Mode v2** – `ad_storage: granted` in `dataLayer`. This covers the banners that send Consent Mode (Cookiebot, Usercentrics, OneTrust, CookieYes, Complianz and others), even when the script doesn't know the banner itself.

If you use another solution, tell the script yourself:

```js title="Your own cookie solution"
// Den besøgende siger ja til marketing:
affilyflow.consent(true);

// Den besøgende siger nej eller trækker samtykket tilbage:
affilyflow.consent(false);
```

You can also set `window.affilyflowConsent = true` before the script loads.

A no deletes everything the script has stored (`af_click`, `af_store`, `af_aff`, `af_t` and `af_sent`) – and also `af_srv` and the click cookies your server has set. A no is only registered on an active choice by the visitor (the banner's event or a Consent Mode update with `ad_storage: denied`) – never because the banner hasn't read its own cookie yet.

> [!WARNING]
> With `data-consent="required"`, you have to accept marketing yourself when you place the test purchase – otherwise it won't show up in the live test.

### Personal discount codes without consent

A [personal discount code](https://www.affilyflow.com/en/docs/store/personal-discount-codes) needs no storage in the browser. So if the customer declines marketing, the code can still earn the affiliate commission. Without a click, an order is only sent when it was placed with a personal code.

## Shopify and WooCommerce

The Shopify pixel does not ask for consent itself. That belongs to the store's own cookie solution.

From version 1.12.0, the WooCommerce plugin follows a cookie banner that supports the WP Consent API (Complianz, Cookiebot, CookieYes and others): the click is only stored once the customer has accepted marketing. Without such a banner the plugin doesn't ask itself – then it belongs to your own cookie solution. See [WooCommerce](https://www.affilyflow.com/en/docs/store/woocommerce#what-the-plugin-does).

## Safari and iPhone

Safari deletes cookies and localStorage set by JavaScript after about 7 days without a visit to the site – in some cases after 24 hours. The script rewrites both on every visit, but cannot and should not get around the limit. That's why the full cookie period counts on computers and Android, while in Safari and on iPhone it's typically about 7 days. A cookie set by the store's own server, like the WooCommerce plugin's, lasts longer. On a custom-built store, your own server can do the same – see [Server-side tracking](https://www.affilyflow.com/en/docs/store/server-side-tracking).

Source: https://www.affilyflow.com/en/docs/store/consent-and-cookies
