Sepet ve Dinamik İçerik

setCart, ürün değerleri, hedef çubuğu, geri sayım

Panelde bir kampanyaya durum (koşullu içerik) eklediyseniz, metninde sepet ya da ürün değeri söylettiyseniz ya da bir hedef çubuğu kurduysanız, uygulama iki bilgiyi SDK'ya vermek zorundadır: sepet ve ekrandaki ürün. Sepet ve ürün uygulamanızın içinde yaşar; SDK bunları göremez.

Sepeti bildirme

setCart(cart: CartInput | null): boolean

interface CartInput {
  total: number | string;        // indirimler düşülmüş ürün toplamı, kargo ve ücretler hariç
  itemCount: number | string;    // sepetteki birim sayısı
  currency?: string | null;      // ISO 4217; yoksa kanalın para birimi
  codes?: Array<string | number> | null;   // satırların ürün kodları (en çok 100)
}
selwise.setCart({ total: 379.8, itemCount: 3, currency: 'TRY', codes: ['4055'] });

selwise.getCart();   // { known: true, total: 379.8, itemCount: 3, currency: 'TRY' }

const stop = selwise.onCartChange((cart) => {
  // hedef çubuğunu yeniden çözün; sepetten söz eden ekranlarda getSurfaces() çağırın
});
  • Her sepet değişiminde ve açılışta sepet yüklendiğinde çağırın. setCart, init()'ten önce de çalışır.
  • Tutar her seferinde sepetin tamamıdır, değişen satır değil. total indirimlerden sonra, kargo ve ücretlerden önceki değerdir (GA4 value): kargo dahil bir toplam ücretsiz kargo eşiğini yanlış hesaplatır. Sayısal metin ('379.80') kabul edilir; total ve itemCount ikisi de zorunludur.
  • Bildirilmemiş sepet bilinmeyen sepettir. Sepet yalnızca bellekte tutulur; her açılış known: false ile başlar. Önceki açılıştan kalan bir tutar başka cihazda değişmiş olabilir ve yanlış tutar hiç tutardan kötüdür. Bilinmeyen sepet hiçbir zaman çizilmez.
  • Sepet artık bilinmiyorsa (sipariş sonrası temizlendi, çıkış yapıldı) setCart(null) çağırın. Sepet olmayan bir değer (negatif ya da sayısal olmayan tutar) reddedilir, false döner ve sepeti bilinmeyen yapar.
  • onCartChange yalnızca sepet değiştiğinde çağrılır: tutar, adet, para birimi ya da satır kodları. Aynı değerle tekrar setCart çağırmak bir değişim değildir. Dönen fonksiyon aboneliği bırakır.
  • codes, yalnızca Kargo Bedavaya Tamamla şeridine gider ve sepetteki ürünün o şeritte önerilmemesini sağlar. Sepetin ölçülmüş sayılmasını etkilemez. Panelde Channel Overview → Cart value kartı sepetin ölçüldüğünü ya da yalnızca sepete ekle/çıkar olaylarının geldiğini söyler; bkz. Hedef Çubuğu.

Bildirilen sepet hedeflemede de kullanılır: behavior geçmediğiniz çağrılarda Cart value (Sepet tutarı, cartValue) ve Cart item count (Sepetteki ürün adedi, cartItemCount) kuralları bu sepetle değerlendirilir; kendi behavior'ınızı verirseniz yalnızca vermediğiniz sepet sinyalleri doldurulur.

Ekrandaki ürünü bildirme

Ürün sayfası ürünü zaten mağazadan almıştır; onu getSurfaces'a siz verirsiniz:

interface ProductInput {
  title?: string | null;
  price?: number | string | null;           // şimdiki fiyat
  originalPrice?: number | string | null;   // indirimden önceki fiyat; indirim yoksa vermeyin
  stock?: number | string | null;           // bilinmiyorsa vermeyin
  currency?: string | null;
  pending?: boolean;                        // ürün hâlâ yükleniyor
}

const surfaces = await selwise.getSurfaces('app://product', {
  product: { title: p.name, price: p.price, originalPrice: p.retailPrice, stock: v.stock, currency: 'TRY' },
  locale: 'tr-TR',
});
  • Ürünü yalnızca ürün ekranında verin. Ürün verilmeyen ekranda ürün değeri söyleyen durum atlanır.
  • Önceki fiyat, indirim tutarı ve indirim yüzdesi yalnızca originalPrice price'tan yüksekse söylenir; stok yalnızca sıfırdan büyükse söylenir.
  • Yeni ürün yüklenirken önceki ürünü vermeyin, product: { pending: true } verin: ürüne bağlı yüzey ürün gelene kadar döndürülmez, önce temel içerik gösterilip sonra değiştirilmez. Diğer yüzeyler etkilenmez. Ürün gelince çağrıyı yeni ürünle yineleyin.
  • Aynı ürün ürün koşullarını da yanıtlar: Product stock (Ürün stoğu), Product is on sale (Ürün indirimde), Product discount rate (%) (Ürün indirim oranı) ve Product price (Ürün fiyatı) koşulları durumlarda ve hedeflemede bu üründen okunur; ürün olmayan ekranda hiçbir koşul eşleşmez.

Durumlar ve yer tutucular

getSurfaces() kazanan durumu sizin yerinize seçer: surface.content o durumun metinlerini taşır, surface.stateId durumun kimliğidir (temel içerikte null). Gizleyen bir durum yüzeyi listeden çıkarır; çizilmediği için gösterim yazılmaz ve yuva almaz.

Kampanya metnindeki yer tutucular çağrı anında doldurulur: {cart.total}, {cart.itemCount}, {product.title}, {product.price}, {product.originalPrice}, {product.discountAmount}, {product.discountRate}, {product.stock}. Söylenemeyen bir değer (sepet ölçülmemiş, para birimi yok, indirim yok) o cümleyi söylenemez kılar: durum sıradaki eşleşen duruma, en sonda temel içeriğe düşer; hiçbiri söylenemiyorsa yüzey döndürülmez. Uygulamanız hiçbir zaman ham süslü parantez basmaz.

Durumlar çağrı anındaki sepete ve ürüne göre seçildiği için sepetten ya da üründen söz eden ekranlarda getSurfaces() çağrısını onCartChange geldiğinde ve ürün değiştiğinde yineleyin.

Eski SDK sürümleri

SDK /config isteğinde hangi yer tutucuları ve koşulları tanıdığını bildirir (p=4: sepet ve ürün değerleri, ürün koşulları). Sunucu daha azını bildiren bir sürüme dolduramayacağı değerleri ya da tanımadığı koşulları içeren kampanyayı hiç göndermez; tanımadığı kuralı yok sayıp kampanyayı olduğundan geniş kitleye göstermesin diye. Aynı bildirim deney atamalarında da yapılır. Yani eski bir uygulama sürümünde bu kampanyalar sessizce görünmez; sebep kampanya değil SDK sürümüdür (Sürümler).

Hedef çubuğu

goal_bar yüzeyinin ne söyleyeceğini resolveGoalBar verir; web widget'ı ve paneldeki önizleme de aynı hesabı kullanır, yani aynı sepet her kanalda aynı cümleyi okur.

resolveGoalBar(surface: Pick<Surface, 'type' | 'content'>, options?: { locale?: string }): GoalBarView

interface GoalBarView {
  state: 'unknown' | 'empty' | 'progress' | 'complete';
  visible: boolean;
  text: string;
  buttonText: string;
  buttonUrl: string;
  progress: GoalProgress | null;
}

interface GoalProgress {
  value: number; target: number; remaining: number;
  percent: number;               // 0 ile 100, aşağı yuvarlanır
  reachedCount: number;          // ulaşılan adım sayısı
  label: string; reachedLabel: string;
  complete: boolean;
  markers: number[];             // her adımın çubuk üzerindeki yeri, 0 ile 100
}

const view = selwise.resolveGoalBar(surface, { locale: 'tr-TR' });
if (view.visible) {
  // view.text: "Ücretsiz kargo için 401 TL kaldı"
  // view.progress.percent: çubuğun doluluğu, 0 ile 100
}
  • visible: false ise hiçbir şey çizmeyin ve gösterim yazmayın: sepet bilinmiyorsa, boş sepette çubuk istenmemişse ya da cümledeki değer söylenemiyorsa.
  • Her onCartChange'de yeniden çözün. Gösterimi (trackSurfaceView) görünür bir görünüm ilk kez çizildiğinde yazın, yüzey listeye girdiğinde değil.
  • Butonun metni ve adresi duruma göre değişir; tıklamada surface.content.buttonUrl değil view.buttonUrl kullanın.

Hedefe ulaşma

goal_reached, sepetin bir adımı çubuk ekrandayken geçtiği anlamına gelir; ekranda ne olduğunu yalnızca uygulama bildiği için bildirimi siz yaparsınız:

import { goalStepsCrossed } from '@selwise/react-native';

for (const step of goalStepsCrossed(previousView, nextView)) {
  selwise.trackGoalReached(surface, { step });   // boolean: gönderildi mi
}
  • Yalnızca önceki görünüm görünürken geçilen adımlar sayılır; çubuk ilk göründüğünde zaten geçilmiş adım ya da gizliyken geçilen adım bildirilmez. Yeni görünümün görünür olması gerekmez (hedefe ulaşınca kaybolan çubuk).
  • Çubuk ekrandan çıkınca önceki görünümü unutun.
  • SDK her adımı oturum başına bir kez gönderir (açılışlar arasında da).
  • Yüzeyi getSurfaces() döndürdüğü gibi geçerseniz { step } yeter; yalnızca kimliği tuttuysanız threshold ve metric (cart_total ya da cart_item_count) de verin.
  • Bu bir tıklama değildir ve ciro kredisi almaz.

Geri sayım

countdown_timer, sabit bir bitiş tarihine ya da günlük kesim saatine ("14:00'e kadar verilen siparişler bugün kargoda") sayabilir; kesim saati mağazanın saat dilimindedir ve geçince ertesi güne döner. Hedef anı countdownTarget verir; her saniye yeniden sorun, bir kez okuyup saklamayın (saklarsanız sayaç ilk kesimde sonsuza dek biter):

import { countdownTarget } from '@selwise/react-native';

const target = countdownTarget(surface.content, Date.now());   // epoch ms ya da null

null dönerse sayacı çizmeyin. Yardımcılar: nextDailyCutoff, parseDailyCutoff, COUNTDOWN_MODES (fixed_date, daily_cutoff), CUTOFF_TIME_ZONES.

Sırada ne var

Son güncelleme: 10 Ekim 2026