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.
Güvenlik modeli
Bölüm başlığı “Güvenlik modeli”- Tarayıcıya gizli anahtar konmaz. Butonda yayınlanabilir anahtar (
rz_pub_…) kullanılır: yalnızcalls:requestkapsamı vardır ve yalnız izinli alan adlarınızdan gelen istekleri kabul eder. - Yayınlanabilir anahtar herkese açıktır ve
Originbaş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_noya damusteri_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_mismatchdö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/aramalarile aynı yoldan geçer: İYS, arama saati, kota ve arama yasağı aynen uygulanır. İsteğin kaynağıbutonolarak kaydedilir.
Kurulum
Bölüm başlığı “Kurulum”-
Ayarlar → API anahtarları’nda iki anahtar oluşturun:
- Sunucunuz için
calls:writekapsamlı gizli anahtar (rz_live_…). - Buton için yayınlanabilir anahtar (
rz_pub_…); butonun çalışacağı alan adlarını girin (ör.https://panel.example.com).
- Sunucunuz için
-
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" \"hedef": {"siparis_no": "560991"}, "gecerlilik_sn": 600}'# {"token": "eyJ2Ijox…", "son_gecerlilik": "2026-09-27T10:25:00Z"} -
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>
Sunucu tarafı örnekleri
Bölüm başlığı “Sunucu tarafı örnekleri”<?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;}?><?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; ?>// Express örneği: sepet sayfasında sepeti hedefleyen token.app.get('/panel/sepet/:id', async (req, res) => { const r = await fetch(`${process.env.RZ_API}/api/v1/buton-token`, { method: 'POST', headers: { Authorization: `Bearer ${process.env.RZ_KEY}`, 'Content-Type': 'application/json' }, body: JSON.stringify({ tetikleyen: { ad: req.user.name, eposta: req.user.email }, hedef: { sepet_id: req.params.id }, }), }); const { token } = await r.json(); res.render('sepet', { rzToken: token, rzPubKey: process.env.RZ_PUB_KEY, rzApi: process.env.RZ_API });});import os, requests
def button_token(tetikleyen: dict, hedef: dict, ttl: int = 600) -> str: r = requests.post(f"{os.environ['RZ_API']}/api/v1/buton-token", headers={"Authorization": f"Bearer {os.environ['RZ_KEY']}"}, json={"tetikleyen": tetikleyen, "hedef": hedef, "gecerlilik_sn": ttl}, timeout=5) r.raise_for_status() return r.json()["token"]
{"musteri_telefon": "05321234567"})# Telefona bağlı token'da sayfaya data-musteri-ad / data-musteri-telefon da ekleyin.Betik öznitelikleri
Bölüm başlığı “Betik öznitelikleri”| Öznitelik | Zorunlu | Açıklama |
|---|---|---|
data-anahtar | evet | Yayınlanabilir anahtar (rz_pub_…) |
data-token | evet | Sunucunuzun ürettiği token |
data-etiket | hayır | Düğme metni (varsayılan “Sizi arayalım”) |
data-musteri-ad, data-musteri-telefon, data-musteri-eposta | yalnız telefona bağlı token’da | Müşteri bilgisi; telefon token’daki özetle eşleşmeli |
data-siparis-no, data-sepet-id | hayır | Token’ın hedefiyle aynı olmalı; farklıysa target_mismatch |
data-asistan | hayır | Pencere başlığındaki asistan adı (en çok 40 karakter); yoksa “Asistan arasın” |
data-marka-renk | hayır | #RRGGBB; yalnız pencerenin 3 px üst şeridine uygulanır. Düğmeler her zaman ürün vurgusunu kullanır |
Kullanıcının gördüğü
Bölüm başlığı “Kullanıcının gördüğü”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.
Tarayıcı uçları
Bölüm başlığı “Tarayıcı uçları”Betik şu uçları kendisi çağırır (OpenAPI şemasında yer almazlar):
| Uç | Açıklama |
|---|---|
GET /api/v1/zitena-buton.js | Betik (1 saat önbellek) |
GET /api/v1/buton/amaclar | Aktif 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}]).
Erişilebilirlik
Bölüm başlığı “Erişilebilirlik”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.
© 2026 Erusoft