# İmzalı Kimlik

Müşteri numarasını sunucunuzda imzalamak ve zorunlu kılmak
Kaynak: https://selwise.com/docs/integration/identity-verification

Mağazanız müşterinin kim olduğunu Selwise'a **müşteri numaranızla** bildirir ([Kullanıcı Kimliklendirme](/docs/integration/identify)). Bu numara tarayıcıdan gelir; imzasızken onu bilen herkes o müşteri gibi davranabilir. İmzalı kimlikte numarayı **kendi sunucunuz** kanalın gizli anahtarıyla imzalar, Selwise de imzayı doğrular.

## Neyi korur

Kanal **Enforce** (Zorunlu) moddayken yalnızca imzalı bir `identify` ile bağlanmış tarayıcı:

- müşterinin segment üyeliğini ve son gezdiği ürünleri okuyabilir;
- bir e-posta adresini ya da tarayıcı bildirimi aboneliğini o müşteriye bağlayabilir;
- müşteri adına senaryoya girebilir ve müşterinin özelliklerini (`traits`) yazabilir.

İmzasız bir `identify` engellenmez: tarayıcının olayları kaydedilmeye ve müşterinin geçmişine eklenmeye devam eder. Yalnızca müşteri adına okuma ve mesaj yönlendirme yapamaz.

## Panelde nerede

**Kanallar → kanal → Signed identity** (Channels) kartı (İmzalı kimlik). Kartta üç şey var:

| Bölüm | Ne yapar |
|---|---|
| Sayımlar | Son 7 gündeki `identify` çağrılarını **Signed** (İmzalı), **Signature rejected** (İmzası reddedilen) ve **Unsigned** (İmzasız) olarak sayar |
| Sır | **Create secret** (Sır oluştur) kanalın kimlik sırrını üretir ve **yalnızca bir kez** gösterir. **Rotate secret** (Sırrı yenile) yenisini üretir; eskisi 24 saat daha çalışır |
| Mod | **Off** (Kapalı), **Report** (Raporla, varsayılan) ya da **Enforce** (Zorunlu) |

## Adım adım geçiş

1. **Create secret** ile sırrı oluşturun ve sunucunuzun ortam değişkenlerine koyun. Sırrı bir web sayfasına, JavaScript dosyasına ya da mobil uygulamaya **asla** koymayın.
2. Sunucunuzda, müşteri giriş yapmışken müşteri numarasını imzalayın ve imzayı sayfaya ya da uygulamaya verin (aşağıdaki örnekler).
3. Kanal **Report** modundayken birkaç gün bekleyin. Sayımlarda **Signed** payı neredeyse tamamını gösterene, **Signature rejected** sıfıra inene kadar devam edin.
4. Modu **Enforce** yapın.

## İmza nasıl hesaplanır

İmza, müşteri numarasının kanal sırrıyla alınmış **HMAC-SHA256** özetidir, onaltılık (hex) yazılır. İki biçim kabul edilir:

| Biçim | İmzalanan metin | Ne zaman |
|---|---|---|
| Zaman damgalı (önerilen) | `MUSTERI_NO:ZAMAN` (ZAMAN Unix saniyesi) | Sızan bir imza en fazla 7 gün işe yarar |
| Damgasız | `MUSTERI_NO` | Şablon diliniz zaman damgasıyla birleştirme yapamıyorsa |

Zaman damgası 7 günden eskiyse ya da 5 dakikadan fazla ilerideyse imza reddedilir.

### Sunucu örnekleri

```js
// Node.js
const crypto = require('crypto');
const userHashTs = Math.floor(Date.now() / 1000);
const userHash = crypto
  .createHmac('sha256', process.env.SELWISE_IDENTITY_SECRET)
  .update(`${customerId}:${userHashTs}`)
  .digest('hex');
```

```php
// PHP
$userHashTs = time();
$userHash = hash_hmac('sha256', $customerId . ':' . $userHashTs, getenv('SELWISE_IDENTITY_SECRET'));
```

```python
# Python
import hmac, hashlib, os, time
user_hash_ts = int(time.time())
user_hash = hmac.new(os.environ["SELWISE_IDENTITY_SECRET"].encode(), f"{customer_id}:{user_hash_ts}".encode(), hashlib.sha256).hexdigest()
```

### Sayfaya vermek

[Veri Katmanı](/docs/integration/data-layer) kullanıyorsanız giriş olayının `user` nesnesine `idHash` ve `idHashTs` ekleyin (kullanıcı takip modülü açık olmalıdır):

```js
window.selwiseLayer = window.selwiseLayer || [];
window.selwiseLayer.push({
  event: 'user_login',
  user: { id: 'MUSTERI-1001', loggedIn: true, idHash: 'SUNUCUNUZUN_URETTIGI_IMZA', idHashTs: 1792700000 },
});
```

İmza olaylara yazılmaz; yalnızca `identify` çağrısına gider. Ya da doğrudan çağırın:

```js
Selwise.identify('MUSTERI-1001', { userHash: 'SUNUCUNUZUN_URETTIGI_IMZA', userHashTs: 1792700000 });
```

İmza sayfaya **sunucuda** yazılmalıdır. Tarayıcıda hesaplanan bir imza, sırrın tarayıcıda olduğu anlamına gelir ve hiçbir şey kanıtlamaz.

### Mobil uygulama

İmzayı uygulamanın arka ucu üretir ve giriş yanıtıyla uygulamaya verir:

```ts
await selwise.identify(customerId, { email }, { userHash, userHashTs });
```

## Platformlara göre

| Platform | İmzayı kim üretir |
|---|---|
| Özel altyapı, `custom_api` | Kendi sunucunuz |
| Akinon | Vitrinin sunucu tarafı |
| Shopify | Tema kodunda Liquid'in `hmac_sha256` filtresi, sır tema ayarında |
| Mobil uygulama (`@selwise/react-native`) | Uygulamanın arka ucu |
| Akinon App Maker eklentisi | Eklenti imza göndermez; imzalı kimlik için uygulamanın kendi `selwise.identify` çağrısı gerekir |
| ikas | Yalnızca sunucu tarafında kod çalıştıran özel bir temada |
| IdeaSoft, Ticimax, T-Soft | Şablon dili imza üretemiyor; kanal **Report** modunda kalır |

**Report** modunda kalan kanallar da korunur: bir tarayıcının bir günde çok sayıda farklı müşteri numarasıyla tanıtılması engellenir, müşterinin kayıtlı e-posta adresi imzasız bir çağrıyla değiştirilemez ve yeni bağlanmış bir tarayıcı müşterinin mevcut iletişim adresinin yerine geçemez.

## API

`POST /api/v1/public/sites/SITE_KEY/users/identify` gövdesine `userHash` ve isteğe bağlı `userHashTs` eklenir; yanıttaki `verified` imzanın geçerli olup olmadığını söyler. Bkz. [Kullanıcı Kimliklendirme API'si](/docs/api-reference/identify-api).

## Sık yapılan hatalar

- **Sayımlar hep İmzasız.** Veri katmanında `idHash` yok ya da `user.id` ile aynı müşteriye ait değil.
- **İmzası reddedilen artıyor.** İmzalanan metin ile gönderilen numara aynı değil (boşluk, büyük küçük harf), farklı bir sır kullanılıyor ya da zaman damgası saniye değil milisaniye.
- **Sırrı yeniledikten sonra hata.** Eski sır 24 saat çalışır; yenisini bu süre içinde yayına alın.
