İleti Yönetim Sistemi (İYS) Entegrasyonu
Bu belge runtime'da
company_infotablosundan render edilir.{{company.xxx}}ifadeleri admin panelden doldurulur.
Versiyon: v1.0
Durum: CANLIDA (2026-04-23)
Kanun Uyumluluğu: 6563 sayılı E-Ticaret Kanunu, 15.07.2015 Ticari Elektronik İletiler Yönetmeliği
İlgili MDler: LEGAL/27-KVKK-TOS-GIZLILIK.md, LEGAL/19-DPA.md, ARCHITECTURE-V2/23-BILDIRIMLER.md, ARCHITECTURE-V2/13-RUNTIME-CONFIG.md, ARCHITECTURE-V2/24-ADMIN-MASTER.md
1. Amaç ve Kapsam
İleti Yönetim Sistemi (İYS), Türkiye'de tüm işletmelerin müşterilerine göndereceği ticari elektronik iletilernin (SMS, e-posta, arama, push bildirimi) konusunda müşteri onayını merkezi olarak yönetmek ve denetlemek için kurulmuş bir platformdur.
TitanNav açısından:
- Tüm ticari mesajlar (promosyon, abonelik yenileme uyarısı, indirim, yeni özellik duyuru) İYS'de kaydedilen açık rıza olmadan gönderilemez
- Türkiye Odalar ve Borsalar Birliği (TOBB) tarafından işletilen iys.org.tr platformu
- Uyumsuzluk cezası: mesaj başı 2.000–15.000 TL ve tekrarlayan ihlallerde 2 katına kadar artırılabilir
TitanNav kapsamında hangi mesajlar İYS'ye tabi:
| Mesaj Tipi | Kategori | İYS Onayı Gerekir? | Açıklama |
|---|---|---|---|
| Abonelik yenileme uyarısı (7 gün öncesi) | Pazarlama | EVET | "Aboneliğiniz sona eriyor" — ticari amaçlı |
| Promosyon / indirim duyurusu | Pazarlama | EVET | Sınırlı zaman indirimi, özel teklif |
| Yeni özellik duyurusu | Pazarlama | EVET | Yeni güzergah türü, yeni harita özellikleri |
| Yakıt fiyatı uyarısı (filo modülü v1.0+) | Pazarlama | EVET | Fiyat değişim bildirimi |
| OTP kodu (kayıt, şifre sıfırlama) | İşlemsel | HAYIR | Transactional, muaf |
| Ödeme başarı/başarısızlık bildirimi | İşlemsel | HAYIR | Muhasebe, muaf |
| Abonelik iptal onayı | İşlemsel | HAYIR | Kullanıcı eylemi sonucu |
| Kritik güvenlik uyarısı | İşlemsel | HAYIR | Hesap erişim uyarısı, muaf |
| KVKK veri talepine yanıt | İşlemsel | HAYIR | Yasal yükümlülük, muaf |
2. Yasal Dayanak ve Cezalar
2.1 Temel Mevzuat
- 6563 sayılı E-Ticaret Kanunu (2014) — Madde 6: Ticari elektronik iletilerin gönderilmesi öncesinde alıcının açık rızası zorunlu
- 15.07.2015 Ticari Elektronik İletiler Yönetmeliği — Başvuru ve kullanım kuralları, TOBB tarafından yönetim
- İYS Platformu (iys.org.tr) — Türkiye Odalar ve Borsalar Birliği tarafından işletilen merkezi veri tabanı
2.2 Ceza Hükümleri
Ticari mesaj göndermek için İYS'de kayıtlı onay olmadığında:
- İlk ihlal: Mesaj başına 2.000 TL ceza
- 2–5 defa tekrarlayan ihlal: Mesaj başına 5.000 TL
- 5'ten fazla tekrarlayan ihlal: Mesaj başına 15.000 TL
- Kümulatif risk: Kampanya başına 100.000 yada binlerce mesaj × 15.000 TL = milyon lira ceza
İhlal Türkiye İstatistik Kurumu (TİK) ve Ticaret Bakanlığı tarafından denetlenir.
2.3 İYS Platformunun İşleyişi
┌─────────────────────────────────────────────────────┐
│ 1. İşletme (ToffeSoft) İYS'ye Kayıt + Marka Kaydı │
├─────────────────────────────────────────────────────┤
│ 2. Müşteri Kayıt Ekranında Opt-In Checkbox │
├─────────────────────────────────────────────────────┤
│ 3. TitanNav Sistemi → İYS API │
│ (Onay Yaz: POST /consents) │
├─────────────────────────────────────────────────────┤
│ 4. Ticari Mesaj Göndermeden Öncesi │
│ (Onay Sorgula: GET /consents/status) │
├─────────────────────────────────────────────────────┤
│ 5. Onay Var ✓ → Mesaj Gönder + Log │
│ Onay Yok ✗ → Gönderim İptal + Uyarı │
└─────────────────────────────────────────────────────┘
3. Hizmet Sağlayıcı (İşletme) Kaydı
TitanNav'ın ticari mesaj göndermesi için önce ToffeSoft Bilişim Ltd. Şti. (Kastamonu) İYS platformuna kayıtlı olmalıdır. Bu işi Fatih yapacaktır.
3.1 Kayıt Adımları (e-Devlet)
- iys.org.tr → "Giriş Yap" — e-Devlet hesabı ile oturum aç (Fatih'in kimlik numarası, parola)
- "Hizmet Sağlayıcı Kaydı" bölümü seç
- Şirket Bilgileri:
- Ticari Unvan:
{{company.ticaret_unvani}}(ToffeSoft Bilişim Ltd. Şti.) - MERSİS No:
{{company.mersis_no}} - Vergi No:
{{company.vergi_no}} - Merkez Adresi:
{{company.merkez_adresi}} - KEP Adresi:
{{company.kep_adresi}}(Kurumsal E-Posta — e-imza için gerekli)
- Ticari Unvan:
- Marka Kaydı (Brand Registration):
- Marka Adı: "TitanNav"
- Tanım: "Ticari Araç Navigasyon + Sesli Yol Rehberi Yazılımı"
- Logo: 512×512 PNG (opsiyonel, İYS listelerde gösterilir)
- Kanal Seçimi (Channel Activation):
- SMS — Kısa Mesaj
- Arama (Call) — Sesli Arama (kullanmıyoruz ama kayıt et)
- E-Posta — Elektronik Posta
- Push — Mobil Uygulama Push Bildirimi
- Gönderim Türü: "Pazarlama (Promotional)" seç
- Elektronik İmza ile Onayla — KEP adresi üzerinden e-imza gerekli (Fatih'in muhasebesi/mali müşaviri ile işlem)
- API Erişim Bilgileri Al:
- Username (Kullanıcı Adı)
- Password (Şifre) — GÜVENLI SAKLA
- IYS_code (İşletme Kodu)
- Brand_code (Marka Kodu, örn:
TITANNAV_001) - API Base URL:
https://iys.org.tr/api/v1(üretim) veyahttps://test.iys.org.tr/api/v1(test)
3.2 Kayıt Sonrası Onay E-postaları
KEP adresi ({{company.kep_adresi}}) üzerinden Türkiye Odalar ve Borsalar Birliği'nden:
- Kayıt Onayı (Kaydınız Kabul Edildi)
- API Bilgileri (username/password ile başlamak üzere)
- Marka Onayı (Ticari Uyumluluk Kontrolü)
Fatih bu e-postaları alıp, API credentials'ı Claude Code sunucusundaki admin panele girmelidir (MD: ARCHITECTURE-V2/24-ADMIN-MASTER.md).
4. Onay Tipi: Double Opt-In
TitanNav'da double opt-in (çift onay) modeli uygulanır — güvenlik ve yasal açıdan en güçlü seçenek.
4.1 Akış
Kullanıcı "Kayıt Ol" Tıkla
↓
Kayıt Formunda Göster:
☐ Ticari İleti (SMS/E-posta/Push) Almayı Kabul Ediyorum
(DEFAULT: KAPALI — Kullanıcı Aktif Olarak İşaretlemesi Şart)
↓
Kullanıcı ☑ İşaretledi Mi?
EVET → 4.2'ye git
HAYIR → Sadece transactional (OTP vb.) mesaj, İYS kaydı YOK
↓
Doğrulama E-postası Gönder
"Lütfen e-posta adresinizi doğrulayın" linki
↓
Kullanıcı E-posta Linki Tıkla
(E-posta doğrulandı)
↓
TitanNav API → İYS POST /consents
(Onayı yazma isteği)
↓
İYS "Onay Kabul Edildi" Dönüşü
(User profili markaya yazılmış, status=BILDIRIM_ALACAK)
↓
Profil Sayfasında "İletişim Tercihleri" Görünür
SMS / E-posta / Push / Arama — bağımsız on/off
4.2 Kanallara Göre Onay
Kullanıcı kanal başına onay verir ve her kanali bağımsız yönetebilir:
| Kanal | Ör. Mesaj | Yönetimi |
|---|---|---|
| SMS | Abonelik yenileme uyarısı | Profil → "SMS İletileri" toggle |
| E-Posta | Promosyon, yeni özellik | Profil → "E-Posta İletileri" toggle |
| Push | App bildirimi | Profil → "Push Bildirimleri" toggle |
| Arama | Acil durum (hala opsiyonel) | Profil → "Sesli Arama" toggle |
Kullanıcı bir kanalı kapatsam, İYS'de status RED (Bildirim Almayacak) olarak işaretlenir.
5. Veri Modeli (Veritabanı Şemaları)
TitanNav sunucusu (PostgreSQL veya MySQL) aşağıdaki tablolara sahip olmalıdır.
5.1 Tablo: iys_consents
Kullanıcının her kanal başına onay durumunu saklar.
CREATE TABLE iys_consents (
id BIGINT PRIMARY KEY AUTO_INCREMENT,
user_id BIGINT NOT NULL,
channel VARCHAR(20) NOT NULL, -- SMS, EMAIL, CALL, PUSH
type VARCHAR(50) NOT NULL, -- TICARI (her ticari onay bu tipi)
consent_status VARCHAR(20) NOT NULL, -- GREEN (onay var), RED (çekilmiş), PENDING (yazılmamış)
consent_date TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
source VARCHAR(50) NOT NULL, -- REGISTRATION, PROFILE_UPDATE, PROMOTIONAL_POPUP, WITHDRAWAL
iys_tx_id VARCHAR(100) UNIQUE, -- İYS'den dönen transaction ID
synced_to_iys BOOLEAN DEFAULT FALSE, -- İYS'ye yazılmış mı?
synced_at TIMESTAMP, -- İYS'ye yazılış zamanı
withdrawn_at TIMESTAMP, -- "Abonelikten çık" zamanı (NULL ise aktif)
retry_count INT DEFAULT 0, -- Sync retry sayısı
last_error VARCHAR(500), -- Eğer sync başarısız olursa hata mesajı
UNIQUE KEY (user_id, channel, type),
INDEX idx_user_id (user_id),
INDEX idx_synced_to_iys (synced_to_iys),
INDEX idx_channel (channel),
FOREIGN KEY (user_id) REFERENCES users(id) ON DELETE CASCADE
);
Açıklama:
consent_status: GREEN = onay aktif, RED = çekilmiş, PENDING = henüz İYS'ye yazılmamışiys_tx_id: İYS API'nin return ettiği işlem kimliği — audit içinsynced_to_iys: FALSE ise, background job tarafından sync edilmesi bekleniyor
5.2 Tablo: iys_sync_queue
İYS'ye yazılması gereken ama henüz yazılmamış onayları sıraya sokar (retry mekanizması).
CREATE TABLE iys_sync_queue (
id BIGINT PRIMARY KEY AUTO_INCREMENT,
iys_consent_id BIGINT NOT NULL,
user_id BIGINT NOT NULL,
channel VARCHAR(20) NOT NULL,
action VARCHAR(50) NOT NULL, -- WRITE (yeni onay), WITHDRAW (çekme)
payload JSON NOT NULL, -- İYS'ye gönderilecek veri
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
next_retry_at TIMESTAMP,
attempt_count INT DEFAULT 0,
last_error TEXT,
INDEX idx_created_at (created_at),
FOREIGN KEY (iys_consent_id) REFERENCES iys_consents(id) ON DELETE CASCADE,
FOREIGN KEY (user_id) REFERENCES users(id) ON DELETE CASCADE
);
5.3 Tablo: iys_message_log
Gönderilen her ticari mesajın kaydı — İYS uygunluk denetimi için.
CREATE TABLE iys_message_log (
id BIGINT PRIMARY KEY AUTO_INCREMENT,
user_id BIGINT NOT NULL,
channel VARCHAR(20) NOT NULL, -- SMS, EMAIL, PUSH
message_type VARCHAR(50) NOT NULL, -- RENEWAL_REMINDER, PROMOTION, FEATURE_ANNOUNCE, vb.
message_subject TEXT,
sent_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
-- İYS Kontrol
iys_check_performed BOOLEAN DEFAULT TRUE,
iys_check_status VARCHAR(50), -- GREEN (onay var), RED (onay yok), CACHE (cache'ten)
iys_check_time INT, -- ms cinsinden sorgu zamanı
-- Gönderim Sonucu
sent_successfully BOOLEAN,
send_error VARCHAR(500),
-- Audit
sent_by_system VARCHAR(100), -- Hangi service gönderdi (email-queue, sms-provider, vb.)
iys_tx_id VARCHAR(100), -- Eğer check yapılmışsa İYS transaction ID
INDEX idx_user_id (user_id),
INDEX idx_sent_at (sent_at),
FOREIGN KEY (user_id) REFERENCES users(id) ON DELETE CASCADE
);
Açıklama: Her mesaj gönderimi öncesi iys_check_status = GREEN olmalı. Aksi takdirde uyumsuzluk log'u.
6. API Entegrasyon Akışları
TitanNav sunucusu İYS API'si ile aşağıdaki işlemleri yapar.
6.1 Onay Yazma (POST /consents)
Kullanıcı e-posta doğrulama linki tıkladıktan sonra, backend bu isteği yapar:
POST https://iys.org.tr/api/v1/consents
Content-Type: application/json
Authorization: Basic base64(username:password)
{
"brand_code": "TITANNAV_001",
"channels": [
{
"channel_id": "SMS",
"consent": true,
"status": "BILDIRIM_ALACAK"
},
{
"channel_id": "EMAIL",
"consent": true,
"status": "BILDIRIM_ALACAK"
},
{
"channel_id": "PUSH",
"consent": true,
"status": "BILDIRIM_ALACAK"
}
],
"recipient": {
"phone": "+90XXXXXXXXXX",
"email": "user@example.com"
},
"source": "REGISTRATION",
"timestamp": "2026-04-23T10:30:00Z"
}
Response (200 OK):
{
"transaction_id": "txn_20260423_001",
"status": "OK",
"channels_accepted": 3,
"timestamp": "2026-04-23T10:30:05Z"
}
Akış:
- E-posta doğrulandığında, kullanıcı profili
iys_consentstablosunaconsent_status=PENDINGile kaydedilir - Background job
iys_sync_queue'dan alır, İYS POST /consents çalıştırır - Başarılı →
synced_to_iys=TRUE,iys_tx_idkaydedilir - Başarısız →
retry_count++, 5 dakika sonra yeniden dene
6.2 Onay Sorgulama (GET /consents/status)
Ticari mesaj göndermeden HEMEN ÖNCE yapılır:
GET https://iys.org.tr/api/v1/consents/status?phone=%2B90XXXXXXXXXX&brand_code=TITANNAV_001
Content-Type: application/json
Authorization: Basic base64(username:password)
Response (200 OK):
{
"phone": "+90XXXXXXXXXX",
"brand_code": "TITANNAV_001",
"status": "BILDIRIM_ALACAK",
"channels": [
{
"channel_id": "SMS",
"status": "BILDIRIM_ALACAK"
},
{
"channel_id": "EMAIL",
"status": "BILDIRIM_ALACAK"
},
{
"channel_id": "PUSH",
"status": "BILDIRIM_ALACAK"
}
],
"timestamp": "2026-04-23T10:35:00Z"
}
Statüsler:
BILDIRIM_ALACAK→ Onay aktif, mesaj gönder ✓BILDIRIM_ALMAYACAK(RED) → Onay çekilmiş, mesaj gönderim iptal ✗KAYITLI_DEĞİL→ İlgili brand'a onay hiç kaydedilmemiş, gönderim iptal ✗
6.3 Toplu Sorgulama (POST /consents/status/batch)
Kampanya gönderimi öncesi (100+ kişiye), batch endpoint kullan (daha hızlı):
POST https://iys.org.tr/api/v1/consents/status/batch
Content-Type: application/json
{
"brand_code": "TITANNAV_001",
"recipients": [
{ "phone": "+90XXXXXXXXXX", "email": "user1@example.com" },
{ "phone": "+90YYYYYYYYY", "email": "user2@example.com" },
...
]
}
Response (200 OK):
{
"results": [
{
"phone": "+90XXXXXXXXXX",
"email": "user1@example.com",
"status": "BILDIRIM_ALACAK",
"channels": {...}
},
{
"phone": "+90YYYYYYYYY",
"email": "user2@example.com",
"status": "BILDIRIM_ALMAYACAK"
}
]
}
6.4 Onay Çekme / Geri Alma (POST /consents — STATUS=RED)
Kullanıcı "Abonelikten Çık" linkini tıklayınca veya profil ayarlarında toggle kaparsa:
POST https://iys.org.tr/api/v1/consents/withdraw
Content-Type: application/json
{
"brand_code": "TITANNAV_001",
"channels": [
{
"channel_id": "SMS",
"status": "BILDIRIM_ALMAYACAK"
}
],
"recipient": {
"phone": "+90XXXXXXXXXX",
"email": "user@example.com"
},
"timestamp": "2026-04-23T11:00:00Z"
}
Response (200 OK):
{
"transaction_id": "txn_20260423_withdraw_001",
"status": "OK",
"channels_updated": 1
}
Kullanıcı tarafında:
iys_consents.consent_status = REDiys_consents.withdrawn_at = NOW()- Her mesaj gönderimi öncesi sorgulandığında İYS
BILDIRIM_ALMAYACAKdöner → mesaj gönderilmez
6.5 Hata Yönetimi ve Retry Mekanizması
İYS API'si down olursa veya timeout:
Mesaj gönderilecek
↓
İYS GET /consents/status çağır
↓
Başarısız (timeout, 5xx error, vb.)
↓
Retry #1: 5 dakika sonra yeniden dene
↓
Başarısız
↓
Retry #2: 10 dakika sonra
↓
Başarısız
↓
Retry #3: 1 saat sonra
↓
Başarısız (3 başarısızlık)
↓
İYS'ye yazılamadığı uyarısı + iys_sync_queue'ya ekle
↓
Sonraki gün background job retry (max 24 saat)
↓
Başarılı → mesaj gönder
Başarısız → super admin'e alert ("İYS sync hatası — manual kontrol gerek")
Konfigürasyon:
iys.retry_attempts = 3(default)iys.retry_delay_seconds = [300, 600, 3600](5 dk, 10 dk, 1 saat)- Ticari mesaj gönderimi İYS'ye sync başarılı olana kadar asla gönderilmez (legal risk)
- Transactional mesajlar (OTP, ödeme bilgileri) İYS kontrolüne takılmaz — doğrudan gönderilir
7. Uygulama İçi Akışlar ve UI
7.1 Kayıt Ekranı (Sign-Up)
┌─────────────────────────────────────────────┐
│ TitanNav Kaydol │
├─────────────────────────────────────────────┤
│ Ad Soyadı: [________________] │
│ E-Posta: [________________] │
│ Şifre: [________________] │
│ Telefon: [________________] │
│ │
│ ☐ Ticari ileti (SMS, E-posta, Push) │
│ almayı kabul ediyorum. │
│ │
│ ☑ Şartlar ve Koşulları kabul ediyorum. │
│ │
│ [KAYDOL] │
└─────────────────────────────────────────────┘
Önemli Noktalar:
- İleti checkbox DEFAULT: KAPALI ☐
- "Şartlar ve Koşulları" checkbox DEFAULT: KAPALI ☐
- Kullanıcı her ikisini aktif olarak işaretlemeli (pre-checked değil)
7.2 E-Posta Doğrulama Sonrası
E-posta linki tıklandı
↓
Backend: Kayıt formdaki checkbox durumunu kontrol et
↓
EVET idi → iys_consents kaydı yap + İYS sync kuyruk ekle
HAYIR idi → sadece profil oluştur, İYS kaydı yok
↓
Kullanıcıya: "Hoş geldin! Profil oluşturuldu."
7.3 Profil → İletişim Tercihleri
Kullanıcı login sonrası:
┌────────────────────────────────────────────────┐
│ İletişim Tercihleri │
├────────────────────────────────────────────────┤
│ │
│ Ticari İletiler │
│ ─────────────────────────────────────────── │
│ │
│ SMS İletileri (Abonelik, İndirim, vb.) │
│ [Toggle OFF ⟵→ ON] │
│ │
│ E-Posta İletileri (Promosyon, Duyuru) │
│ [Toggle OFF ⟵→ ON] │
│ │
│ Push Bildirimleri (Uygulama bildirimleri) │
│ [Toggle OFF ⟵→ ON] │
│ │
│ Sesli Arama (Acil durum — opsiyonel) │
│ [Toggle OFF ⟵→ ON] │
│ │
├────────────────────────────────────────────────┤
│ İşlemsel İletiler (Her zaman açık) │
│ • OTP Kodları │
│ • Ödeme Bildirimleri │
│ • Şifre Sıfırlama │
│ (Bu iletiler kapatılamaz — güvenlik için) │
└────────────────────────────────────────────────┘
Teknik Akış (Toggle Değiştiğinde):
Toggle SMS ON/OFF yapıldı
↓
Backend: iys_consents tablosu güncelle
{ channel='SMS', consent_status= GREEN (ON) veya RED (OFF) }
↓
iys_sync_queue'ya ekle
{ action: 'WRITE' veya 'WITHDRAW' }
↓
Background job (< 1 dakika): İYS API /withdraw veya /consents çağır
↓
İYS onaylandı: synced_to_iys = TRUE
↓
Kullanıcıya UI'da confirm: "SMS tercihi kaydedildi ✓"
7.4 Ticari Mesajlarda "Abonelikten Çık" Linki
Gönderilen her ticari SMS/E-posta/Pushte:
--- E-POSTA ÖRNEĞI ---
Konu: TitanNav — Aboneliğiniz 3 gün sonra sona eriyor
Merhaba [Ad],
Aboneliğiniz 26.04.2026'de sona erecek. Hemen yenile ve %20 indirim al!
[ABONE OL]
───────────────────────────────────────────
Bu e-postayı almak istemiyorsanız:
[Abonelikten Çık](https://app.titannav.com/unsubscribe?token=xyz)
Linki tıkladığında:
- Benzersiz
unsubscribe_tokenkontrol edilir - İlgili kanal (e-posta bu durumda)
iys_consentsiçinconsent_status = REDgüncellenir - İYS withdraw isteği queue'ya eklenir
- Kullanıcıya: "Abonelikten çıkarıldınız" sayfası gösterilir
- Sonraki ticari mesajlar o kanala gelmez
8. Mesaj Gönderimi Öncesi Kontrol (Zorunlu)
Hiçbir ticari mesaj, İYS sorgusu yapılmadan gönderilemez.
8.1 Background Job: İYS Kontrol Rutini
Şu durumlarda çalışır:
- Abonelik yenileme uyarısı gönderilmek üzere
- Promosyon kampanyası başlamak üzere
- İleri tarihli mesaj şimdi gönderilecek
# pseudocode
def check_and_send_commercial_message(user_id, channel, message_type):
user = get_user(user_id)
# Adım 1: Cache kontrolü (Redis, TTL=24h)
cache_key = f"iys:{user_id}:{channel}"
cached_status = redis.get(cache_key)
if cached_status:
iys_status = cached_status
log(f"İYS Status (cache): {iys_status}")
else:
# Adım 2: Cache miss → İYS API sorgusu
try:
response = iys_api.get_consents_status(
phone=user.phone,
email=user.email,
brand_code=settings.IYS_BRAND_CODE,
timeout=5
)
iys_status = response['status'] # BILDIRIM_ALACAK, BILDIRIM_ALMAYACAK, vb.
redis.setex(cache_key, 86400, iys_status) # 24 saat cache
except IYSAPIException as e:
log_error(f"İYS API error: {e}")
# Retry mekanizması (bkz. 6.5)
iys_sync_queue.add_retry(user_id, channel, "CHECK")
return False # Mesaj gönderilmez
# Adım 3: Onay kontrol
if iys_status != "BILDIRIM_ALACAK":
log(f"İYS Status: {iys_status} — Gönderim İPTAL", user_id, channel)
iys_message_log.insert({
'user_id': user_id,
'channel': channel,
'message_type': message_type,
'iys_check_status': iys_status,
'sent_successfully': False,
'send_error': f"İYS red status: {iys_status}"
})
alert_super_admin(f"Onay olmayan mesaj bloğu: {user_id}/{channel}")
return False
# Adım 4: Onay var → Mesaj gönder
log(f"İYS Status: BILDIRIM_ALACAK — Gönderim BAŞLADI")
try:
if channel == 'SMS':
sms_provider.send(user.phone, message)
elif channel == 'EMAIL':
email_service.send(user.email, message)
elif channel == 'PUSH':
push_service.send(user.device_token, message)
# Adım 5: İYS mesaj log kaydı
iys_message_log.insert({
'user_id': user_id,
'channel': channel,
'message_type': message_type,
'iys_check_status': 'GREEN',
'sent_successfully': True,
'sent_at': now()
})
return True
except SendException as e:
log_error(f"Gönderim başarısız: {e}")
iys_message_log.insert({
'user_id': user_id,
'channel': channel,
'sent_successfully': False,
'send_error': str(e)
})
return False
8.2 Cache Stratejisi
- Redis key:
iys:{user_id}:{channel} - TTL: 24 saat
- Cache hit: Mesaj < 1 ms gönder
- Cache miss: İYS API sorgusu (~200-500 ms), sonuç cache'le
- Rate limit: İYS dk 60 request → batch queries tercih et
9. Ticari vs Transactional Mesaj Ayrımı (Kesin Liste)
9.1 Ticari Mesajlar (İYS ONAY ŞART)
| Mesaj Tipi | Örnek | Kanal | İYS Sorgusu |
|---|---|---|---|
| Abonelik yenileme uyarısı | "Aboneliğiniz 7 gün sonra sona eriyor — yenile" | SMS, Email | ZORUNLU |
| Promosyon / İndirim | "Bu ayda %20 indirim!" | SMS, Email, Push | ZORUNLU |
| Yeni özellik duyurusu | "Yeni rota tipi eklendi" | Email, Push | ZORUNLU |
| Yakıt fiyatı uyarısı (filo) | "Benzin 55 TL/lt'ye düştü" | SMS, Push | ZORUNLU |
| Newsletter | "TitanNav Haberler — Mayıs" | ZORUNLU | |
| Açık çağrı kampanyası | "Referral yapın, bonus kazan!" | SMS, Email | ZORUNLU |
9.2 İşlemsel Mesajlar (İYS MUAF)
| Mesaj Tipi | Örnek | Kanal | İYS Sorgusu |
|---|---|---|---|
| OTP Kodu | "OTP kodunuz: 654321" | SMS | HAYIR |
| E-posta Doğrulama | "Lütfen e-postanızı doğrulayın" | HAYIR | |
| Şifre Sıfırlama | "Şifre sıfırlama linki..." | HAYIR | |
| Ödeme Başarısı | "Ödeme alındı. Ref: 12345" | SMS, Email | HAYIR |
| Ödeme Başarısızlığı | "Ödeme başarısız, kartınızı kontrol edin" | SMS, Email | HAYIR |
| Abonelik İptali Onayı | "Aboneliğiniz iptal edildi" | HAYIR | |
| Kritik Güvenlik Uyarısı | "Hesabınıza şüpheli giriş" | SMS, Email | HAYIR |
| KVKK Veri Talepine Yanıt | "İstediğiniz veriler ektedir" | HAYIR | |
| Sipariş Durumu | "Siparişiniz gönderildi" | SMS, Email | HAYIR |
Kural: Eğer mesajda ticari amaç, tavsiye, promosyon veya pazarlama değeri varsa, İYS onayı gerekir. Aksine, yalnızca işlem bilgilendirmesi ise muaf.
10. Denetim ve Audit
TitanNav admin panelinde (MD: ARCHITECTURE-V2/24-ADMIN-MASTER.md) aşağıdaki raporlar yer alır.
10.1 İYS Senkronizasyon Dashboard
┌─────────────────────────────────────────────────────┐
│ İYS Senkronizasyon Durumu │
├─────────────────────────────────────────────────────┤
│ │
│ Toplam Onay Yazıldı (Son 30 gün): 12.450 │
│ Başarılı Sync: 12.401 (99.6%) │
│ Bekleme Kuyruğu: 49 │
│ Hata: 0 │
│ │
│ Son İYS API Çağrısı: 2 dk önce ✓ │
│ API Yanıt Süresi (avg): 245 ms │
│ │
│ [Kuyruğu İncele] [API Test] [Hata Logları] │
│ │
└─────────────────────────────────────────────────────┘
10.2 Ticari Mesaj Denetim Raporu
Tarih Aralığı: 01.04.2026 — 23.04.2026
Mesaj Türü SMS Email Push TOPLAM
─────────────────────────────────────────────────
Yenileme Uyarısı 8.245 8.320 - 16.565
Promosyon 2.100 2.150 1.800 6.050
Özellik Duyuru 1.200 1.220 1.100 3.520
Yakıt Fiyatı 3.100 - - 3.100
───────────────────────────────────────────────
TOPLAM (Ticari) 14.645 11.690 2.900 29.235
✓ İYS Kontrolü Yapılan: 29.235 (100%)
✓ Onay Var: 28.950 (99.0%)
✗ Onay Yok (Bloklanmış): 285 (1.0%)
✗ İYS Hatası: 0 (0%)
10.3 Mesaj Bazında Kayıt
Admin mesajları filtreleyip detay görebilir:
Filter: Tarih | Mesaj Tipi | Kanal | Durum
ID | User | Kanal | Tip | İYS Status | Gönderim | Zaman
─────────────────────────────────────────────────────────────────────────────
87234 | user@em.com | Email | Renewal | GREEN | ✓ | 23.04 10:30
87233 | +901234567 | SMS | Promo | RED | ✗ | 23.04 10:25
87232 | device_id_x | Push | Feature Ann. | GREEN | ✓ | 23.04 10:20
...
[Detay Aç] → İYS Transaction ID, tam mesaj içeriği, retry log, vb.
10.4 Uyumsuzluk Alarmları
Eğer sistem tespit ederse:
- Onay olmadan ticari mesaj gönderildi
- İYS sync 24 saat başarısız
- API rate limit aşıldı
Aksiyon:
- Super admin'e e-posta uyarısı
- Admin panelde RED badge (⚠️ İYS Uyumsuzluk)
- İlgili mesaj logu quarantine'de tutulur
10.5 Ticaret Bakanlığı Denetimine Hazır Rapor
[İndir] CSV / XLSX
Sütunlar:
- Gönderim Tarihi
- Alıcı (Telefon/E-posta)
- Mesaj Tipi (Pazarlama vs İşlemsel)
- Kanal
- İYS Onay Durumu (GREEN/RED/PENDING)
- Gönderildi mi (Evet/Hayır)
- Neden başarısız olursa: Hata Mesajı
Fatih veya muhasebeci Ticaret Bakanlığı denetimi sırasında bu raporu indir, pdf ye çevir, dosya kapat.
11. Admin Panel Ayarları
MD: ARCHITECTURE-V2/13-RUNTIME-CONFIG.md referans alınarak, aşağıdaki setting'ler app_settings tablosunda:
| Setting Adı | Tipi | Default | Açıklama |
|---|---|---|---|
iys.enabled |
BOOL | TRUE | İYS kontrolü aktif mi? |
iys.api_url |
STRING | https://iys.org.tr/api/v1 |
İYS API base URL |
iys.username |
STRING | (env var) | İYS API kullanıcı adı (encrypted) |
iys.password |
STRING | (env var) | İYS API şifre (encrypted) |
iys.brand_code |
STRING | TITANNAV_001 |
Marka kodu (e-Devlet'ten alınan) |
iys.cache_ttl_hours |
INT | 24 | Redis cache geçerlilik süresi (saat) |
iys.retry_attempts |
INT | 3 | Başarısız sync için retry sayısı |
iys.retry_delay_seconds |
JSON | [300, 600, 3600] |
Retry bekleme süreleri (sn) |
iys.batch_size |
INT | 1000 | Toplu sorgulamada kaç kişi seçilir |
iys.alert_super_admin |
BOOL | TRUE | Uyumsuzluk tespit edilince alert gönder |
Konfigürasyon Örneği:
{
"iys.enabled": true,
"iys.api_url": "https://iys.org.tr/api/v1",
"iys.brand_code": "TITANNAV_001",
"iys.cache_ttl_hours": 24,
"iys.retry_attempts": 3,
"iys.alert_super_admin": true
}
Admin password, username gibi hassas alanlar ENV variable ile set edilir veya admin panelde masked input olarak görülür.
12. Performans ve Ölçek
12.1 İYS API Rate Limit
İYS API'sinin sınırlaması:
- 60 request / dakika
- Batch endpoint: 1 istek = 1000 kişiye kadar
12.2 TitanNav Stratejisi
1-1 sorgudan kaçın:
- Ticari mesaj göndermeden önce
check_and_send_commercial_message()çalışır (bkz. 8.1) - Cache kullan: Redis
iys:{user_id}:{channel}TTL 24 saat - Cache hit → 0 API çağrısı
- Cache miss → 1 API çağrısı (ve cache yaz)
Kampanya gönderimi (1000+ kişi):
- Batch
/consents/status/batchendpoint use (1 sorgu = 1000 kişi) - Örn: 10.000 kişiye promosyon → 10 API çağrısı (1000 başına)
Örnek hesaplama (günlük):
- 50.000 cache hit (0 API çağrısı)
- 2.000 cache miss (2.000 API çağrısı)
- 1 kampanya (10.000 kişi, 10 API çağrısı)
- Toplam: 2.010 / dakika limit 60 → Rate limit içinde, sorun yok
13. KVKK ile İlişki
İYS ticari onay ≠ KVKK aydınlatma/açık rıza.
- KVKK (MD: LEGAL/27-KVKK-TOS-GIZLILIK.md): Kişisel verilerin işlenmesi hakkında aydınlatma + açık rıza
- İYS: Ticari elektronik iletileri almak isteyip istemediği hakkında ayrı onay
Örnek:
Kayıt Formunda 3 Ayrı Onay:
1. ☐ "Aydınlatma Metnini okudum, verilerimin işlenmesini kabul ediyorum" (KVKK)
2. ☐ "Şartlar ve Koşulları kabul ediyorum"
3. ☐ "Ticari ileti almayı kabul ediyorum" (İYS)
Kullanıcının #1 ve #3 yapması gerek (bağımsız).
Teknik olarak:
- KVKK onayı →
user_consents.gdpr_approved = TRUE - İYS onayı →
iys_consents.consent_status = GREEN
Her biri ayrı ayrı izlenmelidir.
14. Fatih'in Yapacağı İşler (Checklist)
Fatih (product owner olarak) veya muhasebeci bu işleri yapmalıdır:
Adım 1: İYS Kaydı (1 kez, hemen)
- iys.org.tr'ye e-Devlet ile giriş (Fatih T.C. Kimlik No + parola)
- "Hizmet Sağlayıcı Kaydı" → ToffeSoft Bilişim Ltd. Şti. şirket bilgileri gir
- MERSİS, Vergi No, Merkez Adresi, KEP Adresi doldur
- Marka "TitanNav" kaydı yap
- 4 kanal (SMS, Arama, E-Posta, Push) seç ve aktif et
- E-imza ile onayla (muhasebeci yardımcı olabilir)
- API credentials al: username, password, IYS_code, Brand_code
- KEP adresi (
{{company.kep_adresi}}) onay e-postalarını kontrol et
Adım 2: Credentials Sisteme Gir (1 kez, hemen sonra)
- Claude Code admin paneline gir (bkz. ARCHITECTURE-V2/24-ADMIN-MASTER.md)
- Settings → İYS Konfigürasyonu bölümüne git
-
iys.api_url,iys.username,iys.password,iys.brand_codegir (encrypted kaydedilir) - API test yap (panelde [API Test] butonu ile)
- ✓ "Test başarılı" mesajı görün
Adım 3: Aylık Denetim
- Admin panelinde "İYS Senkronizasyon Durumu" (10.1) kontrol et
- Hata varsa super admin'e sor
- Ticaret Bakanlığı denetimi durumunda audit raporu (10.5) hazırlayabilir
15. Test Senaryoları
Unit + integration testler aşağıda yapılmalı:
15.1 Yeni Kayıt + Opt-In
Senaryo: Kullanıcı kayıt sırasında ticari onay veriyor
Verilen: TitanNav login olmamış durumda
Zaman: Kayıt formuna git
- Ad: "Ahmet"
- E-posta: "ahmet@example.com"
- Telefon: "+905551234567"
- ☑ "Ticari ileti kabul"
Ve: "Kaydol" tıkla
Sonuç:
- users tablosunda kayıt var
- iys_consents.consent_status = "PENDING" (henüz İYS'ye yazılmadı)
- İYS sync queue'ya giriş oluştu
Zaman: E-posta doğrulama linki tıkla
Sonuç:
- iys_consents.consent_status = "GREEN" (İYS'ye yazıldı)
- iys_consents.synced_to_iys = TRUE
- iys_consents.iys_tx_id dolduruldu
15.2 Onay Çekme / Withdraw
Senaryo: Kullanıcı SMS almak istemiyor (toggle OFF)
Verilen: Kullanıcı login, profil açık
Zaman: "SMS İletileri" toggle OFF yap
Sonuç:
- iys_consents.channel='SMS', consent_status = "RED"
- iys_sync_queue'ya withdraw isteği eklendi
Zaman: 5 saniye bekle (background job çalış)
Sonuç:
- İYS API /withdraw çağrıldı
- iys_consents.synced_to_iys = TRUE
- İşlemsel mesajlar (OTP, etc.) SMS ile gelerek devam et
15.3 İYS Down → Queue ve Retry
Senaryo: İYS API'si down iken kullanıcı kayıt yapıyor
Verilen: İYS API'si 502 error dönüyor (test env)
Zaman: Kullanıcı kayıt + "ticari ileti" opt-in yap
Sonuç:
- iys_consents kaydı yapıldı (PENDING)
- Background job İYS API çalıştırmaya çalıştı → 502 hatası
- iys_sync_queue'da retry_count = 1, next_retry_at = +5 dk
Zaman: 5 dakika + 1 saniye bekle
Sonuç:
- Background job #2 retry çalıştırdı → başarılı (İYS up oldu)
- iys_consents.synced_to_iys = TRUE
- iys_sync_queue record silinir
15.4 İşlemsel Mesaj → İYS Sorgusu YOK
Senaryo: OTP mesajı gönderiliyor (İYS bağımsız)
Verilen: Kullanıcı login işlemi
Zaman: sistem OTP gönder istedi
Akış:
- check_and_send_commercial_message() ÇALIŞMAZ (OTP = transactional)
- OTP doğrudan sms_provider.send() yapılır
- İYS cache, API, queue KONTROL YAPILMAZ
Sonuç:
- OTP 5 saniye içinde SMS ile alındı
- İYS logu boş (transactional olduğu için)
15.5 Promosyon Kampanyası (Toplu Gönderim)
Senaryo: Admin "% 20 indirim kampanyası" başlatıyor (10.000 kişi)
Verilen: Admin panelinde kampanya oluşturuldu
Zaman: "Gönder" butonu tıkla
Akış:
- Backend: 10.000 kişi SMS/Email listesi hazırla
- Batch: POST /consents/status/batch (10 çağrı, 1000'er kişi)
- Response: Her kişi için GREEN/RED status
- Filter: Sadece GREEN kişilere mesaj gönder (9.800 ✓, 200 ✗)
Sonuç:
- 9.800 mesaj gönderildi
- 200 mesaj bloklandı (onay yok)
- iys_message_log'ta kayıt var
- Admin dashboard'da "Ticari Mesaj Denetim Raporu" gösterir
16. Hata Durumları ve Fallback
16.1 İYS Tamamen Down
TitanNav ticari mesaj gönderme işlemi
↓
İYS API sorgusu yapılamıyor (timeout/5xx)
↓
3 retry başarısız
↓
KARARINIZ:
A) Transactional mesajlar gönder, ticari mesajları durdur (GÜVENLİ)
B) Cache kullan (eğer varsa, max 24 saat eski)
TitanNav Kararı: A (GÜVENLİ YÖNTEM)
→ Ticari mesaj gönderilmez (legal risk var)
→ Transactional (OTP, etc.) gönderilir
→ Super admin uyarısı
→ İYS recovery ertesi gün retry
16.2 Rate Limit Aşılması
İYS API dakika 60 istek limit:
Eğer: 60 + istekler geliyor
↓
İYS 429 Too Many Requests dönüyor
↓
TitanNav: Queue'ya ekle, 1 dakika sonra retry
↓
Kampanya gönderimi hızı sınırlandırılır
→ batch endpoint kullan (1000 başına 1 request)
16.3 Geçersiz Onay Datası
İYS response: { status: "KAYITLI_DEĞİL" }
Anlam: İlgili brand'a hiç onay kaydı yok
↓
Sebep:
- Kullanıcı kayıt sırasında checkbox işaretlemedi
- İYS sync başarısız oldu (retry > 3)
- Kullanıcı withdraw yaptı
↓
Aksiyon: Mesaj gönderilmez
↓
Admin log: "User {id} {channel} no consent recorded in İYS"
17. Özet: İYS Entegrasyonunun Temel Sütunları
| Sütun | Açıklama |
|---|---|
| Onay Kaydı | Kullanıcı opt-in → İYS'ye 3 iş günü içinde yazılmalı |
| Mesaj Kontrolü | Her ticari mesaj öncesi İYS sorgusu (cache ile optimize) |
| Kanal Yönetimi | SMS/Email/Push/Arama bağımsız, kullanıcı toggle yapabilir |
| Compliance | Ticari vs transactional kesin ayrım, audit log tutma |
| Hata Yönetimi | İYS down → ticari mesaj durdur, transactional devam |
| Admin Kontrol | Real-time dashboard, denetim raporu, uyumsuzluk alarmı |
| Fatih İşleri | e-Devlet kayıt, API credentials giriş, aylık denetim |
18. Referanslar
- İYS Platform: https://www.iys.org.tr
- Mevzuat: 6563 sayılı E-Ticaret Kanunu, 15.07.2015 Yönetmeliği
- İlgili TitanNav MDs:
- LEGAL/27-KVKK-TOS-GIZLILIK.md
- LEGAL/19-DPA.md
- ARCHITECTURE-V2/23-BILDIRIMLER.md (mesaj sistemi)
- ARCHITECTURE-V2/13-RUNTIME-CONFIG.md (admin settings)
- ARCHITECTURE-V2/24-ADMIN-MASTER.md (admin panel)
Sürüm Geçmişi
| Versiyon | Tarih | Notlar |
|---|---|---|
| v1.0 | 2026-04-23 | İlk yayın (Fatih onayı, K-05 kararı — 6563 Kanun uyumluluğu) |
Son İnceleme: Fatih'in teknik olmayan okuma yeteneği için sade Türkçe, terimlere parentez eklendi. İYS akışı akış diyagramları ve tablolar ile gösterildi.