> ## Knowledge Base Index
> Fetch the complete knowledge base index at: https://help.pandectes.io/sitemap.xml
> Use this file to discover available pages before exploring further.
> Pure-Markdown content can be obtained by appending a '.md' suffix to the content URLs listed in the sitemap (without the trailing slash).

# Hoe je controleert of Pandectes werkt met de Shopify Customer Privacy API

### Overzicht

Pandectes GDPR Compliance is geïntegreerd met de Customer Privacy API van Shopify. Wanneer een bezoeker **Accept**, **Reject** of een aangepaste selectie in het voorkeurenvenster kiest, meldt de banner die keuze via de officiële API aan Shopify. Shopify past die vervolgens toe op de onderdelen die het beheert: web pixels, customer events, doelgroepen en checkout.

In dit artikel lees je hoe je bevestigt dat het signaal in je eigen winkel aankomt. Ook staan er controles in die op fouten lijken maar dat niet zijn.

Zie voor hoe de integratie zich gedraagt [How the app works with Shopify's Customer Privacy API](/nl/article/hoe-de-app-werkt-met-de-customer-privacy-api-van-shopify-4kjrzt/). De eigen referentie van Shopify is de [Customer Privacy API](https://shopify.dev/docs/api/customer-privacy).

|| Deze handleiding is geschreven voor een gewone Shopify-winkel (Online Store-thema). Op een headless of aangepaste storefront gelden dezelfde controles, met enkele praktische beperkingen. Lees Headless en aangepaste storefronts voordat je begint.

### Hoe het werkt

De taak van de app in deze integratie is de beslissing van de bezoeker correct en direct aan Shopify door te geven. Alles daarna is van Shopify: het laden of tegenhouden van web pixels in de winkel en in de checkout, het afschermen van verkoopkanalen zoals Google & YouTube of Meta, en het toepassen van toestemming op customer events, doelgroepen en checkout.

Dit zijn systemen van Shopify die toestemming uit de eigen API van Shopify lezen. Zodra de onderstaande controles laten zien dat het signaal aankomt, heeft de app gedaan wat hij moet doen.

`setTrackingConsent()` is de gedocumenteerde manier waarop een app Shopify laat weten wat een bezoeker heeft besloten. Pandectes roept deze functie aan. Die aanroep is de interface tussen de app en Shopify.

### Belangrijkste punten

* Gebruik `currentVisitorConsent()` om de ruwe beslissing van de bezoeker te verifiëren (`''`, `'yes'` of `'no'`).
* De `Allowed()`-methoden combineren instellingen van de merchant, locatie en toestemming. Een `true` of `false` alleen bewijst niet dat de bezoeker iets heeft besloten.
* `shouldShowBanner()` is een regiocontrole. Deze kan `true` blijven na Accept.
* Gebruik geen Shopify-cookies, `dataLayer` of netwerkverzoeken om deze integratie te beoordelen.
* De eerste controle installeert niets. Het themafragment en de testpixel zijn tijdelijk. Verwijder ze wanneer je klaar bent.

| Haast? Doe alleen de Quick Console Check. Als de waarden van leeg naar `'yes'` gaan wanneer je op Accept klikt, schrijft de integratie toestemming naar Shopify.

### Voordat je begint

Drie dingen, anders zijn de resultaten misleidend:

1. **Gebruik een schoon browserprofiel.** Open een nieuw Incognito-/privévenster of wis cookies en local storage voor je domein. Als je al toestemming hebt gegeven, vraagt de banner niet opnieuw en zie je alleen de status "na".
2. **Test als bezoeker uit een regio waar toestemming vereist is** (bijvoorbeeld de EU/EER/het VK als je banner zo is geconfigureerd). In regio's waar Shopify niet is ingesteld om toestemming te vereisen, is standaard alles toegestaan en bewijst de test niets.
3. **Zorg ervoor dat de Pandectes app embed is ingeschakeld** in je thema. De integratie met Shopify Customer Privacy is altijd actief en heeft geen instelling om in te schakelen.

Open de **Developer Console** van de browser:

* **Chrome / Edge:** druk op `F12` en open de tab **Console**
* **Firefox:** druk op `F12` en open de tab **Console**
* **Safari:** schakel het menu *Develop* in via Settings → Advanced en druk dan op `Option + Command + C`

||| De eerste controle installeert niets. De twee fragmenten die hierna volgen, zijn tijdelijke diagnosetools. Verwijder ze zodra de verificatie klaar is. Ze zijn bedoeld om een paar minuten op je scherm te draaien en niet om op een live winkel te blijven staan.

### Wat Pandectes naar Shopify stuurt

De API van Shopify gebruikt vier doeleinden. Pandectes koppelt zijn cookiecategorieën eraan:

| Pandectes-categorie | Shopify-doeleinde |
| --- | --- |
| Functionality / Preferences | `preferences` |
| Performance / Analytics | `analytics` |
| Targeting / Marketing | `marketing` |
| Sale of data opt-out (Do not sell my data) | `sale_of_data` |

Strikt noodzakelijke cookies hebben geen equivalent. Ze zijn altijd toegestaan en maken geen deel uit van deze toestemmingsregistratie.

### Optie 1: Quick Console Check

Je hoeft niets te installeren. Eén opdracht, drie keer uitgevoerd, is genoeg.

**Stap 1.** Open je winkel in een nieuw Incognito-venster. De banner verschijnt. Klik nergens op.

**Stap 2.** Open de Console, plak dit en druk op Enter:

```javascript
window.Shopify.customerPrivacy.currentVisitorConsent();
```

Je zou vier lege strings moeten krijgen. Zo geeft Shopify aan dat de bezoeker nog niets heeft besloten:

```javascript
{marketing: '', analytics: '', preferences: '', sale_of_data: ''}
```

**Stap 3.** Klik op de banner op **Accept all** en voer dezelfde opdracht opnieuw uit:

```javascript
{marketing: 'yes', analytics: 'yes', preferences: 'yes', sale_of_data: ''}
```

**Stap 4.** Laad de pagina opnieuw en voer de opdracht nog een laatste keer uit. De waarden moeten er nog steeds zijn.

Leeg vóór de beslissing, ingevuld direct erna en nog steeds ingevuld bij het volgende laden van de pagina. Dat is de verificatie. Als je in plaats daarvan op **Reject all** klikt, krijg je `'no'` in plaats van `'yes'`. Dat is even correct: de bezoeker is gevraagd en heeft nee gezegd.

Alleen `preferences`, `analytics` en `marketing` hoeven te veranderen. `sale_of_data` mag leeg blijven. Dat is normaal. Zie de opmerking onder Wat je niet moet gebruiken om te verifiëren.

|| Als de opdracht een foutmelding geeft dat `customerPrivacy` undefined is, is de API nog niet klaar met laden. Wacht even en probeer het opnieuw, of voer eerst één keer dit uit:

```javascript
window.Shopify.loadFeatures([{name: 'consent-tracking-api', version: '0.1'}], () => {});
```

#### Waarom currentVisitorConsent en niet marketingAllowed

Merchants controleren vaak alleen dit:

```javascript
window.Shopify.customerPrivacy.preferencesProcessingAllowed();  // true / false
```

Die methode is nuttig, maar kan alleen `true` of `false` antwoorden. In de documentatie van Shopify wordt uitgelegd dat deze methoden instellingen van de merchant, de locatie van de gebruiker en de toestemming van de gebruiker combineren.

`false` kan dus betekenen dat de bezoeker heeft geweigerd, of dat de bezoeker zich in een regio bevindt waar toestemming vereist is en nog niet heeft geantwoord. `true` kan betekenen dat de bezoeker heeft geaccepteerd, of dat deze regio geen toestemming vereist. De boolean alleen kan je niet vertellen of de bezoeker iets heeft besloten.

`currentVisitorConsent()` geeft de voorkeuren terug die de gebruiker heeft geselecteerd en mengt geen locatie of configuratie van de merchant erdoor:

```javascript
window.Shopify.customerPrivacy.currentVisitorConsent();
// → {marketing: 'yes', analytics: 'no', preferences: 'yes', sale_of_data: ''}
```

| Waarde | Betekenis |
| --- | --- |
| `''` (lege string) | De bezoeker heeft nog geen toestemming gegeven of geweigerd |
| `'yes'` | De bezoeker heeft actief toestemming gegeven |
| `'no'` | De bezoeker heeft actief toestemming geweigerd |

Leeg voordat de bezoeker besluit, ingevuld daarna. Die overgang is het bewijs dat Pandectes de beslissing naar Shopify heeft geschreven.

### Optie 2: On-Screen Theme Test

Dit fragment automatiseert de Quick Console Check. Het drukt de toestemmingsstatus af in de console wanneer de pagina laadt en opnieuw wanneer de bezoeker besluit. Het leest en logt alleen. Het wijzigt niets.

#### Waar je het themafragment plakt

1. Shopify admin → **Online Store → Themes**
2. Klik bij je live thema op **… → Edit code** *(veiliger: **Duplicate** eerst het thema en test op de kopie)*
3. Open `layout/theme.liquid`
4. Plak het fragment **direct vóór de afsluitende tag `</body>`**
5. **Save**

```html
{% comment %} PANDECTES CONSENT CHECK: temporary, remove after testing {% endcomment %}
<script>
(function () {
  var pandectesTag = '[Pandectes theme check]';

  function pandectesSnapshot(label) {
    var cp = window.Shopify && window.Shopify.customerPrivacy;
    if (!cp) {
      console.warn(pandectesTag, label, 'API not available');
      return;
    }

    var consent = cp.currentVisitorConsent();

    console.log('%c' + pandectesTag + ' ' + label, 'font-weight:bold;color:#0a7');
    console.table({
      'currentVisitorConsent().preferences' : consent.preferences,
      'currentVisitorConsent().analytics'   : consent.analytics,
      'currentVisitorConsent().marketing'   : consent.marketing,
      'currentVisitorConsent().sale_of_data': consent.sale_of_data,
      'preferencesProcessingAllowed()'      : cp.preferencesProcessingAllowed(),
      'analyticsProcessingAllowed()'        : cp.analyticsProcessingAllowed(),
      'marketingAllowed()'                  : cp.marketingAllowed(),
      'saleOfDataAllowed()'                 : cp.saleOfDataAllowed()
    });
  }

  document.addEventListener('visitorConsentCollected', function (event) {
    console.log(pandectesTag, 'visitorConsentCollected →', event.detail);
    pandectesSnapshot('AFTER the visitor decided');
  });

  (function pandectesWaitForShopify(tries) {
    tries = tries || 0;
    if (window.Shopify && window.Shopify.loadFeatures) {
      window.Shopify.loadFeatures(
        [{ name: 'consent-tracking-api', version: '0.1' }],
        function (error) {
          if (error) {
            console.error(pandectesTag, 'could not load the Customer Privacy API', error);
            return;
          }
          pandectesSnapshot('ON PAGE LOAD');
        }
      );
      return;
    }
    if (tries > 100) {
      console.error(pandectesTag, 'window.Shopify.loadFeatures never became available');
      return;
    }
    setTimeout(function () { pandectesWaitForShopify(tries + 1); }, 100);
  })();
})();
</script>
```

#### Hoe je de thematest uitvoert

Open je winkel in een **nieuw Incognito-venster**, open de **Console** en volg deze drie stappen.

**Stap 1: Voordat je de banner aanraakt**

De banner staat op het scherm. Je hebt nog nergens op geklikt. Zoek de tabel `ON PAGE LOAD`.

| Wat je zou moeten zien | Betekenis |
| --- | --- |
| `currentVisitorConsent().preferences` → `""` *(leeg)* | Nog geen beslissing genomen |
| `currentVisitorConsent().analytics` → `""` *(leeg)* | Nog geen beslissing genomen |
| `currentVisitorConsent().marketing` → `""` *(leeg)* | Nog geen beslissing genomen |
| `preferencesProcessingAllowed()` → `false` | Niets wat niet essentieel is, is toegestaan |
| `analyticsProcessingAllowed()` → `false` | Niets wat niet essentieel is, is toegestaan |
| `marketingAllowed()` → `false` | Niets wat niet essentieel is, is toegestaan |

De lege strings zijn het belangrijkste. Shopify geeft hiermee aan dat deze bezoeker nog niet heeft besloten.

**Stap 2: Klik op een knop in de banner**

Klik op **Accept all**. Er moeten direct twee dingen in de console verschijnen:

1. Een regel `visitorConsentCollected → {marketingAllowed: true, saleOfDataAllowed: …, analyticsAllowed: true, preferencesAllowed: true}`
2. Een tweede tabel, `AFTER the visitor decided`:

| Wat je zou moeten zien | Betekenis |
| --- | --- |
| `currentVisitorConsent().preferences` → `"yes"` | Toestemming actief gegeven |
| `currentVisitorConsent().analytics` → `"yes"` | Toestemming actief gegeven |
| `currentVisitorConsent().marketing` → `"yes"` | Toestemming actief gegeven |
| `preferencesProcessingAllowed()` → `true` | Verwerking is nu toegestaan |
| `analyticsProcessingAllowed()` → `true` | Verwerking is nu toegestaan |
| `marketingAllowed()` → `true` | Verwerking is nu toegestaan |

Als je in plaats daarvan op **Reject all** klikt, worden de waarden `"no"` en blijven de `Allowed()`-methoden `false`. `"no"` is niet hetzelfde als `""`: de bezoeker is gevraagd en heeft nee gezegd.

**Stap 3: Laad de pagina opnieuw**

Laad de pagina opnieuw en bekijk de nieuwe tabel `ON PAGE LOAD`. De waarden uit Stap 2 moeten er nog steeds zijn. Dat bewijst dat Shopify de beslissing heeft opgeslagen en op latere pagina's teruggeeft.

Als Stap 1, 2 en 3 zich gedragen zoals hierboven, schrijft de integratie toestemming naar Shopify.

||| Verwijder nu het fragment uit `layout/theme.liquid` en sla op. Laat het niet op een live thema staan. Het is een testtool en geen onderdeel van je winkel.

### Optie 3: Shopify Pixel Test

Het themafragment bewijst dat Shopify de beslissing heeft vastgelegd. Dit tweede fragment bewijst dat de beslissing de web pixels van Shopify bereikt (Google & YouTube, Meta, Klaviyo en elke aangepaste pixel).

Pixels draaien in een sandbox, los van je thema. Shopify geeft hun de toestemmingsstatus rechtstreeks door. Het fragment maakt een kleine testpixel die rapporteert wat hem is doorgegeven.

#### Waar je het pixelfragment plakt

1. Shopify admin → **Settings → Customer events**
2. Klik op **Add custom pixel** en geef hem de naam `Pandectes consent check`
3. Stel onder **Customer privacy** de **Permission** in op **Not required**, zodat deze testpixel altijd draait en ook de status "ervoor" kan rapporteren
4. Plak de code, klik op **Save** en vervolgens op **Connect**

```javascript
// Pandectes consent check. TEMPORARY test pixel. Disconnect and delete when finished.
const pandectesTag = '[Pandectes pixel check]';

function pandectesLog(label, cp) {
  console.log(pandectesTag + ' ' + label, {
    preferencesProcessingAllowed: cp.preferencesProcessingAllowed,
    analyticsProcessingAllowed:   cp.analyticsProcessingAllowed,
    marketingAllowed:             cp.marketingAllowed,
    saleOfDataAllowed:            cp.saleOfDataAllowed
  });
}

let pandectesConsentState = init.customerPrivacy;
pandectesLog('state when the pixel started', pandectesConsentState);

api.customerPrivacy.subscribe('visitorConsentCollected', (event) => {
  pandectesConsentState = event.customerPrivacy;
  pandectesLog('state after the visitor decided', pandectesConsentState);
});

analytics.subscribe('page_viewed', (event) => {
  pandectesLog('state at page_viewed', pandectesConsentState);
});
```

|| Waarom de lange variabelenamen? De pixel-sandbox definieert al globale variabelen zoals `status` en `name`, waardoor een gewone `let status = …` wordt gemeld als een herdefinitie. Elke naam in beide fragmenten heeft het voorvoegsel `pandectes`. Laat ze zoals ze zijn.

#### Wat je in de pixeltest zou moeten zien

Opnieuw in een nieuw Incognito-venster met de console open:

| Moment | Verwachte log |
| --- | --- |
| Pagina laadt, banner zichtbaar, nergens op geklikt | `state when the pixel started` → `preferencesProcessingAllowed`, `analyticsProcessingAllowed` en `marketingAllowed` zijn alle drie `false` |
| Je klikt op **Accept all** | `state after the visitor decided` → dezelfde drie zijn nu `true` |
| Je laadt de pagina opnieuw | `state when the pixel started` → de drie zijn nog steeds `true` |

`saleOfDataAllowed` maakt geen deel uit van deze controle. Buiten regio's met een opt-out voor de verkoop van gegevens kan deze vanaf het begin `true` zijn. Dat is te verwachten.

|| Deze regels komen uit de pixel-sandbox van Shopify, dus in Chrome verschijnen ze met een bron `web-pixels…sandbox` ernaast. Als je ze niet ziet, controleer dan of het consolefilter niet op "selected context only" staat en dat er geen filtertekst in het filtervak is getypt.

Als die drie waarden van `false` naar `true` gaan wanneer je op Accept klikt, geeft Shopify de toestemmingsstatus door aan pixels.

||| Koppel deze testpixel los en verwijder hem zodra je klaar bent. Hij is ingesteld om zonder toestemming te draaien en mag dus niet op een live winkel blijven staan.

### Zodra het signaal aankomt, is de rest een taak van Shopify

De web pixels van Shopify draaien in sandboxed cross-origin iframes die Shopify beheert. Geen enkele toestemmingsapp kan ze starten, stoppen of veranderen wat ze versturen. Het toestemmingssignaal is de hefboom die bestaat.

De verificatie bestaat uit twee delen:

1. **Komt het signaal aan?** Dat beantwoorden de bovenstaande controles. Dat is het deel waarvoor Pandectes verantwoordelijk is.
2. **Handelt Shopify naar het signaal?** Dat is een vraag voor Shopify, die wordt beantwoord in de instellingen van Shopify en, indien nodig, door Shopify support.

Als `currentVisitorConsent()` van leeg naar `'yes'` of `'no'` gaat wanneer de bezoeker klikt, heeft de app zijn werk gedaan. Als een pixel of kanaal zich daarna nog steeds anders gedraagt dan je verwachtte, zoek dan aan de kant van Shopify:

| Wie | Doet wat |
| --- | --- |
| **Pandectes** | Toont de banner, verzamelt de beslissing en schrijft die via `setTrackingConsent()` naar Shopify |
| **Shopify** | Bepaalt welke web pixels worden geladen in de winkel en in de checkout, schermt verkoopkanalen af en past toestemming toe op customer events, doelgroepen en checkout |

* **Settings → Customer events:** elke pixel heeft een eigen instelling **Customer privacy → Permission**. Een pixel die op *Not required* staat, draait ongeacht toestemming, omdat de winkel Shopify dat zo heeft opgedragen.
* **De eigen configuratie van elk verkoopkanaal.** Het kanaal Google & YouTube bouwt bijvoorbeeld zijn eigen Google-toestemmingssignaal op basis van de API van Shopify. Die vertaling is code van Shopify.
* **Shopify support**, voor alles wat overblijft nadat de API de juiste waarde bevat.

Zie het als een lichtschakelaar: Pandectes is de schakelaar, Shopify is de bedrading en de lampen. Zodra je hebt geverifieerd dat de schakelaar overgaat, is een lamp die aan blijft een kwestie van bedrading.

### Headless en aangepaste storefronts

Dezelfde API, dezelfde methoden en dezelfde betekenis van `''`, `'yes'` en `'no'` gelden voor een headless winkel. De Quick Console Check werkt ongewijzigd. Wat verandert, is hoe je de twee fragmenten uitvoert, plus één extra instelling.

#### Je hebt geen theme.liquid

Je winkelpagina's zijn je eigen code, dus er is nergens om het themafragment zoals het is te plakken. Twee opties:

**Optie A: plak het in de browserconsole (niets te deployen).**
Kopieer alles tussen `<script>` en `</script>` in het themafragment, open je winkel in een schoon Incognito-venster terwijl de banner zichtbaar is, plak het in de Console en druk op Enter. Je krijgt direct de tabel `ON PAGE LOAD`, en de tabel `AFTER the visitor decided` wanneer je op de banner klikt.

|| Code in de console wordt gewist door het opnieuw laden van de pagina. Laad voor de stap met opnieuw laden eerst de pagina opnieuw en plak het fragment daarna nogmaals om de opgeslagen waarden te lezen.

**Optie B: zet het in je eigen root layout.**
Voeg hetzelfde `<script>`-blok toe aan wat op elke pagina wordt gerenderd: de root layout in Hydrogen of Next.js, `index.html` in een Vite/React-app, enzovoort. Verwijder het zodra het testen klaar is.

#### Fragment 2 draait in de checkout, niet in je storefront

De web pixels van Shopify draaien niet op pagina's die je zelf host. Ze draaien op onderdelen die Shopify bezit: de **checkout** en de **orderstatus-/bedankpagina**. Om de uitvoer van het pixelfragment te zien, voeg je een product toe aan de winkelwagen en ga je met de console open verder naar de checkout. De toestemmingsbeslissing die op je storefront is genomen, zou al aanwezig moeten zijn wanneer de pixel start.

#### Eén extra instelling: je twee domeinen

Op een headless winkel heeft Shopify de domeinen van de storefront en de checkout nodig voordat het toestemming kan vastleggen. De documentatie van Shopify vereist deze waarden voor aangepaste storefronts:

* `headlessStorefront`
* `storefrontRootDomain`
* `checkoutRootDomain`
* `storefrontAccessToken`

Pandectes stuurt ze mee bij elke toestemmingsregistratie, vanuit je appconfiguratie. Als ze ontbreken of onjuist zijn in de Pandectes-admin, kan het schrijven naar Shopify niet slagen en blijft `currentVisitorConsent()` lege strings teruggeven. Als je headless test mislukt, controleer dan eerst deze waarden.

De domeinen moeten ook een passend paar vormen: het storefrontdomein en het checkoutdomein moeten bij dezelfde winkel horen, zodat de beslissing op de storefront dezelfde is als die de checkout ziet.

### Wat je niet moet gebruiken om te verifiëren

Deze controles meten ofwel iets anders, ofwel maken ze geen deel uit van de gedocumenteerde API.

#### Verwacht niet dat shouldShowBanner false wordt na toestemming

Veel merchants verwachten dat `shouldShowBanner()` vóór toestemming `true` is en daarna `false`, en melden een bug wanneer deze `true` blijft.

Het is geen toestemmingsmethode. Shopify documenteert het als een aanduiding of de huidige klant zich in een regio bevindt die is geconfigureerd om een cookiebanner te tonen. Een Duitse bezoeker is na Accept nog steeds in Duitsland, dus het antwoord is nog steeds `true`. Een `shouldShowBanner()` die na toestemming `true` blijft, is te verwachten.

Hetzelfde geldt voor `saleOfDataRegion()`, dat aangeeft of de huidige klant zich in een regio bevindt die is geconfigureerd voor opt-outs voor de verkoop van gegevens. Ook dat is een regiocontrole.

#### Vertrouw niet op getTrackingConsent, getRegulation of isRegulationEnforced

Deze komen niet voor in de documentatie van de Customer Privacy API van Shopify. Het zijn interne waarden die Shopify kan wijzigen of verwijderen. Met name het feit dat `getTrackingConsent()` vóór toestemming `"yes"` teruggeeft, is geen bewijs dat er iets is verleend.

#### Gebruik userCanBeTracked of userDataCanBeSold niet

Deze bestaan, maar Shopify vermeldt ze onder verouderde documentatie en zegt dat je er geen nieuwe integraties mee moet beginnen. Gebruik in plaats daarvan `currentVisitorConsent()` en de vier `Allowed()`-methoden.

#### Zoek niet naar een _tracking_consent-cookie in document.cookie

In de documentatie van Shopify staat dat je Shopify-cookies niet rechtstreeks moet lezen of wijzigen. Shopify belooft niet dat het toestemmingscookie via JavaScript leesbaar is, dat het een bepaalde naam heeft of dat het in een bepaalde release bestaat. Het niet vinden ervan bewijst niets.

#### Beoordeel de app niet op basis van of een pixel of netwerkverzoek nog steeds afgaat

Een verzoek dat de browser verlaat, is een uitkomst van Shopify. Als het toestemmingssignaal correct is en een Shopify-pixel toch afgaat, is Shopify het juiste verteld en heeft het ervoor gekozen de pixel te laten draaien, meestal omdat de **Permission** van die pixel op *Not required* staat in **Settings → Customer events**, of omdat het verkoopkanaal is geconfigureerd om zonder toestemming te draaien. Los het daar op.

#### Vergelijk geen items in window.dataLayer

De `dataLayer` is Google Consent Mode, een apart systeem van de Shopify Customer Privacy API. Pandectes schrijft naar beide en ook het kanaal Google & YouTube van Shopify schrijft eigen items. Meerdere `consent`-items daar zijn normaal en verifiëren de Shopify API niet.

#### Verwacht geen setTrackingConsent-aanroep bij elke paginalading

Pandectes schrijft alleen naar Shopify wanneer de status verandert. Als Shopify dezelfde beslissing al bevat, pusht de app die niet opnieuw. Bij een herlading na toestemming zou je de opgeslagen waarden moeten zien maar geen nieuwe schrijfactie.

#### Maak je geen zorgen als sale_of_data leeg blijft

`sale_of_data` is relevant waar een opt-out voor de verkoop van gegevens geldt (voornamelijk bepaalde Amerikaanse staten). Als de bezoeker zich niet in zo'n regio bevindt, of *Do not sell my data* niet is ingeschakeld in Pandectes, wordt dit veld weggelaten uit wat Pandectes verstuurt. Een lege `sale_of_data` voor een EU-bezoeker is te verwachten.

### Snelle referentie: de gedocumenteerde methoden

| Methode | Geeft terug | Wat het je vertelt |
| --- | --- | --- |
| `currentVisitorConsent()` | `{preferences, analytics, marketing, sale_of_data}` elk `'yes'` / `'no'` / `''` | De eigen beslissing van de bezoeker. Gebruik deze. |
| `preferencesProcessingAllowed()` | `true` / `false` | Of verwerking van voorkeuren is toegestaan (regio + instellingen + toestemming gecombineerd) |
| `analyticsProcessingAllowed()` | `true` / `false` | Of verwerking voor analyse is toegestaan (regio + instellingen + toestemming gecombineerd) |
| `marketingAllowed()` | `true` / `false` | Of marketing is toegestaan (regio + instellingen + toestemming gecombineerd) |
| `saleOfDataAllowed()` | `true` / `false` | Of het delen van gegevens met derden is toegestaan |
| `shouldShowBanner()` | `true` / `false` | Alleen regio: of in deze regio een banner moet worden getoond |
| `saleOfDataRegion()` | `true` / `false` | Alleen regio: of hier een opt-out voor de verkoop van gegevens geldt |
| `getRegion()` | bijv. `"DEHH"` | De locatie van de bezoeker, in ISO 3166-2-formaat |
| `visitorConsentCollected` event | `{marketingAllowed, saleOfDataAllowed, analyticsAllowed, preferencesAllowed}` | Wordt afgevuurd telkens wanneer toestemming verandert |

### Als de test echt mislukt

Bepaal eerst welke helft is mislukt.

**Als het signaal correct is**, dat wil zeggen dat `currentVisitorConsent()` van leeg naar `'yes'` of `'no'` gaat wanneer je klikt, dan schrijft de app toestemming. Al het andere is van Shopify. Controleer de **Permission** van elke pixel in **Settings → Customer events**, daarna de configuratie van verkoopkanalen en vervolgens Shopify support.

**Als het signaal ontbreekt**, dat wil zeggen dat `currentVisitorConsent()` nog steeds lege strings teruggeeft nadat je op een bannerknop hebt geklikt, controleer dan in deze volgorde:

1. De Pandectes app embed is ingeschakeld in het thema dat je test (Online Store → Themes → Customize → App embeds).
2. Je test het live thema, niet een voorbeeld van een ander thema.
3. Er is geen andere toestemmingsapp geïnstalleerd. Twee toestemmingsapps die naar dezelfde API schrijven, conflicteren. Er mag er maar één actief zijn.
4. Je zit niet in een adminvoorbeeldsessie, die zich anders kan gedragen dan een echt bezoek.
5. Alleen voor headless winkels: het storefrontdomein, het checkoutdomein en de storefront access token zijn correct ingevuld in de Pandectes-admin.

Werkt het nog steeds niet? Neem contact op via **support@pandectes.io** en voeg het volgende toe:

* je winkeldomein (en bij headless je storefront- en checkoutdomeinen)
* het land van de bezoeker waarmee je hebt getest
* de console-uitvoer van de Quick Console Check of van het themafragment, op alle drie de momenten (voor het klikken / na het klikken / na het opnieuw laden)

### Ruim op wanneer je klaar bent

Sla deze stap niet over. De Quick Console Check installeert niets. Beide fragmenten zijn tijdelijk.

1. **Themafragment:** open `layout/theme.liquid`, verwijder het blok dat begint met `{% comment %} PANDECTES CONSENT CHECK` en **Save**. Als je op een gedupliceerd thema hebt getest, kun je die themakopie verwijderen.
2. **Pixelfragment:** ga naar **Settings → Customer events**, open `Pandectes consent check`, **Disconnect** de pixel en **Delete** hem vervolgens.
3. **Headless winkels:** als je het script aan je eigen layout hebt toegevoegd, verwijder het dan en deploy opnieuw. Als je de browserconsole hebt gebruikt, volstaat het om het tabblad te sluiten.

Waarom dit belangrijk is:

* Het themafragment drukt toestemmingsdetails af in de console van elke bezoeker, op elke pagina, totdat je het verwijdert.
* De testpixel is geconfigureerd met **Permission: Not required**, dus hij draait bewust vóór toestemming. Dat is correct voor een korte test en fout voor een live winkel.
* Beide voegen werk toe aan elke paginalading zonder voordeel zodra de verificatie klaar is.

Het verwijderen ervan verandert niets aan de integratie. De app blijft toestemming aan Shopify rapporteren zoals voorheen.

### Samenvatting

Verifieer deze integratie met `currentVisitorConsent()`. Lege strings vóór een keuze, `'yes'` of `'no'` direct erna en dezelfde waarden na het opnieuw laden betekenen dat Pandectes de beslissing naar Shopify heeft geschreven. Het laden van pixels, verkoopkanalen en het gedrag van de checkout daarna zijn de verantwoordelijkheid van Shopify. Verwijder alle tijdelijke thema- of pixelfragmenten wanneer je klaar bent.