Google & Stripe Enterprise Standard

Yanitly Kurumsal Webhook Entegrasyonu

10 dikey sektör (E-Ticaret, Klinik, Otel, Restoran, Spor, Emlak, Ses AI, CRM vb.) için 50+ anlık olay bildirimi, RFC 2104 HMAC-SHA256 replay-attack korumalı çift imza ve sıfır kesintili anahtar rotasyonu.

Genel Bakış

Yanitly Webhook motoru, platformunuzda gerçekleşen her önemli aksiyonu (yeni sipariş, randevu onayı, sesli arama analizi, lead yakalama veya destek devri) anında harici ERP, CRM veya sunucularınıza güvenle iletir.

Milisecond Latency

CloudEvents 1.0 standart formatında alt-saniyelik JSON teslimatı

Replay-Attack Koruması

300s toleranslı t=...,v1=... HMAC-SHA256 imzası

Sıfır-Kesintili Rotasyon

24 saat çift-imza ile kesintisiz gizli anahtar değişimi

10 Sektör & 50+ Doğrulanmış Olay Kataloğu

Şirketinizin sektörüne özel tasarlanmış olayları dinleyebilir, dilerseniz ecommerce.* gibi sektörel wildcard veya * genel joker karakteriyle tüm olayları tek uç noktada toplayabilirsiniz.

E-Ticaret & Perakende (E-Commerce)ecommerce.*
ecommerce.order.createdMüşteri yeni bir sipariş verdiğinde tetiklenir.
ecommerce.order.paidSipariş ödemesi başarıyla tamamlandığında tetiklenir.
ecommerce.order.shippedSipariş kargoya verildiğinde ve takip kodu atandığında tetiklenir.
ecommerce.order.deliveredKargo müşteriye teslim edildiğinde tetiklenir.
ecommerce.cart.abandonedKullanıcı sepetine ürün ekleyip satın almayı tamamlamadığında tetiklenir.
ecommerce.cart.recoveredYapay zeka hatırlatması ile terk edilen sepet satışa dönüştüğünde tetiklenir.
ecommerce.return.requestedMüşteri iade veya değişim talebi oluşturduğunda tetiklenir.
ecommerce.inventory.low_stockÜrün stoğu kritik eşiğin altına indiğinde tetiklenir.
Klinik, Sağlık & Randevu (Clinic & Healthcare)clinic.*
clinic.appointment.bookedHasta yeni bir randevu oluşturduğunda tetiklenir.
clinic.appointment.confirmedHasta veya klinik yetkilisi randevuyu teyit ettiğinde tetiklenir.
clinic.appointment.rescheduledRandevu tarihi/saati ertelendiğinde tetiklenir.
clinic.appointment.cancelledRandevu iptal edildiğinde tetiklenir.
clinic.reminder.confirmedHasta gelen hatırlatma mesajına "Geliyorum" yanıtı verdiğinde tetiklenir.
clinic.treatment.createdYeni bir tedavi protokolü veya fiyat teklifi oluşturulduğunda tetiklenir.
Otel & Konaklama (Hotel & Hospitality)hotel.*
hotel.reservation.createdYeni bir oda rezervasyonu oluşturulduğunda tetiklenir.
hotel.reservation.confirmedRezervasyon depozitosu alınıp kesinleştiğinde tetiklenir.
hotel.guest.checked_inMisafir otele giriş yaptığında (check-in) tetiklenir.
hotel.concierge.requestedMisafir oda servisi, transfer veya ek hizmet talep ettiğinde tetiklenir.
Restoran & Yeme-İçme (Restaurant & Dining)restaurant.*
restaurant.booking.createdMasa rezervasyonu talebi oluşturulduğunda tetiklenir.
restaurant.guest.seatedMisafir masaya oturtulduğunda tetiklenir.
restaurant.table.assignedRezervasyona özel masa atandığında tetiklenir.
Sesli Asistan & Telefon AI (Yanitly SIP / OpenAI Live)voice.*
voice.call.startedGelen veya giden sesli yapay zeka araması başladığında tetiklenir.
voice.call.endedSesli arama sonlandığında süre ve temel metriklerle tetiklenir.
voice.call.summary_readyYapay zeka görüşme özeti, duygu analizi ve aksiyon maddeleri hazırlandığında tetiklenir.
voice.call.human_escalationArayan kişi canlı bir temsilciye aktarılmak istediğinde tetiklenir.
Çekirdek Destek & Sohbet (Core Support)core.*
core.conversation.createdYeni bir sohbet oturumu açıldığında tetiklenir.
core.conversation.closedKonuşma çözüme kavuşturulup kapatıldığında tetiklenir.
core.message.receivedZiyaretçiden yeni mesaj geldiğinde tetiklenir.
core.handover.requestedZiyaretçi temsilciye devir istediğinde tetiklenir.
core.ticket.createdYeni bir destek bileti oluşturulduğunda tetiklenir.
CRM & Müşteri Zekası (CRM & Intelligence)crm_ai.*
crm.lead.capturedSohbet veya formdan yeni potansiyel müşteri yakalandığında tetiklenir.
crm.lead.score_changedYapay zeka lead skorunu (soğuk/ılık/sıcak) güncellediğinde tetiklenir.
ai.churn_risk.flaggedMüşteri mesajında memnuniyetsizlik veya ayrılma riski tespit edildiğinde tetiklenir.

CloudEvents 1.0 Standart Zarf Yapısı

Tüm giden webhook bildirimleri CNCF CloudEvents 1.0 spesifikasyonuna uygundur. Bu sayede AWS EventBridge, GCP Eventarc, Zapier ve kurumsal mesajlaşma kuyruklarıyla doğrudan tak-çalıştır uyumluluk sağlar:

CloudEvents 1.0 Standart Gövdesi (Örnek: E-Ticaret Siparişi)json
{
  "specversion": "1.0",
  "id": "evt_01J8Y4V9X8Z6B2M0W1C3D4E5F6",
  "type": "ecommerce.order.created",
  "source": "https://api.yanitly.com/v1/tenants/ten_998877",
  "time": "2026-09-27T00:15:30.124Z",
  "datacontenttype": "application/json",
  "tenant_id": "ten_998877",
  "sector": "ecommerce",
  "api_version": "2026-09-26",
  "data": {
    "orderId": "ord_100234",
    "orderNumber": "TR-2026-8819",
    "totalAmount": 3499.50,
    "currency": "TRY",
    "customer": {
      "id": "cust_5544",
      "name": "Merve Demir",
      "email": "[email protected]",
      "phone": "+905321112233"
    },
    "items": [
      {
        "sku": "MONT-DERI-01",
        "name": "Hakiki Deri Ceket",
        "quantity": 1,
        "unitPrice": 3499.50
      }
    ],
    "status": "paid"
  }
}

RFC 2104 HMAC-SHA256 Güvenlik & Replay Attack Koruması

Her webhook isteği HTTP başlığında Yanitly-Signature taşır. Formatı Stripe ve GitHub standartlarındadır:

Yanitly-Signature: t=1727384400,v1=5d41402abc4b2a76b9719d911017c592...

• t (Zaman Damgası): İsteğin üretildiği Unix zaman damgası (saniye). Sunucunuz gelen zaman damgası ile kendi saati arasında 300 saniyeden (5 dk) fazla fark varsa isteği reddetmelidir.

• v1 (İmza): HMAC-SHA256(gizli_anahtar, t + "." + ham_json_gövdesi) çıktısıdır.

• Sabit Zamanlı Karşılaştırma: Timing-attack açıklarını önlemek için imza doğrulaması mutlaka timingSafeEqual ile yapılmalıdır.

Doğrulama SDK Kod Örnekleri (Copy & Paste)

Sunucunuzun dilini seçerek hazır doğrulama fonksiyonunu doğrudan projenize entegre edebilirsiniz:

import crypto from 'node:crypto';
import express from 'express';

const app = express();

// Ham JSON gövdesini (raw body) string olarak saklayın:
app.use(express.json({
  verify: (req, _res, buf) => {
    (req as any).rawBody = buf.toString('utf-8');
  }
}));

function verifyYanitlySignature(
  rawBody: string,
  signatureHeader: string | undefined,
  secret: string,
  toleranceSeconds = 300 // 5 dakika replay attack toleransı
): boolean {
  if (!signatureHeader || !rawBody) return false;

  const parts = signatureHeader.split(',');
  const timestampPart = parts.find((p) => p.startsWith('t='));
  const signatureParts = parts.filter((p) => p.startsWith('v1='));

  if (!timestampPart || signatureParts.length === 0) return false;

  const timestamp = Number(timestampPart.slice(2));
  if (isNaN(timestamp)) return false;

  // Replay Attack Koruması
  const now = Math.floor(Date.now() / 1000);
  if (Math.abs(now - timestamp) > toleranceSeconds) {
    console.error('Webhook zaman damgası tolerans dışı (Replay attack şüphesi)');
    return false;
  }

  // Beklenen HMAC-SHA256 hesaplama: secret + "t.payload"
  const expectedSig = crypto
    .createHmac('sha256', secret)
    .update(`${timestamp}.${rawBody}`, 'utf-8')
    .digest('hex');

  // Sıfır-kesintili rotasyonda v1=yeni,v1=eski şeklinde birden fazla v1 gelebilir
  return signatureParts.some((part) => {
    const candidateSig = part.slice(3);
    if (candidateSig.length !== expectedSig.length) return false;
    return crypto.timingSafeEqual(
      Buffer.from(candidateSig),
      Buffer.from(expectedSig)
    );
  });
}

app.post('/api/webhooks/yanitly', (req, res) => {
  const signature = req.headers['yanitly-signature'] as string;
  const rawBody = (req as any).rawBody;

  const isValid = verifyYanitlySignature(rawBody, signature, process.env.YANITLY_WEBHOOK_SECRET!);
  if (!isValid) {
    return res.status(401).json({ error: 'Invalid Yanitly-Signature' });
  }

  const { id, type, data, time, sector } = req.body;
  console.log(`[Yanitly Webhook] Olay: ${type} (ID: ${id}, Sektör: ${sector})`);

  // Asenkron işlem kuyruğuna alın ve hemen 200 dönün
  res.status(200).json({ received: true });
});

Sıfır-Kesintili (Zero-Downtime) 24h Anahtar Rotasyonu

Güvenlik gereği anahtarınızı yenilediğinizde sunucunuzun hemen yeni anahtara geçememe riskine karşın Yanitly, 24 saatlik geçiş süreci (grace period) tanır:

Rotasyon süresince başlıkta iki imza birden gönderilir:Yanitly-Signature: t=1727384400,v1=<yeni_imza>,v1=<eski_imza>Sunucunuz ister eski anahtarla ister yeni anahtarla doğrulama yapsın, istek başarıyla geçer. Sunucunuzu güncelledikten sonra panelden "Rotasyonu Onayla" butonuna basarak eski anahtarı tek tıkla iptal edebilirsiniz.

Akıllı Devre Kesici (Circuit Breaker) & DLQ Politikası

Sunucunuzda çökme veya uzun süreli kesinti yaşandığında sisteminizi gereksiz HTTP trafiğiyle boğmamak ve Yanitly kaynaklarını korumak için koruma mekanizmaları devrededir:

Üstel Geri Çekilme (Exponential Backoff):Her başarısız denemede bekleme süresi katlanarak artar: 1. deneme hemen, 2. deneme 1 dk, 3. deneme 5 dk, 4. deneme 30 dk, 5. deneme 2 saat sonra yapılır.
100 Ardışık Başarısızlıkta Otomatik Kilit:Uç nokta 100 ardışık istek boyunca aralıksız hata döndürürse devre kesici devreye girer (disabled_circuit_breaker). Sunucunuzu onardıktan sonra panelden "Devre Kesiciyi Sıfırla" butonuyla anında açabilirsiniz.
Teslimat Müfettişi (Delivery Inspector):Gönderilen her isteğin HTTP durumu, tam giden/gelen gövdesi ve gecikme süresi (ms) panelinizde saklanır ve tek tıkla yeniden tetiklenebilir (redeliver).

En İyi Uygulamalar

Her zaman imza doğrulaması yapın
Webhook işlemlerini asenkron olarak gerçekleştirin
200 yanıtını hızlı dönün, ağır işlemleri kuyruğa alın
Idempotent olaylar için event ID kontrolü yapın
Webhook loglarını izleyin ve saklayın
Timeout sürenizi 30 saniyenin altında tutun
Hata durumlarını loglayın ve izleyin