Webhook bildirimleri
Sipariş olayları sisteminize anında, imzalı bir POST isteğiyle gönderilir. Böylece siparişleri sürekli sorgulamanız gerekmez.
Kime hangi olaylar gider#
| Alıcı |
Adres nereden |
Olaylar |
Sipariş nesnesi |
| İşletmenin kendi yazılımı |
İşletme paneli › API ve entegrasyon › Webhook adresi |
order.placed, order.status.changed |
İşletme API |
| POS firması |
Firmanın Söyle Gelir'e verdiği adres |
order.placed, order.status.changed |
İşletme API |
| Kurye firması |
Firmanın Söyle Gelir'e verdiği adres |
order.assigned, order.status.changed, order.released |
Kurye API |
| Olay |
Ne zaman |
Ek alanlar |
order.placed |
Yeni sipariş geldi (onay bekliyor) |
— |
order.status.changed |
Siparişin durumu değişti |
from, to |
order.assigned |
İşletme teslimat siparişini onayladı, sipariş kurye firmasına geçti |
— |
order.released |
İşletme siparişi kurye firmasından geri aldı |
by |
İstek#
POST https://sizin-adresiniz.com/soylegelir/webhook
Content-Type: application/json
X-SoyleGelir-Event: order.status.changed
X-SoyleGelir-Signature: sha256=5d41402abc4b2a76b9719d911017c592...
X-SoyleGelir-Api-Key: sgk_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
{
"event": "order.status.changed",
"sent_at": "2026-11-14T12:05:00+00:00",
"store": { "id": 1, "name": "Pamukkale Kebap" },
"order": { "number": "SG261114GCCE", "status": "ready", "...": "..." },
"from": "preparing",
"to": "ready"
}
| Başlık / alan |
Açıklama |
X-SoyleGelir-Event |
Olay adı (gövdedeki event ile aynı) |
X-SoyleGelir-Signature |
sha256= + gövdenin HMAC-SHA256 imzası (onaltılık) |
X-SoyleGelir-Api-Key |
Yalnız POS ve kurye firmalarına: bildirimin hangi işletme bağlantısına ait olduğu. İmzayı o bağlantının gizli anahtarıyla doğrulayın |
store |
Yalnız POS ve kurye firmalarına: işletmenin kimliği ve adı |
order |
Siparişin olay anındaki hâli |
İmzayı doğrulama#
Her bildirimi işlemeden önce imzayı doğrulayın; imzası tutmayan isteği reddedin. İmza, isteğin ham gövdesi üzerinden hesaplanır: gövdeyi ayrıştırıp yeniden JSON'a çevirirseniz imza tutmaz.
- İşletmenin kendi yazılımı: sır, işletme panelindeki İmza sırrı değeridir.
- POS ve kurye firmaları: sır,
X-SoyleGelir-Api-Key başlığındaki bağlantının gizli anahtarıdır (sgs_…).
PHP#
$body = file_get_contents('php://input');
$secret = getenv('SOYLEGELIR_SECRET'); // firma: X-SoyleGelir-Api-Key'e göre o işletmenin gizli anahtarı
$expected = 'sha256=' . hash_hmac('sha256', $body, $secret);
if (! hash_equals($expected, $_SERVER['HTTP_X_SOYLEGELIR_SIGNATURE'] ?? '')) {
http_response_code(401);
exit;
}
$event = json_decode($body, true);
// Siparişi kuyruğa alın, hemen 200 dönün.
http_response_code(200);
Node.js (Express)#
const crypto = require('crypto');
app.post('/soylegelir/webhook', express.raw({ type: 'application/json' }), (req, res) => {
const secret = process.env.SOYLEGELIR_SECRET;
const expected = 'sha256=' + crypto.createHmac('sha256', secret).update(req.body).digest('hex');
const given = req.get('X-SoyleGelir-Signature') || '';
const valid = given.length === expected.length
&& crypto.timingSafeEqual(Buffer.from(given), Buffer.from(expected));
if (!valid) return res.sendStatus(401);
const event = JSON.parse(req.body.toString('utf8'));
// Siparişi kuyruğa alın, hemen 200 dönün.
res.sendStatus(200);
});
Python (Flask)#
import hashlib, hmac, os
from flask import Flask, request, abort
app = Flask(__name__)
@app.post('/soylegelir/webhook')
def soylegelir_webhook():
body = request.get_data()
secret = os.environ['SOYLEGELIR_SECRET'].encode()
expected = 'sha256=' + hmac.new(secret, body, hashlib.sha256).hexdigest()
if not hmac.compare_digest(expected, request.headers.get('X-SoyleGelir-Signature', '')):
abort(401)
event = request.get_json()
# Siparişi kuyruğa alın, hemen 200 dönün.
return '', 200
Yanıt ve yeniden deneme#
- Bildirimi aldığınızda 10 saniye içinde
2xx dönün; uzun işleri kendi kuyruğunuzda yapın.
2xx dışı yanıt, zaman aşımı ya da bağlantı hatasında bildirim yeniden gönderilir: toplam 6 deneme, aralar 10 saniye, 1 dakika, 5 dakika, 15 dakika ve 1 saat.
- Yönlendirme (
3xx) izlenmez: adresiniz doğrudan 2xx dönmelidir.
- Adres internetten erişilebilen bir HTTPS adresi olmalıdır (443 portu); iç ağ adreslerine gönderim yapılmaz.
İyi uygulamalar#
- Aynı olay birden çok kez gelebilir (yeniden deneme). Siparişi
number ile tanıyın, aynı durumu iki kez işlemeyin.
- Sıra garanti değildir. Kesin durum için
GET /orders/{number} ile siparişi doğrulayın ya da order.status ile sent_at değerine bakın.
- Bildirim kaçarsa (sunucunuz uzun süre kapalı kaldıysa)
GET /orders?since=<son başarılı zaman> ile aradaki siparişleri çekin.
- İmza sırrını ya da gizli anahtarı yenilediğinizde eski sırla imzalanmış bildirimler doğrulanamaz; yenisini hemen sisteminize girin.