İçeriğe geç

Gömülebilir buton

Asistan arasın butonu, kendi yönetim panelinize, CRM’inize ya da sipariş ekranınıza eklediğiniz küçük bir düğmedir. Ekibinizden biri düğmeye basıp amacı ve konuyu seçer; asistan müşteriyi arar. Buton bağımlılıksız tek bir betiktir ve paketinizde Asistan arasın butonu (ve Giden arama) özelliğini ister.

Buton isteğinin yolu1. Sunucunuz (gizli anahtarla token üretir) → 2. Sayfa (betik + data-token) → 3. Kullanıcı (amaç ve konu seçer) → 4. Buton ucu (rz_pub_ + token + origin) → 5. Giden arama (aynı ön kontroller)Sunucunuzgizli anahtarla tokenüretirSayfabetik + data-tokenKullanıcıamaç ve konu seçerButon ucurz_pub_ + token + originGiden aramaaynı ön kontroller
  • Tarayıcıya gizli anahtar konmaz. Butonda yayınlanabilir anahtar (rz_pub_…) kullanılır: yalnız calls:request kapsamı vardır ve yalnız izinli alan adlarınızdan gelen istekleri kabul eder.
  • Yayınlanabilir anahtar herkese açıktır ve Origin başlığı tarayıcı dışında taklit edilebilir; bu yüzden anahtar tek başına arama başlatamaz. Her istek, sunucunuzun gizli anahtarla ürettiği tek kullanımlık ve en çok 15 dakika geçerli bir token ister.
  • Token, tetikleyeni (sayfayı açan kendi kullanıcınız) ve aramanın hedefini bağlar — tam olarak biri: sepet_id, siparis_no ya da musteri_telefon.
    • Hedef sepet ya da siparişse müşteri bilgisi (telefon, e-posta, ad) Zitena’daki kayıttan okunur; tarayıcının gönderdiği yok sayılır.
    • Hedef telefonsa token’a yalnız telefonun özeti girer; tarayıcının gönderdiği telefon bu özetle eşleşmek zorundadır.
    • Hedef dışında bir sepet ya da sipariş eklemek 403 target_mismatch döner.
  • Anahtar başına hız sınırı yalnız izinli origin’den gelen isteklerde sayılır (başkası anahtarınızı tüketip butonu kilitleyemez); başarısız denemeler IP başına dakikada 20 ile sınırlıdır.
  • İstek, POST /api/v1/aramalar ile aynı yoldan geçer: İYS, arama saati, kota ve arama yasağı aynen uygulanır. İsteğin kaynağı buton olarak kaydedilir.
  1. Ayarlar → API anahtarları’nda iki anahtar oluşturun:

    • Sunucunuz için calls:write kapsamlı gizli anahtar (rz_live_…).
    • Buton için yayınlanabilir anahtar (rz_pub_…); butonun çalışacağı alan adlarını girin (ör. https://panel.example.com).
  2. Sayfayı oluştururken sunucunuzda bir token üretin (her sayfa açılışında yeni bir token):

    Terminal window
    curl -s -X POST "$RZ_API/api/v1/buton-token" \
    -H "Authorization: Bearer rz_live_xxx" -H "Content-Type: application/json" \
    -d '{"tetikleyen": {"ad": "Can Demir", "eposta": "[email protected]"},
    "hedef": {"siparis_no": "560991"}, "gecerlilik_sn": 600}'
    # {"token": "eyJ2Ijox…", "son_gecerlilik": "2026-09-27T10:25:00Z"}
  3. Betiği sayfaya ekleyin ve token’ı basın:

    <script src="https://<konsol-adresiniz>/api/v1/zitena-buton.js"
    data-anahtar="rz_pub_xxx"
    data-token="eyJ2Ijox…"
    data-etiket="Sizi arayalım"
    defer></script>
<?php
// Sipariş ekranında: bu siparişin müşterisini aratmak için token üret.
function rz_button_token(string $orderNo, array $user): ?string {
$res = wp_remote_post(RZ_API . '/api/v1/buton-token', [
'timeout' => 5,
'headers' => ['Authorization' => 'Bearer ' . RZ_KEY, 'Content-Type' => 'application/json'],
'body' => wp_json_encode([
'tetikleyen' => ['ad' => $user['name'], 'eposta' => $user['email']],
'hedef' => ['siparis_no' => $orderNo],
'gecerlilik_sn' => 600,
]),
]);
if (is_wp_error($res) || wp_remote_retrieve_response_code($res) !== 200) { return null; }
return json_decode(wp_remote_retrieve_body($res), true)['token'] ?? null;
}
$token = rz_button_token('560991', ['name' => 'Can Demir', 'email' => '[email protected]']);
?>
<?php if ($token): ?>
<script src="<?= esc_url(RZ_API . '/api/v1/zitena-buton.js') ?>"
data-anahtar="<?= esc_attr(RZ_PUB_KEY) ?>" data-token="<?= esc_attr($token) ?>" defer></script>
<?php endif; ?>
ÖznitelikZorunluAçıklama
data-anahtarevetYayınlanabilir anahtar (rz_pub_…)
data-tokenevetSunucunuzun ürettiği token
data-etikethayırDüğme metni (varsayılan “Sizi arayalım”)
data-musteri-ad, data-musteri-telefon, data-musteri-epostayalnız telefona bağlı token’daMüşteri bilgisi; telefon token’daki özetle eşleşmeli
data-siparis-no, data-sepet-idhayırToken’ın hedefiyle aynı olmalı; farklıysa target_mismatch
data-asistanhayırPencere başlığındaki asistan adı (en çok 40 karakter); yoksa “Asistan arasın”
data-marka-renkhayır#RRGGBB; yalnız pencerenin 3 px üst şeridine uygulanır. Düğmeler her zaman ürün vurgusunu kullanır

Düğmeye basınca modal bir pencere açılır: amaç (firmanızın aktif amaçları), zorunlu konu (asistanın bilmesi gereken mesele, 10–1000 karakter, sayaçlı) ve isteğe bağlı olarak arama saatleri içinde belirli bir zaman. Gönderince sonuç pencerede yazılır: sıraya alındı, planlandı (İstanbul saatiyle zaman ve nedeni) ya da aranmayacak (ör. “müşteri aranmak istemediğini bildirmiş”).

Bir token bir istek içindir: ikinci istek 401 button_token_used alır; yeni istek için sayfa yeni token’la yenilenir. Süresi dolan token 401 invalid_button_token döner ve pencere kullanıcıya sayfayı yenilemesini söyler.

Betik şu uçları kendisi çağırır (OpenAPI şemasında yer almazlar):

UçAçıklama
GET /api/v1/zitena-buton.jsBetik (1 saat önbellek)
GET /api/v1/buton/amaclarAktif amaçlar ve arama saatleri; geçerli token ister (tüketmez)
POST /api/v1/buton/aramalarİsteği gönderir; başlıklar Authorization: Bearer rz_pub_… ve X-Zitena-Buton-Token

CORS yalnız bu uçlarda ve yalnız izinli origin için açıktır; ön kontrol (OPTIONS) yalnız bir yayınlanabilir anahtarın izin listesindeki origin’i yansıtır.

Hata kodları: invalid_button_token, button_token_used, target_mismatch, target_not_found, cart_without_phone, order_without_phone, musteri_required, invalid_phone, origin_not_allowed, publishable_key_required, too_many_failures, validation_error (alan listesi hatalar: [{alan, etiket, mesaj}]).

Arayüz Shadow DOM içindedir (sitenizin CSS’i karışmaz), metinler textContent ile yazılır (HTML enjekte edilmez). Pencere modal bir <dialog>’dur: Esc kapatır, odak pencerede kalır, kapanınca düğmeye döner. Durum mesajları aria-live ile okunur; renkler açık ve koyu temada AA kontrastlıdır.