# Onay Yönetimi (Consent)

KVKK/GDPR çerez onayı entegrasyonu
Kaynak: https://selwise.com/docs/integration/consent

Selwise, KVKK ve GDPR uyumluluğu için çerez onayı denetimini destekler. Onay denetimi etkinleştirildiğinde, ziyaretçi cevap verene kadar olaylar **bekletilir** ve cevap gelince gönderilir. Bu sayfa teknik tarafı anlatır: tarayıcı API'si, kendi onay çözümünüzle entegrasyon, kararın nerede saklandığı ve sunucuya nasıl bildirildiği. Panel ekranının sekme sekme anlatımı için [Çerez Onayı](/docs/customers/consent) sayfasına bakın.

Onay denetimi varsayılan olarak **kapalıdır**: kapalıyken her olay hiç sorulmadan gönderilir. Kişisel veri ya da izleme çerezi kullanıyorsanız açmanız önerilir.

## Her şey tek ekranda

Çerez onayının tamamı (banner'ın görünürlüğü, metni, tasarımı, konumu ve onay politikası) panelde **Kitle → Çerez Onayı** (Audience → Cookie Consent) ekranından yönetilir. Başka hiçbir ekran bu ayarları yazmaz.

## Onay kategorileri

| Kategori | Açıklama |
| --- | --- |
| `necessary` | Teknik olarak zorunlu: yalnızca widget'ın kendi hata kaydı (`script_injected`, `script_error`). Her zaman verilmiş sayılır |
| `analytics` | Ziyaretçinin yaptığı: sayfa ve ürün görüntüleme, sepet, ödeme, sipariş, arama, kimlik eşleştirme (`identify`) |
| `marketing` | Bir Selwise yüzeyinin ziyaretçiye gösterdiği ve ona verilen cevap: gösterim, tıklama, kapatma, deney gösterimi; ayrıca ziyaretçinin geçmişinden içerik seçmek (segment, kişisel öneri, senaryo) |
| `preferences` | Kullanıcı tercihleri |

Sayfa görüntüleme ve tıklama zorunlu değildir: mağaza onlar olmadan da çalışır. Listede adı geçmeyen bir olay `analytics` sayılır. Liste widget, mobil SDK ve sunucu için tektir; sunucu da her olayı kendi kategorisine göre denetler ve izin verilmeyen olayı kaydetmez.

## Onay olaylardan fazlasını kapsar

Olay dışındaki istekler de ziyaretçinin cevabını sorar:

| İstek | Gerekli kategori | Onay yoksa |
| --- | --- | --- |
| Kimlik eşleştirme (`identify`), müşteri özellikleri | `analytics` | Kimlik sayfada kalır, sunucuya gitmez; cevap bekleniyorsa onay gelince gönderilir |
| Sipariş (`trackOrder` ve her `purchase` olayı) | `analytics` | Sipariş **her zaman** kaydedilir, ama ziyaretçi, oturum ve temas bilgisi olmadan: hiçbir kampanyaya atfedilmez. Bandı hiç yanıtlamayan ziyaretçi de böyledir (teşekkür sayfasından sonra bekleyecek sayfa yoktur). Siparişin kaynağı fark etmez: kendi veri katmanınız, mağazanın kendi `dataLayer`'ı (IdeaSoft, GA4) ya da `Selwise.trackOrder`. Bu durumda cihazdan son temas ve deney bilgisi de okunmaz |
| A/B testleri (varlık ve sayfa deneyleri) | `marketing` | Ziyaretçi hiçbir teste girmez, orijinal içeriği görür; kişiselleştirme (herkese uygulanan deney) uygulanmaya devam eder |
| Segment sorgusu, kişisel öneri, senaryo gelen kutusu | `marketing` | Ziyaretçi hiçbir segmentte sayılmaz; öneri şeridi sayfadaki ürün ve sepetten çizilir; senaryo adımı gösterilmez |
| Öneri ve arama geri bildirimleri | Olayın kategorisi | Gönderilmez |

Bir kampanyayı ya da sayfa deneyini yalnızca onay veren ziyaretçilere göstermek için hedeflemede **Çerez onayı** koşullarını kullanın: [Davranış Kuralları](/docs/campaigns/behavior-rules).

**Ziyaretçi sayısı onaydan bağımsızdır.** Widget her sayfa görüntülemesinde, onay verilmiş olsun ya da olmasın, kimlik taşımayan tek bir sayım isteği gönderir: yalnızca ziyaretin nereden geldiği (doğrudan, arama, sosyal, reklam, yönlendirme), bu sayfanın ziyareti başlatıp başlatmadığı ve ziyaretçinin o anki onay durumu (izin verdi, reddetti, yanıtlamadı, bant yok). Ziyaretçi ya da oturum kimliği, adres, sayfa adresi gönderilmez; cihaza bu sayım için hiçbir şey yazılmaz. Sunucu cihaz türünü ve ülkeyi ekleyip günlük toplamlara işler. Bu, KVKK Çerez Rehberi'nin (Temmuz 2025) 5.9 maddesindeki, açık rıza gerektirmeyen birinci taraf kitle ölçümüdür. Toplamlar **Cookie Consent** → **Analytics** sekmesindeki "Bandın dışında kalanlar" kartında görünür: ölçülen, reddeden ve bandı yanıtlamayan ziyaretçilerin sayfa payı ile bandın yanıtlanma oranı. Ziyaretçi analitiğine eklenmez, bu yüzden kimse iki kez sayılmaz.

**Ürün ve sepet sayımı da onaydan bağımsızdır.** Aynı kural ürün görüntüleme, sepete ekleme ve ödemeye başlama için de geçerlidir: widget her ziyaretçi için yalnızca eylemi ve ürün kodunu, kimlik olmadan sayar (sayfa başına tek istek). **Product Performance** (Ürün Performansı) ekranındaki **tüm trafik** sütunları buradan gelir; yanlarındaki görüntülenme ve sepete ekleme sütunları yalnızca takip izni veren ziyaretçileri kapsar ve ikisi hiçbir yerde toplanmaz. Sayım başladığı günden önceki bir aralık için tüm trafik sütunları boş kalır.

**IP adresi.** İzleme olayları ve çerez onayı kayıtları ziyaretçinin tam IP adresini saklamaz: IPv4'te son blok sıfırlanır (`85.105.12.0`), IPv6'da ilk 48 bit tutulur. Ülke tespiti ve hız sınırları canlı istekten yapılır.

## Karar nasıl çözülür

Widget "bu ziyaretçi için izin var mı" sorusunu şu sırayla cevaplar; ilk bulduğu kazanır:

1. **Ziyaretçinin kendi kayıtlı cevabı.** Siz denetimi sonradan kapatsanız bile geçerlidir: bu bir ayar değil, ziyaretçinin kendi verisi hakkındaki kararıdır.
2. Onay denetimi **kapalıysa**: herkese tüm kategoriler açık sayılır (başka hiçbir sinyal okunmaz).
3. Canlı bir CMP sinyali (IAB TCF v2 ya da Google Consent Mode v2).
4. Sizin `window` değişkeniniz.
5. Politika: cevap beklenmiyorsa (**Hold events until the answer** kapalı) tümü açık sayılır. Bekleniyorsa ve ziyaretçi cevap vermemişse durum **cevap bekleniyor**dur ve olaylar tutulur; **Apply consent when there is no answer** açıksa cevapsızlık onay sayılır.

## Politika alanları

**Cookie Consent** → **Policy** (Politika) sekmesinde:

| Alan | Varsayılan | Açıklama |
| --- | --- | --- |
| **Require consent before tracking** (Takipten önce onay iste) | Kapalı | Onay denetimini açar |
| **Category-level consent** (Kategori bazlı onay) | Kapalı | Ziyaretçi kategori kategori cevap verir |
| **Categories** → **Always on** (Her zaman açık) | `necessary` | Ziyaretçinin **kapatamayacağı** kategoriler. Ön işaretli değil, kapatılamaz demektir |
| **Hold events until the answer** (Cevaba kadar olayları beklet) | Kapalı | Açıkken olaylar atılmaz, kuyruğa alınır |
| **Apply consent when there is no answer** (Cevap gelmezse onay verilmiş say) | Kapalı | Süre dolunca cevapsız banner'ı onay sayar |
| **Write no visitor data to the device until consent** (Onaya kadar cihaza ziyaretçi verisi yazma) | **Açık** | Analitiğe izin verilene kadar kimlikler (ziyaretçi, oturum, yolculuk) ve ziyaretçinin yaptıklarına dair her kayıt (son temaslar, sepet ve ödeme durumu, davranış sayaçları) yalnızca sayfanın belleğinde tutulur, cihaza yazılmaz; izin verilince yazılır, reddedilince silinir. KVKK Çerez Rehberi ve ePrivacy m.5/3 cihaza yazmanın kendisi için de onay ister; kapatmanız önerilmez. **Hold events until the answer** açıkken etkilidir |
| **Timeout** (Bekleme süresi) | 5000 ms | 0 süresiz bekler |

> **Ön işaretli kutu geçerli onay değildir**
>
> "Her zaman açık" işaretlediğiniz bir kategori banner'da kilitli görünür ve kapatılamaz. Zorunlu olanın ötesindeki kategoriler için bu, onayın özgür iradeyle verilmesi ilkesiyle çelişebilir (GDPR, Planet49 C-673/17). Kendi hukuk sürecinizle değerlendirin.

## Kendi onay çözümünüzle entegrasyon

### Otomatik algılanan iki standart

Ayar gerekmez (onay denetimi açıkken). Veri katmanı kapalı olsa da çalışır:

- **IAB TCF v2** (`window.__tcfapi`): amaç 1 depolama izni, 7-10 analitik, 2-4 pazarlama olarak eşlenir. CMP widget'tan sonra yüklense de karar okunur.
- **Google Consent Mode v2**: `gtag('consent', …)` çağrıları `window.dataLayer`'da (ve tanımladıysanız kendi veri katmanı adınızda) okunur; widget'tan önce ve sonra yapılan çağrıların ikisi de geçerlidir.

İkisi birden varsa TCF kazanır. Bu iki yoldan gelen karar tarayıcıda uygulanır; sunucuya ayrıca bir onay kaydı yazılmaz (panelin **Analytics** sekmesi yalnızca Selwise banner'ını ve aşağıdaki yöntemleri sayar).

### Programatik API

```js
// Mevcut kararı oku: henüz cevap yoksa null
const state = window.Selwise.getConsentState();
// -> { necessary: true, analytics: false, marketing: false, preferences: false } | null

// Onay ver (tümü veya seçili kategoriler)
window.Selwise.grantConsent();
window.Selwise.grantConsent({ analytics: true, marketing: false });

// Onayı geri çek
window.Selwise.revokeConsent();
window.Selwise.revokeConsent(['marketing']);

// Banner'ı yeniden aç (ziyaretçi fikrini değiştirsin diye)
window.Selwise.showConsentPreferences();

// Kararı tamamen unut ve yeniden sor
window.Selwise.withdrawConsent();
```

`grantConsent` / `revokeConsent` karar yazıldığında sunucuya da bildirilir (`action: api`) ve bekletilen olaylar serbest bırakılır. Yöntemlerin ayrıntısı: [JavaScript API](/docs/integration/javascript-api#onay-consent). Bu yöntemler komut kuyruğuna girer: onay çözümünüz widget'tan önce çalışsa bile çağrılar kaybolmaz.

Kendi banner'ınızla entegre etmek için:

```html
<script>
  document.querySelector('#cookie-accept')?.addEventListener('click', function () {
    window.Selwise?.grantConsent({ analytics: true, marketing: true });
  });

  document.querySelector('#cookie-reject')?.addEventListener('click', function () {
    window.Selwise?.revokeConsent();
  });
</script>
```

Bu üç yöntem veri katmanından bağımsız çalışır: veri katmanı kapalı olsa da karar yazılır ve bekletilen olaylar serbest bırakılır. Selwise'in kendi banner'ını kullanmıyorsanız **Show the Selwise consent banner** ayarını kapalı bırakın ve kararı bu yöntemlerle bildirin.

### Karar değiştiğinde sizi çağırması

**Policy** → **Your own consent solution** (Kendi onay çözümünüz) altındaki **Change callback** (Değişiklik fonksiyonu) alanına global bir fonksiyon adı yazarsanız karar her değiştiğinde `callback('granted' | 'denied', snapshot)` çağrılır (`granted`: zorunlu dışında en az bir kategoriye izin var; kategori ayrıntısı `snapshot.categories` içindedir); örneğin kararı etiket yöneticinize iletmek için. Fonksiyon hata fırlatsa bile karar yine kaydedilir.

### Window değişkeni

Ne TCF ne Consent Mode yayımlayan bir çözüm için **Policy** → **Your own consent solution** → **Consent variable name** (Onay değişkeni adı) alanında bir window değişkeni adı belirtebilirsiniz (varsayılan `__wcmp_consent`). Şu değerleri anlar: `true`/`false`, `1`/`0`, `'granted'`/`'denied'` ve `{ analytics, marketing, preferences }` ya da `{ all: true }` biçiminde bir nesne.

## Reddeden ve yanıtlamayan ziyaretçi için ne olur

- **Olaylar.** Reddedilen kategorideki olay hiç gönderilmez; ziyaretçi sonradan izin verse de geriye dönük gönderilmez, izin o andan sonrası içindir. Bandı henüz yanıtlamamış ziyaretçinin olayları sayfada bekletilir; yanıt gelince izin verilenler gider, gelmezse hiçbiri gitmez.
- **Sipariş.** Her durumda kaydedilir, kimliksiz ve atıfsız (yukarıdaki tablo).
- **Cihaz.** Varsayılan ayarla, izin gelene kadar cihaza ziyaretçiye dair hiçbir şey yazılmaz. Yazılabilenler ziyaretçiyle değil ekranla ilgilidir: onay cevabının kendisi, kapatılan bir kampanyanın tekrar gösterilmemesi için sıklık sınırları, bildirim isteğine verilen cevap.
- **Sayım.** Sayfa görüntüleme, ürün görüntüleme, sepete ekleme ve ödemeye başlama kimliksiz olarak sayılır (yukarıda).
- **Kişiselleştirme.** Kampanyalar gösterilir (segment hedefli olanlar hariç); öneriler sayfadaki ürün ve sepete göre çizilir; arama çalışır. A/B testine girilmez.

## Karar nerede saklanır

localStorage'da, `selwise_consent_<siteKey>` anahtarında (`siteKey` kanalınızın anahtarıdır). Ön ek **Storage key** (Saklama anahtarı) alanıyla değiştirilebilir; Selwise eski anahtarı da okumaya devam eder, böylece mevcut ziyaretçilere ikinci kez sorulmaz. Saklanan değer `{ granted, timestamp, categories, source }` biçimindedir; `granted: true` "ziyaretçi **cevap verdi**" demektir (reddetmek dahil), asıl karar `categories` içindedir.

## Onayın geri çekilmesi

Geri çekmek, vermek kadar kolay olmalıdır (GDPR Madde 7(3)). Banner'ı yeniden açmanın iki yolu vardır:

1. **Cookie Consent** → **Banner** → **Show a persistent preferences button** (Kalıcı tercih butonunu göster)
2. Kendi sayfanızdaki bir bağlantıya öznitelik ekleyin:

```html
<a href="#" data-selwise-consent>Çerez tercihleri</a>
```

Öznitelik taşıyan öğeye tıklamak banner'ı yeniden açar. Programatik yol: `showConsentPreferences()`. Kararı tamamen silmek için `withdrawConsent()`.

## Sunucuya onay kaydı

Banner cevabı otomatik olarak kaydedilir. Kendi çözümünüzü kullanıyorsanız ve kararı sunucuya kendiniz yazmak istiyorsanız doğrudan da çağırabilirsiniz; alan ayrıntıları ve yanıtlar için [Onay ve Bülten API'si](/docs/api-reference/consent-newsletter-api) sayfasına bakın.

### Onay kaydet

```bash
curl -X POST https://api.selwise.com/api/v1/public/sites/SITE_KEY/consent \
  -H "Content-Type: application/json" \
  -H "Origin: https://magaza.com" \
  -d '{
    "categories": { "necessary": true, "analytics": true, "marketing": false, "preferences": true },
    "visitorId": "VISITOR_ID",
    "sessionId": "SESSION_ID",
    "action": "accepted"
  }'
```

`categories` zorunludur ve dört kategoriyi de taşımalıdır. `action` alanı panelde **Cookie Consent** → **Analytics** → *Consent Methods* (Onay Yöntemleri) dağılımını belirler: `accepted` ve `declined` banner, `customized` ayar ekranı, `timeout` varsayılan, diğer her şey programatik sayılır.

### Onayı geri çek (silme talebi)

```bash
curl -X DELETE https://api.selwise.com/api/v1/public/sites/SITE_KEY/consent \
  -H "Content-Type: application/json" \
  -H "Origin: https://magaza.com" \
  -d '{ "visitorId": "VISITOR_ID" }'
```

Yanıt, istemcide yapılması gereken temizliği de bildirir (`clientAction`); `storageKey` sizin yapılandırdığınız anahtardır. Sunucu tarayıcı depolamasını silemez; temizliği çağıran taraf yapar (widget'ın `withdrawConsent()` yöntemi ikisini birlikte yapar).

> **Bekleyen olaylar kaybolmaz**
>
> **Hold events until the answer** açıkken onay gelmeden hiçbir olay gönderilmez; olaylar bellekte kuyruğa alınır ve onay verilir verilmez gönderilir. Kuyruk sınırlıdır (en yeni 200 olay), bu yüzden banner'ı sayfa yükünde hızlı gösterin. Sunucu tarafı gönderimde `consentSnapshot.granted` değerinin anlamı için [Olay Gönderimi](/docs/api-reference/events-ingest) sayfasına bakın.

## Pazarlama izni ayrı bir konudur

Bu sayfa **çerez onayını** anlatır: bir tarayıcının izlenmeye verdiği cevap. Bir kişinin e-posta ya da SMS ile pazarlanmaya izin vermesi başka bir kayıttır ve başka uçlardan yazılır (sipariş sırasında `marketingConsent`, bülten kaydı, sunucudan `contacts/consent`): [Onay ve Bülten API'si](/docs/api-reference/consent-newsletter-api).
