Teknik Doküman · Entegrasyon & Güvenlik

Güventik Widget'ı sitenizde ne yapar?

Sitenize üçüncü taraf bir script eklemek bir güven kararıdır. Bu doküman, widget'ın kaynak kodunda gerçekte ne yaptığını — hangi DOM düğümlerini eklediğini, hangi ağ isteklerini attığını, hangi verileri sakladığını ve hangilerini asla toplamadığını — teknik ekiplerin doğrulayabileceği düzeyde açıklar.

Hedef kitle: geliştirici / güvenlik ekibi Widget sürümü: v2 API: api.guventik.com Script: guventik.com/widget/widget.js
15,7 KB
gzip'li JS
boyutu
1
sayfanıza eklenen
DOM düğümü
0
çerez
(cookie)
0
analitik / reklam
pikseli
0
saklanan
IP adresi
3
global JS
fonksiyonu
§ 01

Özet

Güventik Widget, mağazanızın doğrulanmış müşteri yorumlarını ziyaretçilerinize gösteren ve ödeme sayfasında yorum daveti sunan tek dosyalık bir JavaScript bileşenidir. Sayfanıza tek satırla eklenir:

<!-- Güventik Widget -->
<script src="https://guventik.com/widget/widget.js" data-slug="123"></script>

Teknik açıdan üç cümlelik özeti şudur:

  • İzole çalışır. Tüm arayüz bir Shadow DOM içinde oluşturulur. Sitenizin CSS'i widget'ı, widget'ın CSS'i sitenizi etkileyemez. Sayfanızın <body> ağacına tek bir boş <div> eklenir.
  • Pasif veri toplamaz. Çerez kullanmaz, parmak izi çıkarmaz, form alanlarını, sepet içeriğini veya DOM'unuzu okumaz. Sunucuya yalnızca sayfa URL'si, referrer ve anonim bir oturum kimliği gider.
  • Kişisel veri yalnızca açık rızayla alınır. E-posta ve telefon, ziyaretçi bunları ödeme sonrası açılan pencereye kendisi yazdığında ve KVKK onay kutusunu işaretlediğinde toplanır — sayfanızdaki alanlardan okunarak değil.
Bu dokümanı nasıl doğrularsınız

Widget'ın kaynağı küçültülmemiş (unminified) ve yorum satırlarıyla birlikte yayınlanır. widget.js dosyasını doğrudan açıp bu dokümandaki her iddiayı satır satır karşılaştırabilirsiniz. Ağ trafiğini de tarayıcı geliştirici araçlarının Network sekmesinden api.guventik.com filtresiyle gözlemleyebilirsiniz.

§ 02

Yükleme akışı

Script bir IIFE olarak paketlenmiştir; global kapsama sızıntı yapmaz. Yürütme sırası tam olarak şöyledir:

  1. Yapılandırma okunur. Mağaza kimliği data-slug özniteliğinden veya window.guventikSlug değişkeninden alınır. Sunucu adresi, localhost dışında her zaman https://api.guventik.com/api olarak sabittir.
  2. DOM hazır olması beklenir. Yürütme DOMContentLoaded sonrasına ertelenir. Bu noktaya kadar sayfanızın render'ına hiçbir müdahale olmaz.
  3. Oturum kaydı açılır. POST /api/stores/{id}/sessions çağrısıyla anonim bir oturum GUID'i alınır ve sessionStorage'a yazılır (bkz. § 04).
  4. Mağaza verisi çekilir. Puan, yorum listesi ve widget ayarları paralel fetch istekleriyle alınır. Hepsi salt okunur uçlardır.
  5. Shadow host oluşturulur. <div id="__gvntk_host" style="all:initial"> düğümü yaratılır ve üzerine bir shadow root iliştirilir. Tüm markup ve stil bu kökün içinde kalır.
  6. Görünürlük kontrolü yapılır. Widget yalnızca mağaza aktifse ve sayfanın origin'i mağazanın kayıtlı alan adıyla eşleşiyorsa <body>'ye eklenir. Eşleşme yoksa host düğümü DOM'a hiç eklenmez.
  7. Görünür hale getirilir. Widget, kendi stil dosyası uygulanana kadar visibility: hidden durumunda tutulur; böylece stilsiz bir an (FOUC) yaşanmaz. Stil dosyası hiç gelmezse 3 saniyelik emniyet zamanlayıcısı devreye girer.
Entegrasyon notu — async / defer

Script etiketini async veya defer ile yüklerseniz tarayıcı document.currentScript değerini null döndürür ve data-slug okunamaz. Bu durumda mağaza kimliğini script'ten önce global değişkenle verin: <script>window.guventikSlug = "123";</script>

§ 03

Sitenize etkisi

Bu bölüm, "bu script sitemi yavaşlatır mı, bir şeyleri bozar mı" sorusunun ölçülebilir cevabıdır.

Ağırlık

DosyaHamGzipNot
widget.js62 KB15,7 KBAna bileşen; bağımlılığı yoktur
widget.css13 KB3,6 KBShadow root içine yüklenir
widget-nav.js25 KB7,0 KBOpsiyonel — menü içi rozet varyantı

Framework, bundler veya çalışma zamanı kütüphanesi yoktur — saf JavaScript. Karşılaştırma için: tipik bir jQuery kopyası gzip'li 30 KB civarındadır.

DOM ayak izi

Eklenen düğümNereyeNe zaman
div#__gvntk_hostbody sonuHer zaman (görünürlük kontrolü geçerse)
link[Font Awesome]headYalnızca sayfanızda Font Awesome yoksa
link[DM Sans]headYalnızca sayfanızda bu font yoksa
div#gvntk-overlaybody sonuYalnızca ödeme sayfasında; kapatılınca kaldırılır

Host düğümüne all: initial uygulanır, yani sitenizden hiçbir stil miras almaz. Font Awesome ve DM Sans, sayfanızda zaten varsa tekrar yüklenmez — sürüm çakışması yaratmamak için bu kontrol bilinçlidir.

Global kapsam

Widget yalnızca üç fonksiyon tanımlar: window.widgetOpen, window.widgetClose, window.widgetAction. Başka hiçbir global değişken, prototip genişletmesi veya polyfill eklenmez.

Tarayıcı API'lerine müdahale

Tam şeffaflık — bilmeniz gereken tek yan etki

Mağazanız için bir ödeme sayfası URL'si tanımlıysa, widget history.pushState ve history.replaceState fonksiyonlarını sarmalar. Bunun tek amacı, tam sayfa yenilemesi olmadan adım değiştiren SPA checkout akışlarını yakalamaktır. Sarmalayıcı önce orijinal fonksiyonu değiştirmeden çağırır, ardından yalnızca URL eşleşmesini kontrol eder; dönüş değerini veya davranışını değiştirmez. Ödeme URL'si tanımlı değilse bu sarmalama hiç yapılmaz.

Hata dayanıklılığı

  • Tüm ağ çağrıları try/catch ve .catch() ile sarılıdır. API erişilemezse widget sessizce görünmez — sayfanıza istisna fırlatmaz, window.onerror tetiklemez.
  • Hiçbir istek sayfanın render'ını veya load olayını bloke etmez; tamamı asenkron fetch'tir.
  • Widget konumu, yapılandırılmış kaydırma değerleri ne olursa olsun ekran dışına taşmayacak şekilde sınırlanır (her eksende en fazla görünüm alanının yarısı).
  • Konsola birkaç tanılama satırı yazılır ([Widget] v2 loaded…). Destek taleplerini hızlandırmak içindir; hata seviyesinde değildir.
§ 04

Toplanan veriler

Toplanan alanların tamamı aşağıdadır. Liste veritabanı şemasından birebir çıkarılmıştır; başka bir alan yazılmaz.

Oturum kaydı — Sessions

AlanDeğerNasıl elde edilir
SessionIdRastgele GUIDSunucuda üretilir; kişiden türetilmez
StoreIdMağaza numarasıScript etiketindeki slug
StartedAt / LastSeenAtUTC zaman damgasıSunucu saati
DeviceTypemobile / desktopUser-Agent başlığından sunucu tarafında sınıflandırılır; UA metni saklanmaz
WidgetOpened0 / 1Ziyaretçi paneli fiilen açtığında 1 olur
PaymentPageVisited0 / 1Ödeme sayfası URL eşleşmesinde 1 olur
ReviewRequested0 / 1Ziyaretçi yorum daveti formunu gönderdiğinde 1 olur

Sayfa görüntüleme — PageViews

AlanDeğerSınır
PageUrlwindow.location.href2000 karakterde kesilir
Referrerdocument.referrer2000 karakterde kesilir; boşsa null
ViewedAtUTC zaman damgası
URL'ler hakkında

Sayfa URL'si sorgu parametreleriyle birlikte kaydedilir. Checkout URL'lerinizde token, oturum anahtarı veya müşteri kimliği gibi hassas parametreler taşıyorsanız, bunları bize iletmemek için mağaza panelinden yalnızca yol bazlı bir ödeme URL'si tanımlamanızı öneririz.

Oturum kimliğinin saklanması

  • Çerez kullanılmaz. Kimlik tek bir sessionStorage anahtarında tutulur: gvntk_session_<magazaId>.
  • sessionStorage sekme kapandığında silinir — kalıcı takip yoktur.
  • Depolama origin bazlıdır; kimlik sitenizin origin'inde kalır, başka bir siteye taşınmaz. Siteler arası takip teknik olarak mümkün değildir.
  • Kimlik mağaza bazında ayrılır; aynı ziyaretçi başka bir Güventik mağazasında farklı bir oturum kimliği alır.

Kişisel veri — yalnızca açık rızayla

Ödeme sayfasında açılan pencerede ziyaretçi kendi yazdığı e-posta adresini ve (yalnızca SMS onayı işaretlenmişse) telefon numarasını gönderebilir. E-posta için KVKK onay kutusu işaretlenmeden gönder düğmesi etkinleşmez; telefon alanı SMS onayı verilmeden açılmaz bile. İki rıza birbirinden bağımsız kaydedilir. Ayrıntı için KVKK Aydınlatma Metni.

§ 05

Toplamadıklarımız

Güvenlik incelemelerinde en sık sorulan başlıklar. Aşağıdakilerin hiçbirini yapan kod widget'ta bulunmaz:

IP adresi saklamak. Sessions tablosunda IP sütunu yoktur.
Çerez yazmak. Ne birinci ne üçüncü taraf.
Parmak izi çıkarmak. Canvas, WebGL, font veya cihaz numaralandırması yok.
Form alanlarını okumak. Sayfanızdaki input'lara hiç erişilmez.
Sepet veya sipariş içeriğini okumak. Ürün, tutar, adet bilgisi alınmaz.
DOM'unuzu taramak. İçerik, fiyat veya metin kazıma yapılmaz.
Tuş vuruşu veya fare kaydı. Session replay teknolojisi kullanılmaz.
Reklam / analitik pikseli. GA, Meta Pixel, GTM veya benzeri hiçbir etiket yüklenmez.
Veri satmak veya paylaşmak. Toplanan veri yalnızca mağazanızın kendi panelinde görünür.
Uzaktan kod çalıştırmak. eval, new Function veya dinamik script enjeksiyonu yok.
iframe açmak. Widget sayfanıza çerçeve gömmez.
Sayfanızı yönlendirmek. location değiştirilmez.
§ 06

Ödeme sayfası tespiti

Yorum daveti penceresi rastgele değil, mağaza panelinden sizin tanımladığınız URL'de açılır. Eşleştirme kuralı katıdır:

  • Origin ve yol birebir eşleşmeli. Karşılaştırma büyük/küçük harf duyarsızdır ve sondaki eğik çizgi yok sayılır.
  • Tanımladığınız sorgu parametrelerinin tamamı mevcut URL'de aynı değerle bulunmalıdır. Sayfadaki fazladan parametreler eşleşmeyi bozmaz.
  • Ödeme URL'si tanımlı değilse pencere hiçbir koşulda açılmaz ve history sarmalaması da yapılmaz.
  • Pencere oturum başına en fazla bir kez gösterilir; ziyaretçi checkout adımları arasında gidip gelse bile tekrar açılmaz.
  • Eşleşme sağlandığında pencere 800 ms gecikmeyle açılır, böylece sayfanızın kendi yükleme animasyonlarının üzerine binmez.

Pencere, ziyaretçinin ödeme akışını kesmez: ödeme formunuzun üzerine modal olarak gelir, kapatılabilir ve kapatıldığında DOM'dan tamamen kaldırılır. Ödeme işleminizin hiçbir aşamasına müdahale etmez.

§ 07

Güvenlik önlemleri

İstemci tarafı

ÖnlemUygulama
XSS koruması API'den gelen her dinamik metin (< > & ") DOM'a yazılmadan önce HTML entity'lerine dönüştürülür. Yorum metni, isim ve kupon açıklaması dahil istisnasız uygulanır.
Stil izolasyonu Shadow DOM sınırı iki yönlüdür — sayfanızın stilleri içeri, widget'ın stilleri dışarı sızamaz.
Alan adı doğrulaması Widget yalnızca mağazanın kayıtlı web sitesinde render edilir. Script'i kopyalayıp başka bir alan adına koyan biri mağazanızın arayüzünü elde edemez.
Kod çalıştırma yok API'den gelen değerler veri olarak işlenir (konum, tema, metin). Sunucudan gelen hiçbir içerik kod olarak yorumlanmaz.
Kişisel veri maskeleme Yorumcu adı hem sunucuda hem istemcide temizlenir: @ içeren her parça atılır ve isim Ahmet Y. biçimine indirgenir.

Sunucu tarafı

ÖnlemUygulama
Taşıma güvenliği Tüm trafik HTTPS üzerindedir; API yalnızca TLS ile yayınlanır.
CORS allowlist Access-Control-Allow-Origin: * kullanılmaz. İzinli origin listesi veritabanından okunur ve çalışma zamanında yenilenir; yalnızca kayıtlı mağaza alan adları API'ye erişebilir.
SQL enjeksiyonu Tüm sorgular Dapper ile parametrelidir; kullanıcı girdisi hiçbir zaman SQL metnine gömülmez.
Hız sınırlama Kimlik doğrulama uçları IP başına 10 istek/dakika; form gönderim uçları 5 istek/dakika. Aşımda 429 döner.
Yetkilendirme JWT tabanlı, rol kapsamlı (admin / mağaza / kullanıcı ayrı audience). Widget'ın kullandığı uçlar anonimdir ve yalnızca okuma + kendi oturumuna ekleme yapabilir.
Güvenlik başlıkları X-Content-Type-Options: nosniff
X-Frame-Options: DENY
Referrer-Policy: strict-origin-when-cross-origin
X-XSS-Protection: 1; mode=block
Hata sızıntısı Global istisna yakalayıcı, üretimde yığın izi veya SQL parçası döndürmez; ayrıntı yalnızca sunucu günlüğüne yazılır.
Veri erişimi Oturum ve ziyaret verilerini okuyan tüm uçlar kimlik doğrulaması ister. Bir mağaza yalnızca kendi verisini görür.
Yetki sınırı

Widget'ın anonim olarak erişebildiği yazma işlemleri yalnızca şunlardır: yeni bir oturum satırı açmak, o oturuma sayfa görüntüleme eklemek ve o oturumun üç boolean bayrağını 1 yapmak. Var olan hiçbir kaydı güncelleyemez, silemez veya başka bir mağazanın verisine dokunamaz — her sorgu StoreId ile kısıtlıdır.

§ 08

API yüzeyi

Widget'ın attığı isteklerin tam listesi. Hepsi https://api.guventik.com adresine gider; başka hiçbir uç noktaya çağrı yapılmaz.

Uç noktaTürNe zamanGönderilen
GET /Dealers/DetailOkumaHer sayfa yüklemesiMağaza slug'ı
GET /Comments/DealerOkumaHer sayfa yüklemesiMağaza slug'ı
POST /AdminWidgetSetting/GetOkumaHer sayfa yüklemesiBoş gövde
GET /stores/{id}OkumaHer sayfa yüklemesiMağaza numarası
POST /stores/{id}/sessionsYazmaHer sayfa yüklemesiOturum GUID'i, sayfa URL'si, referrer
PATCH …/widget-openedYazmaPanel ilk kez açıldığındaGövde yok
PATCH …/payment-visitedYazmaÖdeme sayfası eşleşmesindeGövde yok
PATCH …/review-requestedYazmaForm gönderildiğindeGövde yok
POST /stores/{id}/review-requestsYazmaZiyaretçi formu gönderdiğindeE-posta, sayfa URL'si
POST /contact-consentYazmaZiyaretçi formu gönderdiğindeE-posta, telefon (varsa), rıza bayrakları

İlk sekiz çağrı ziyaretçi etkileşimi olmadan gerçekleşir ve hiçbiri kişisel veri taşımaz. Son iki çağrı yalnızca ziyaretçi formu doldurup KVKK onayını işaretlediğinde tetiklenir.

§ 09

Dış bağımlılıklar ve CSP

Widget üç dış kaynağa bağlıdır. Hiçbiri analitik veya reklam amaçlı değildir; ikisi yalnızca görsel varlıklar içindir.

KaynakAmaçKoşul
api.guventik.comYorum verisi ve oturum kaydıHer zaman
cdnjs.cloudflare.comFont Awesome 6.4.0 ikonlarıShadow root'a her zaman; sayfanıza yalnızca Font Awesome yoksa
fonts.googleapis.com
fonts.gstatic.com
DM Sans yazı tipiSayfanızda bu font yoksa

Content-Security-Policy için gereken izinler

Katı bir CSP uyguluyorsanız aşağıdaki kaynakları eklemeniz yeterlidir:

script-src   https://guventik.com;
connect-src  https://api.guventik.com;
style-src    https://cdnjs.cloudflare.com https://fonts.googleapis.com;
font-src     https://fonts.gstatic.com https://cdnjs.cloudflare.com;
img-src      https://guventik.com data:;
Sıkı CSP kullanan ekipler için

Ödeme sayfası penceresi, stillerini bir <style> etiketiyle enjekte eder. style-src direktifinizde 'unsafe-inline' yoksa bu pencere stilsiz görünür. Nonce tabanlı bir CSP kullanıyorsanız bize yazın — dağıtımınıza özel bir yapılandırma sağlayabiliriz.

§ 10

Teknoloji yığını

KatmanTeknolojiNot
WidgetVanilla JS (ES2020)Framework, bundler veya çalışma zamanı bağımlılığı yok
İzolasyonShadow DOM v1Yerel tarayıcı API'si; polyfill kullanılmaz
APIASP.NET Core (.NET 7)REST, JSON
Veri erişimiDapperParametreli sorgular
VeritabanıSQL ServerMağaza bazlı satır izolasyonu
Kimlik doğrulamaJWT (HS256)Rol kapsamlı audience ayrımı
E-postaMailKit / SMTPYorum hatırlatmaları ve kupon teslimi

Tarayıcı desteği: Shadow DOM, fetch ve sessionStorage destekleyen tüm modern tarayıcılar (Chrome, Edge, Firefox, Safari — masaüstü ve mobil). Desteklemeyen bir tarayıcıda widget sessizce devre dışı kalır; sayfanız etkilenmez.

§ 11

KVKK ve rıza

  • Ayrık rıza. E-posta ve SMS izinleri iki ayrı onay kutusudur. Tek bir "hepsini kabul ediyorum" kutusu yoktur.
  • Rıza olmadan alan yok. E-posta onayı işaretlenmeden gönder düğmesi etkinleşmez; SMS onayı işaretlenmeden telefon alanı açılmaz ve boş bırakılır.
  • Aydınlatma metni erişilebilir. Her iki onay kutusu da KVKK metnine doğrudan bağlantı içerir.
  • Rıza kaydı tutulur. Hangi iznin verildiği, kayıtla birlikte saklanır.
  • Veri minimizasyonu. Anonim oturum verisinden kişiye ulaşmak mümkün değildir; IP saklanmaz, çerez yazılmaz, kalıcı tanımlayıcı üretilmez.
  • Silme talepleri. Bir ziyaretçi verisinin silinmesini talep ederse e-posta adresi üzerinden ilgili tüm kayıtlar kaldırılır.

Ziyaretçi sözleşmeniz açısından: widget çerez kullanmadığı için çerez rıza bandınıza yeni bir kategori eklemeniz gerekmez. Yine de gizlilik politikanızda Güventik'i bir yorum altyapısı sağlayıcısı olarak anmanızı öneririz.

§ 12

Kurulum ve kaldırma

Kurulum

Script'i </body> etiketinden hemen önce ekleyin. Şablonunuzda tek bir yere koymanız yeterlidir — ödeme sayfası dahil tüm sayfalarda çalışır.

<script
  src="https://guventik.com/widget/widget.js"
  data-slug="123"
  data-position="right"></script>

Doğrulama

  1. Tarayıcı konsolunda [Widget] v2 loaded satırını görün.
  2. Network sekmesinde api.guventik.com filtreleyin; § 08'deki listenin dışında istek olmadığını doğrulayın.
  3. Application → Storage'da tek bir gvntk_session_* anahtarı ve hiç çerez olmadığını görün.
  4. Elements sekmesinde div#__gvntk_host düğümünü ve altındaki #shadow-root'u inceleyin.

Kaldırma

Script satırını silin. Geriye hiçbir iz kalmaz: çerez yazılmadığı için temizlenecek çerez yoktur, sessionStorage anahtarı sekme kapandığında kendiliğinden silinir ve DOM'a eklenen düğümler sayfa yenilendiğinde yeniden oluşturulmaz. Servis worker, kalıcı önbellek veya arka plan görevi bırakılmaz.

§ 13

Güvenlik ekipleri için sık sorulanlar

Sitemizin DOM'unu veya form alanlarını okuyabilir mi?

Hayır. Widget sayfanızda yalnızca iki şeye bakar: mevcut URL (ödeme sayfası eşleşmesi için) ve <head> içinde Font Awesome / DM Sans bağlantısı olup olmadığı (çift yükleme yapmamak için). Hiçbir input, form, metin düğümü veya veri özniteliği okunmaz.

Müşterimizin sepetini veya sipariş tutarını görüyor musunuz?

Hayır. Ürün, tutar, adet veya müşteri bilgisi hiçbir şekilde okunmaz ve iletilmez. Bize ulaşan tek şey sayfa URL'sidir — bu yüzden § 04'te URL'lerde hassas parametre taşımama önerimiz var.

API'niz çökerse sitemiz etkilenir mi?

Hayır. Tüm çağrılar asenkron ve hata korumalıdır. API yanıt vermezse widget görünmez; sayfanızın render'ı, load olayı veya JavaScript yürütmesi etkilenmez. Konsola bir hata satırı düşer, o kadar.

Script'i güncellediğinizde sitemize istediğiniz kodu gönderebilir misiniz?

Bu, her üçüncü taraf script'i için geçerli olan gerçek bir tedarik zinciri riskidir ve dürüst cevabı şudur: teknik olarak evet, çünkü dosya bizim sunucumuzdan servis edilir. Bu riski kaldırmak isteyen ekipler için iki seçeneğimiz var — (a) widget.js ve widget.css dosyalarını kendi sunucunuzdan barındırın (script kendi konumunu algılayıp CSS'i oradan yükler, ek yapılandırma gerekmez); (b) script etiketine integrity ile SRI hash ekleyin — sürüm sabitlenmiş bir kopya ve hash'i talep üzerine sağlıyoruz.

Sitemizin performans skorunu (Core Web Vitals) düşürür mü?

Ölçülebilir etkisi minimumdur. Widget DOMContentLoaded sonrasında çalışır, dolayısıyla LCP'yi etkilemez. Sabit konumlu ve boyutlu tek bir katman eklediği için CLS'ye katkısı yoktur. Toplam transfer yükü gzip'li ~19 KB'dır.

Widget'ın gösterdiği yorumlar sizin kontrolünüzde mi?

Yorumlar bağımsız bir sistemde tutulur ve yalnızca onaylı olanlar yayınlanır. Bu, sistemin güvenilirliğinin temelidir: mağaza olumsuz yorumları silemez. Panelinizden kural ihlali içeren yorumları raporlayabilirsiniz; değerlendirme Güventik tarafında yapılır.

Bir penetrasyon testi yapmak istiyoruz. Mümkün mü?

Evet. Kendi mağaza hesabınız ve alan adınız kapsamında test yapabilirsiniz. Test öncesi bize bildirin ki hız sınırlama uyarılarımız yanlış alarm üretmesin. Bulguları sorumlu ifşa kapsamında değerlendirir ve süre taahhüdüyle yanıtlarız.

Ekibinizin başka bir sorusu mu var?

Bu doküman widget'ın çalışan kaynak kodundan çıkarılmıştır. Güvenlik incelemeniz için ek bilgi, SRI hash'i, sürüm sabitlenmiş kopya veya özel CSP yapılandırması gerekiyorsa teknik ekibimize yazın.