Süper GelsinPartner APIv1.0.0
API Referansı
TREN
Başlangıç
  • Hemen Başla
  • Test Ortamı (Sandbox)
  • Yetkilendirme
  • Servis Limitleri
  • Test hesabı başvurusu
Ortak uçlar
  • İşletme
  • Sipariş Yaşam Döngüsü
  • Sipariş Durumları
  • Mali Belge
  • Kurye Firması Entegrasyonu
  • Müşteri Talepleri
  • Değerlendirmeler
  • Webhook
Yemek
  • Menü ve Ürün Eşleme
Çarşı
  • Çarşı'ya genel bakış
  • Katalog
  • Toplama ve Dönüş
Referans
  • Sürümleme ve Hız Sınırı
  • Hata Kodları ve Sorun Giderme
  • Changelog
  • Sıkça Sorulan Sorular
  • API Referansı
Geliştirici Portalı/Ortak uçlar

Webhook

Webhook adresinin yazılması, anlık sipariş bildirimleri, imza doğrulama, tekilleştirme ve tekrar deneme.

Bu sayfadaki uçlar

Her satır API referansındaki tam tanıma gider — alanlar, yanıt kodları ve deneme konsolu orada.

  • GET/webhook
  • PUT/webhook
  • DELETE/webhook
  • POST/webhook/test

Olaylar

AlanTipAçıklama
order.createdeventYeni sipariş.
order.updatedeventDurum değişimi (restoranda preparing, ready, on_the_way, delivered; Çarşı'da confirmed, preparing, on_the_way, delivered). Restoranda online ödenmiş teslim edilemedi siparişi de bu olayla gelir (deliveryFailed.completedSale: true); iptal değildir.
order.cancelledeventSipariş iptali (müşteri, destek ya da işletme kaynaklı). Çarşı'da teslim edilemedi sipariş de bu olayla gelir.
İptal ayrı bir olaydır; order.updated içine gömülmez. Bu olayı işlemezseniz iptal edilen sipariş kasanızda açık kalır. Restoranda online ödenmiş teslim edilemedi sipariş iptal sayılmaz: order.updated ile gelir ve kasada satış olarak kapanır.

Gövde: {eventId, event, sentAt, order}. order alanı GET /orders/{id} yanıtıyla aynı nesnedir. Olay tipini gövdedeki event alanından okuyun; başlıklar imzanın kapsamı dışındadır. Kasa yazılımının kendi yazdığı durum webhook olarak geri gönderilmez.

Adresi yazma

Webhook adresini yalnız bu API yazar; işletme panelinde ve mobil uygulamada salt okunur görünür. PUT /webhook adresi, anahtarın bağlı olduğu işletme için kaydeder (iki dikeyde aynı uç); GET /webhook okur, DELETE /webhook kaydı kaldırır (kayıt yoksa da 200 döner) ve teslim durur. Webhook tanımlı değilse sipariş olayları yalnız GET /orders ile izlenir.

Adres kaydı
curl -X PUT "https://api.supergelsin.com/api/partner/v1/webhook" \
  -H "Authorization: Basic $(printf '%s:%s' "$API_KEY" "$API_SECRET" | base64)" \
  -H "X-Integrator: Ornek POS" \
  -H "X-Operator: kasiyer_01" \
  -H "Content-Type: application/json" \
  -d '{ "url": "https://ornek-entegrator.example/hook", "events": ["order.created", "order.updated", "order.cancelled"] }'
AlanTipAçıklama
urlzorunlustringhttps:// ile başlayan, kamuya açık adres. Özel ağ adresleri, localhost ve yönlendiren adresler reddedilir (400 invalid_webhook_url).
secretstringİmza sırrı. whsec_ öneki ve ardından standart base64 (dolgulu) olmalı; çözülünce 24–64 bayt eder. Gönderilmezse mevcut geçerli sır korunur; yoksa ya da mevcut sır geçerli biçimde değilse yeni bir sır üretilir.
eventsarrayAbone olunan olaylar; verilmezse mevcut ayar, yoksa üçü de.
authHeader · authValuestring | nullAlıcının kendi kimlik başlığı (ör. Authorization); her isteğe eklenir. webhook-id, webhook-timestamp, webhook-signature ve content-type olamaz.

Üretilen sır yalnız PUT yanıtında açık döner (secret ve secretNote); sonra maskeli görünür (whsec_••••abcd). Kaybolursa yeniden PUT ile yenilenir. Gövde en çok 16 KB olabilir; aşımda 413 payload_too_large döner. GET /webhook ayrıca son teslim denemesinin izini lastDelivery içinde verir (at, status: ok, error, idle).

Sırrı olmayan ya da geçerli biçimde olmayan yapılandırmaya olay gönderilmez; işletmenin panelinde "webhook imza sırrı tanımlı değil" görünür. Her işletmenin kendi anahtarı olduğundan her vitrinin adresi kendi anahtarıyla yazılır; aynı adresi verebilirsiniz.

Tekilleştirme

Teslim en az bir kez yapılır, tam olarak bir kez değil. Aynı olayı birden fazla alabilirsiniz. Her istekteki webhook-id başlığı (gövdedeki eventId ile aynı) bütün denemelerde aynıdır; bunu saklayıp tekrarı eleyin.

webhook-id biçimi
<orderId>:order.created
<orderId>:order.cancelled
<orderId>:order.updated:<status>
<orderId>:order.updated:delivery_failed     <- restoranda online ödenmiş teslim edilemedi
sentAt ve webhook-timestamp her denemede değişir. Tekilleştirme için bunları kullanmayın; yalnızca webhook-id kullanın.

Sıra garantisi yoktur

Olaylar üretildikleri sırada ulaşmayabilir. Tekrar denenen bir olay, kendisinden sonra üretilmiş bir olaydan sonra ulaşabilir; gecikmiş bir order.updated:preparing, ready olayından sonra gelebilir.

Gövdedeki order.status alanını otorite kabul edin ve kendi kaydınızdan geriye giden bir geçişi yok sayın. Emin olamadığınızda GET /orders/{id} ile uzlaştırın. İstisna: deliveryFailed.completedSale: true ise status: cancelled iptal değil, online ödenmiş satıştır; kasada iptal edilmez.

İmza doğrulama

Tek imza şeması vardır: Standard Webhooks. Başlık webhook-signature: v1,<base64> biçimindedir; imzalanan içerik {webhook-id}.{webhook-timestamp}.{ham gövde}, algoritma HMAC-SHA256'tir. whsec_ önekinden sonraki kısım base64 çözülür ve ham bayt olarak anahtar yapılır; resmî Standard Webhooks kütüphaneleri imzayı bu biçimde doğrular. webhook-timestamp imzaya dahildir: alıcı bunu bir tolerans penceresiyle (öneri: 5 dakika) karşılaştırmalı ve imzayı sabit zamanlı karşılaştırmalıdır.

Elle doğrulama
import crypto from "node:crypto";

function verify(rawBody, headers, secret) {
  const id  = headers["webhook-id"];
  const ts  = headers["webhook-timestamp"];
  const sig = headers["webhook-signature"];        // "v1,BASE64"
  if (!id || !ts || !sig) return false;

  // 1) Tekrar oynatma penceresi: 5 dk dışını reddedin.
  if (Math.abs(Date.now() / 1000 - Number(ts)) > 300) return false;

  // 2) İmzalanan içerik: {id}.{timestamp}.{rawBody}; HAM gövdeyi kullanın.
  // Anahtar: 'whsec_' sonrası base64 çözülür (ham bayt).
  const key = Buffer.from(secret.slice("whsec_".length), "base64");
  const expected = "v1," + crypto
    .createHmac("sha256", key)
    .update(id + "." + ts + "." + rawBody)
    .digest("base64");

  // 3) Sabit zamanlı karşılaştırma.
  const a = Buffer.from(sig), b = Buffer.from(expected);
  return a.length === b.length && crypto.timingSafeEqual(a, b);
}

Tekrar deneme ve kalıcı hata

2xx dışındaki her yanıt başarısızlık sayılır. Her deneme 10 saniye bekler. Ne olacağı döndürdüğünüz koda bağlıdır:

AlanTipAçıklama
5xx · 408 · 429 · timeout · ağ hatasıgeçiciToplam 8 deneme yapılır: anlık deneme, ardından 30 sn, 1, 2, 4, 8, 16 ve 32 dk aralıklarla; toplam yaklaşık 63 dakika.
diğer 4xx (400, 401, 403, 404, 410, 422 ...)kalıcıAynı içerik aynı reddi üreteceği için yeniden denenmez.
3xx yönlendirme · güvenli olmayan adreskalıcıYönlendirme yanıtı ve güvenli olmayan adres de kalıcı hatadır.

Tükenen ya da kalıcı reddedilen olaylar, iki dikeyde de işletme panelindeki teslim sağlığı kartında listelenir. Geçici bir sorun yaşıyorsanız 5xx döndürün; kalıcı bir reddi 4xx ile bildirin. Uzun işleri senkron yapmayın: önce 2xx dönün, işlemeyi kendi kuyruğunuzda sürdürün.

Test ve güvenilirlik modeli

POST /webhook/test ucunuzu canlı sipariş beklemeden doğrular: kayıtlı adrese imzalı bir order.created gönderir. Gövde her zaman uydurma örnek sipariştir (isTest: true); gerçek sipariş ya da müşteri verisi gönderilmez. Olayın webhook-id değeri test-<uuid> biçimindedir; bunu ayırt edip mutfağa ya da toplamaya göndermeyin. Sonuç eşzamanlı döner: alıcı olayı reddetse de yanıt 200 olur ve sonuç gövdededir (ok, httpStatus, permanent, error). Adres tanımlı değilse 409 webhook_not_configured döner.

Webhook düşük gecikme sağlar, çekme uçları doğruluk kaynağıdır. Bir webhook kaçarsa GET /orders?updatedSince=… ile boşluğu kapatın. Öneri: webhook'u hız için, çekmeyi güvence için birlikte kullanın.
ÖncekiDeğerlendirmelerSonrakiMenü ve Ürün Eşleme
Bu sayfada
  • Olaylar
  • Adresi yazma
  • Tekilleştirme
  • Sıra garantisi yoktur
  • İmza doğrulama
  • Tekrar deneme ve kalıcı hata
  • Test ve güvenilirlik modeli