İçeriğe geç

Entegrasyonlar

Webhook'lar

Firma ya da kişi oluşturulduğunda, sözleşme onaylandığında, tahsilat kaydedildiğinde ya da ziyaretçi kaydolduğunda efuar'ın sisteminize gönderdiği imzalı iletiler ve doğrulanmaları.

Menüdeki yeri
Ayarlar › API ve Webhook
Gerekli yetki
API anahtarlarını ve webhook'ları yönetme
Paket özelliği
API Erişimi

Ne işe yarar

Webhook, efuar'da bir olay olduğunda sizin sisteminize kendiliğinden gönderilen bir iletidir. Sisteminiz API'yi sürekli sorgulamak yerine, örneğin bir sözleşme onaylandığında ya da bir tahsilat kaydedildiğinde haberi kısa sürede alır. İletiyi alacak adrese uç denir; uçlar Ayarlar › API ve Webhook ekranının Webhook'lar sekmesinde tanımlanır.

Her ileti, ucun imza anahtarıyla imzalanır. Sisteminiz imzayı denetleyerek iletinin efuar'dan geldiğini ve yolda değişmediğini doğrular.

Olaylar

Ekrandaki adı Kod Ne zaman gönderilir
Firma oluşturuldu company.created Bir firma kaydı oluşturulduğunda, nasıl oluşturulduğundan bağımsız olarak.
Kişi oluşturuldu contact.created Bir firmaya kişi eklendiğinde.
Sözleşme onaylandı contract.approved Bir satış sözleşmesi onaylandığında; yeni sözleşme sürümünün onayı da bildirilir. Devir sözleşmeleri bildirilmez.
Tahsilat alındı payment.received Yeni bir tahsilat kaydedildiğinde.
Ziyaretçi kaydoldu visitor.registered Bir ziyaretçi bir fuara kaydolduğunda: online formla, davetiyeyle, girişte ya da dosyadan aktarımla.

Yalnız bu beş olay bildirilir. Bir kaydın değişmesi, silinmesi ya da iptali için (örneğin tahsilatın iptali ya da kart ödemesinin iadesi) ileti gönderilmez.

Uç tanımlamak

  1. Ayarlar › API ve Webhook ekranında Webhook'lar sekmesini açın.
  2. Adres alanına iletileri alacak adresi yazın. Adres https:// ile başlayan tam bir adres olmalıdır (en fazla 500 karakter). efuar yalnız internete açık adreslere ileti gönderir; yerel ağ adresleri (ör. 192.168.…) çalışmaz.
  3. Açıklama alanına ucun hangi sisteme ait olduğunu yazın (isteğe bağlı, en fazla 200 karakter).
  4. Bildirilecek olaylar altında en az bir olay işaretleyin.
  5. Uç ekle düğmesine tıklayın.
  6. Sayfanın üstündeki kutuda gösterilen imza anahtarını kopyalayıp iletileri alacak sistemin ayarlarına yazın. Anahtar whsec_ ile başlar ve bir daha gösterilmez.
  7. Satırdaki Deneme gönder simgesiyle bir deneme iletisi gönderin ve ulaştığını görün.

Bir organizatörde en fazla 10 uç olabilir. Aynı olay birden çok uca bildirilebilir; her uç kendi iletisini alır.

İletinin biçimi

efuar, seçilen olay olunca ucun adresine JSON gövdeli bir POST isteği gönderir:

POST /fuar/webhook HTTP/1.1
Host: ornek.com
Content-Type: application/json; charset=utf-8
User-Agent: FairPlatform-Webhooks/1
X-FairPlatform-Event: contract.approved
X-FairPlatform-Delivery: 1234
X-FairPlatform-Signature: t=1791619200,v1=5f0c…

{"id":"6f1d…","type":"contract.approved","createdAt":"2026-10-10T08:00:00+00:00","data":{…}}
Başlık İçeriği
X-FairPlatform-Event Olayın kodu; deneme iletisinde ping.
X-FairPlatform-Delivery İletinin numarası; aynı iletinin yeniden denemelerinde değişmez.
X-FairPlatform-Signature İmza: t= gönderim anı (Unix saniye), v1= imzanın kendisi.

Gövdedeki alanlar:

  • id: olayın kimliği. Aynı olay birden çok uca aynı id ile gider. Bir ileti ikinci kez gelirse onu bu kimlikle tanıyıp yok sayın.
  • type: olayın kodu.
  • createdAt: olayın kaydedildiği an (UTC).
  • data: olayın konusu olan kaydın bilgileri. Tutarlar, ekranlarda gördüğünüz kayıttan gelir.

data alanları

Olay Alanlar
company.created id, name, legalName, taxNumber, taxOffice, stage (Lead Potansiyel, Prospect Aday müşteri, Customer Müşteri), phone, email, website
contact.created id, companyId, firstName, lastName, title, department, email, phone, mobile, isPrimary
contract.approved id, number, revision, revisedFromId, companyId, companyName, fairId, participationId, contractDate, approvedAt, currency, subtotal, discountTotal, vatTotal, grandTotal
payment.received id, number, companyId, fairId, date, method (Cash Nakit, BankTransfer Havale / EFT, CreditCard Kredi kartı, Cheque Çek, PromissoryNote Senet, Other Diğer), amount, currency, reference
visitor.registered id, fairId, visitorId, firstName, lastName, email, companyName, source (Online Online kayıt, Invitation Davetiye, OnSite Girişte kayıt, Import Dosyadan aktarım), registeredAt

fairId ve participationId, Organizatör API'si içindeki fuar ve katılım numaralarıdır; ayrıntıyı oradan okuyabilirsiniz. Bir fuara bağlanmamış tahsilatta fairId boştur. Sözleşmenin yeni sürümünde revision sürüm numarasını, revisedFromId yerini aldığı sözleşmeyi verir; bütün sürümler aynı number değerini taşır. visitor.registered iletisinde id ziyaretçinin fuar kaydının, visitorId kişinin numarasıdır. Günler (contractDate, date) yyyy-MM-dd, anlar UTC olarak yazılır.

{
  "id": "6f1d2c3a-0b7e-4c1d-9a55-2f3e4d5c6b7a",
  "type": "contract.approved",
  "createdAt": "2026-10-10T08:00:00+00:00",
  "data": {
    "id": 3105,
    "number": "SZL-2026-00042",
    "revision": 2,
    "revisedFromId": 3090,
    "companyId": 881,
    "companyName": "Örnek Ahşap A.Ş.",
    "fairId": 229,
    "participationId": 5120,
    "contractDate": "2026-10-09",
    "approvedAt": "2026-10-10T07:59:41+00:00",
    "currency": "EUR",
    "subtotal": 12000.00,
    "discountTotal": 600.00,
    "vatTotal": 2280.00,
    "grandTotal": 13680.00
  }
}

İmzayı doğrulamak

  1. X-FairPlatform-Signature başlığını virgülden bölün ve t ile v1 değerlerini alın.
  2. t değerini, bir noktayı ve gövdeyi yan yana yazın: {t}.{gövde}. Gövdeyi geldiği haliyle kullanın; JSON'u ayrıştırıp yeniden yazarsanız imza tutmaz.
  3. Bu metnin HMAC-SHA256 değerini ucun imza anahtarıyla hesaplayın ve küçük harfli onaltılık (hex) metne çevirin. Anahtar, başındaki whsec_ dahil olduğu gibi kullanılır.
  4. Sonuç v1 ile aynı değilse iletiyi reddedin.
  5. t çok eskiyse (örneğin 5 dakikadan eski) iletiyi yine reddedin; böylece yakalanıp sonradan yeniden gönderilen bir ileti kabul edilmez.

Her deneme gönderildiği anda yeniden imzalanır; yeniden denenen bir ileti yeni bir t taşır.

using System.Linq;
using System.Security.Cryptography;
using System.Text;

static bool IsValidSignature(string signatureHeader, string rawBody, string secret)
{
    var parts = signatureHeader.Split(',')
        .Select(part => part.Trim().Split('=', 2))
        .Where(pair => pair.Length == 2)
        .ToDictionary(pair => pair[0], pair => pair[1]);
    if (!parts.TryGetValue("t", out var t) || !parts.TryGetValue("v1", out var v1)
        || !long.TryParse(t, out var sentAt)
        || Math.Abs(DateTimeOffset.UtcNow.ToUnixTimeSeconds() - sentAt) > 300)
    {
        return false;
    }

    var mac = HMACSHA256.HashData(Encoding.UTF8.GetBytes(secret), Encoding.UTF8.GetBytes($"{t}.{rawBody}"));
    var expected = Convert.ToHexString(mac).ToLowerInvariant();
    return CryptographicOperations.FixedTimeEquals(Encoding.ASCII.GetBytes(expected), Encoding.ASCII.GetBytes(v1));
}
const crypto = require('node:crypto');

function isValidSignature(signatureHeader, rawBody, secret) {
  const parts = Object.fromEntries(signatureHeader.split(',').map((part) => part.trim().split('=')));
  const sentAt = Number(parts.t);
  if (!parts.v1 || !Number.isInteger(sentAt) || Math.abs(Date.now() / 1000 - sentAt) > 300) {
    return false;
  }
  const expected = crypto.createHmac('sha256', secret).update(`${parts.t}.${rawBody}`, 'utf8').digest('hex');
  const a = Buffer.from(expected);
  const b = Buffer.from(parts.v1);
  return a.length === b.length && crypto.timingSafeEqual(a, b);
}

İki örnekte de rawBody, isteğin gövdesinin geldiği haliyle okunmuş metnidir.

Yanıt, yeniden deneme ve duraklatma

  • Yanıt verin: iletiyi aldığınızda 10 saniye içinde 2xx bir kodla (ör. 200 ya da 204) yanıt verin. Uzun sürecek işleri yanıttan sonra yapın; 10 saniyede yanıt gelmezse ileti ulaşmamış sayılır.
  • Gönderim: iletiler dakikada bir, eskiden yeniye gönderilir (her seferde organizatör başına en çok 100 ileti). Değişiklik kaydedildiyse iletisi de kaydedilmiştir; kaydedilmeyen bir değişiklik için ileti yazılmaz.
  • Yeniden deneme: 2xx alınamazsa ileti Yeniden denenecek olur ve en çok 6 kez denenir: ilk denemeden sonra yaklaşık 1 dakika, 5 dakika, 30 dakika, 2 saat ve 6 saat arayla. Altıncı deneme de başarısız olursa ileti Bırakıldı durumuna geçer.
  • Sıra ve tekrar: yeniden denenen bir ileti, kendisinden sonraki olayların iletilerinden sonra ulaşabilir; sıra için createdAt alanına bakın. Sisteminiz iletiyi işlediği halde yanıtı efuar'a zamanında ulaşmadıysa aynı ileti yeniden gelir; id ile tanıyıp yok sayın.
  • Duraklatma: bir uca art arda 20 deneme başarısız olursa uç Duraklatıldı durumuna geçer; ulaşan her ileti bu sayacı sıfırlar. Sorunu giderdikten sonra ucu satırdaki Aç simgesiyle yeniden açın.
  • Kapalı uç: kapalı ya da duraklatılmış bir uç için yeni ileti yazılmaz; uç yeniden açıldığında arada olan olaylar sonradan gönderilmez. Uç kapalıyken sırası gelen iletiler Bırakıldı olur.
  • Paket: paketinizde API Erişimi kapanırsa ya da aboneliğiniz geçerliliğini yitirirse sırası gelen iletiler gönderilmez, Bırakıldı olur.

İpucu: Deneme gönder, kapalı ya da duraklatılmış bir uca da gönderilir ve duraklatma sayacına eklenmez. Ucu yeniden açmadan önce alıcının düzeldiğini bununla denetleyebilirsiniz.

Son iletiler ve yeniden gönderme

Sekmenin altındaki Son iletiler tablosu gönderilen son 50 iletiyi gösterir: Zaman, Olay, Uç, Durum ve Yanıt (alıcının HTTP kodu ya da "Alıcı 10 saniye içinde yanıt vermedi." gibi bir hata). Birden çok denenen iletide deneme sayısı da yazar. Durumlar: Sırada, Ulaştı, Yeniden denenecek ve Bırakıldı.

Yeniden denenecek ya da Bırakıldı durumundaki bir iletinin satırındaki Yeniden gönder düğmesi, iletiyi deneme sayısını sıfırlayarak hemen sıraya alır; ileti bir sonraki gönderimde, yaklaşık bir dakika içinde gider. Ulaşmış iletiler ve deneme iletileri yeniden gönderilmez.

Günlükte ulaşan iletiler 30 gün, bırakılan iletiler 90 gün tutulur; sonra silinir.

Deneme iletisi

Deneme gönder, uca hemen bir ping iletisi gönderir ve sonucu sayfanın üstünde söyler: "Deneme iletisi ulaştı (HTTP 200)." ya da "Deneme iletisi ulaşmadı: …". Deneme bir kez gönderilir, yeniden denenmez ve Son iletiler tablosunda Deneme olarak görünür. Gövdesi diğer iletilerle aynı biçimdedir ve aynı anahtarla imzalanır:

{"id":"…","type":"ping","createdAt":"2026-10-10T08:00:00+00:00","data":{"message":"FairPlatform webhook test","organization":"Örnek Fuarcılık A.Ş."}}

İmza anahtarını yenilemek ve ucu değiştirmek

  • İmza anahtarını yenile, onay sorusundan sonra yeni bir anahtar üretir ve bir kez gösterir. Eski anahtar hemen geçersiz olur: bundan sonraki her gönderim, sırada bekleyen iletiler dahil, yeni anahtarla imzalanır. Geçiş sırasında imzası tutmayan iletiyi 2xx dışı bir kodla reddederseniz ileti yeniden denenir ve yeni anahtarı sisteminize yazdıktan sonra ulaşır.
  • Düzenle ile adresi, açıklamayı ve olayları değiştirebilirsiniz. Sırada bekleyen iletiler de yeni adrese gider; olay seçimi yalnız bundan sonraki olayları etkiler.
  • Sil ucu kaldırır; sırada bekleyen iletileri gönderilmez.

Kişisel veriler

contact.created ve visitor.registered iletileri ad, e-posta ve telefon gibi kişisel veriler taşır; bu olaylar için yalnız kendi sisteminize ait bir adres tanımlayın. Bir kişinin ya da ziyaretçinin kişisel verileri efuar'da silindiğinde onunla ilgili iletiler günlükten silinir; henüz gönderilmemiş olanlar hiç gönderilmez.

Önemli: Daha önce ulaşmış iletiler sizin sisteminizde kalır. Bir silme talebini kendi sisteminizde ayrıca karşılayın; efuar silme için ileti göndermez.

İlgili sayfalar