Webhook ile sipariş bildirimlerini kendi sisteminize alın
Webhook, mağazanızda bir şey olduğunda kendi sunucunuza imzalı bir HTTP isteği gönderir; sürekli sorgulama yapmadan siparişleri ERP, depo ya da muhasebe sisteminize taşırsınız. Bu rehber kurulumu, imza doğrulamasını, yeniden deneme takvimini ve hata ayıklamayı adım adım anlatır.
Sepetya Editör EkibiYayın tarihi: 6 dk okumaGüncellendi:

Bu yazıda
Siparişleri ERP'nize, depo yazılımınıza, muhasebe programınıza ya da bir mesajlaşma kanalına taşımanın iki yolu vardır: API'yi belirli aralıklarla sorgulamak ya da olay olduğunda sizi arayan webhook kullanmak. Webhook ikincisidir: mağazanızda bir olay olduğunda Sepetya seçtiğiniz adrese JSON gövdeli, imzalı bir POST isteği gönderir.
Bu rehberde bir webhook'u kurmayı, gelen isteğin imzasını doğrulamayı, yeniden denemelerin nasıl işlediğini ve sorun gidermeyi anlatıyoruz. Ayrıntılar platformun API belgelerinden ve kaynak kodundan doğrulanmıştır; kesin referans için geliştirici sayfasına bakın.
Webhook mu, API mi?
Webhook size neyin olduğunu söyler; ayrıntıyı API'den okursunuz. Örneğin sipariş oluşturulduğunda gönderilen olay sipariş kimliğini, sipariş adını, toplam tutarı, para birimini, kanalı ve müşteri kimliğini taşır; ürün satırları ve adresler için siparişi API'den okursunuz (GET /api/v1/stores/{storeId}/orders/{id}, Authorization: Bearer ile API anahtarı). Paketinizde webhook özelliğinin ve API erişiminin açık olması gerekir.
| İhtiyaç | Doğru araç |
|---|---|
| Yeni siparişi anında kendi sisteminize aktarmak | Webhook |
| Geçmiş siparişleri toplu çekmek | API |
| Olaydan sonra siparişin tam ayrıntısını okumak | Webhook ile haberdar olun, ayrıntıyı API'den alın |
Siparişlerin panel tarafındaki akışını (durumlar, gönderim, iade) sipariş ve iade yönetimi sayfasında anlattık; iade süreçlerinin müşteriye bakan tarafı için cayma hakkı ve iade politikası rehberine bakabilirsiniz.
Webhook'u kurun
Ayarlar › Webhook'lar sayfasında "Webhook ekle"ye basın ve şu adımları izleyin:
- Uç nokta adresi: HTTPS olmalı ve herkese açık bir sunucuyu göstermelidir. Sepetya özel ağ, loopback ve link-local adreslere istek göndermez (SSRF koruması) ve yönlendirmeleri takip etmez. Yerelde denemek için bir tünel hizmetiyle genel bir HTTPS adresi kullanın.
- Olaylar: siparişler, ödemeler, iadeler (para), kargo, iade talepleri, sepet, ürünler, stok, kategoriler, müşteriler, bülten, alan adları, mağaza, faturalar ve kampanyalar gruplarından seçin. Sipariş entegrasyonu için genellikle "Sipariş oluşturuldu", "Sipariş ödendi", "Sipariş gönderildi" ve "Sipariş iade edildi" yeterlidir.
- Satış kanalları (isteğe bağlı): seçerseniz yalnız o kanallardan gelen sipariş olayları gönderilir; hiçbiri seçilmezse tüm kanallar.
- İmzalama anahtarı:
whsec_ile başlar ve güvenlik nedeniyle yalnızca oluşturulduğunda ve yenilendiğinde bir kez gösterilir. Alıcı sunucunuzun ortam değişkenlerine kaydedin; kaybederseniz anahtarı yenilemeniz gerekir. - Test bildirimi: "Test bildirimi gönder" ile bir
webhook.testolayı yollayın; sonucu teslimat ayrıntısında görürsünüz. Test bildirimleri yeniden denenmez, ardışık hata sayacına eklenmez ve webhook kapalıyken de gönderilebilir.
Gelen istek nasıl görünür?
Her istek bir POST'tur ve Standard Webhooks başlıklarını taşır:
| Başlık | Anlamı |
|---|---|
webhook-id | Mesaj kimliği; msg_ ile başlar ve yeniden denemelerde aynı kalır |
webhook-timestamp | Gönderim zamanı, Unix saniyesi |
webhook-signature | v1, ile başlayan base64 imza; anahtar yenilenirken boşlukla ayrılmış birden çok imza |
content-type | application/json |
user-agent | Platformun kısa adı ve -Webhooks/1.0 ekinden oluşur |
Gövde, olay zarfıdır; id olay kimliğini, data olaya özgü alanları taşır. Aşağıdaki sipariş örneğindeki değerler örnektir:
{
"id": "…olay kimliği…",
"type": "order.created",
"timestamp": "2026-10-05T09:30:00.000Z",
"storeId": "…mağaza kimliği…",
"apiVersion": "v1",
"data": {
"orderId": "…sipariş kimliği…",
"name": "#1001",
"totalMinor": 129900,
"currencyCode": "TRY",
"channel": "storefront",
"customerId": "…müşteri kimliği…"
}
}
Tutarlar küçük para biriminde tamsayıdır (totalMinor: 129900, 1.299,00 TL demektir).
İmzayı doğrulayın
Standard Webhooks şeması şöyle çalışır; her adım atlanmamalıdır:
- Ham gövdeyi okuyun: JSON'a çevirmeden önce, gelen baytları olduğu gibi kullanın. Gövdedeki tek bir boşluk farkı bile imzayı bozar.
- Zamanı denetleyin:
webhook-timestampşimdiki zamandan 5 dakikadan fazla uzaksa isteği reddedin; bu, tekrar saldırısına karşı korumadır. - Anahtarı çözün:
whsec_ön ekinden sonraki kısım base64'tür; çözülmüş baytlar HMAC anahtarıdır. - İmzayı hesaplayın:
webhook-id, nokta,webhook-timestamp, nokta ve ham gövde birleştirilir; HMAC-SHA256 base64 olarak yazılır. - Karşılaştırın: başlıktaki
v1,imzalarından biriyle sabit zamanlı karşılaştırma yapın.
Node.js ve Express ile bir örnek (sırrı koda yazmayın, ortam değişkeninden okuyun):
import express from 'express';
import { createHmac, timingSafeEqual } from 'node:crypto';
const SECRET = process.env.WEBHOOK_SECRET; // whsec_…
const TOLERANCE_SECONDS = 5 * 60;
function verify(rawBody, headers) {
const id = headers['webhook-id'];
const timestamp = headers['webhook-timestamp'];
const signatures = headers['webhook-signature'];
if (!id || !timestamp || !signatures) return false;
if (Math.abs(Date.now() / 1000 - Number(timestamp)) > TOLERANCE_SECONDS) return false;
const key = Buffer.from(SECRET.replace(/^whsec_/, ''), 'base64');
const expected = createHmac('sha256', key)
.update(id + '.' + timestamp + '.' + rawBody)
.digest();
return signatures.split(' ').some(function (part) {
const [version, signature] = part.split(',');
if (version !== 'v1' || !signature) return false;
const given = Buffer.from(signature, 'base64');
return given.length === expected.length && timingSafeEqual(given, expected);
});
}
const app = express();
app.post('/webhooks', express.raw({ type: 'application/json' }), function (req, res) {
const rawBody = req.body.toString('utf8');
if (!verify(rawBody, req.headers)) return res.status(401).end();
const event = JSON.parse(rawBody);
// webhook-id daha önce işlendiyse atlayın; işi kuyruğa bırakıp hemen yanıt verin
res.status(204).end();
});
app.listen(3000);
Anahtarı yenilerken 0 ile 168 saat arasında bir geçiş süresi seçersiniz: bu sürede her istek hem eski hem yeni anahtarla imzalanır ve başlıkta iki v1, imzası bulunur. Alıcınız hangisini biliyorsa onunla doğrular; böylece anahtar değişimi kesintisiz olur.
Yanıt verin: başarı, zaman aşımı ve yeniden denemeler
2xx yanıt alan teslimat başarılıdır. Sepetya yanıt için 10 saniye bekler; Standard Webhooks spesifikasyonu 15 ile 30 saniye önerir, yani uç noktanızın daha hızlı davranması gerekir: olayı kuyruğa alıp hemen 2xx dönün, ağır işi sonra yapın. Yönlendirme (3xx) yanıtı başarısız sayılır ve takip edilmez; yanıt gövdesi en fazla 64 KB okunur ve teslimat günlüğüne kısa bir özeti yazılır.
Başarısız teslimatlar artan aralıklarla yeniden denenir; toplam 8 deneme yapılır ve ilk denemeden son denemeye yaklaşık 24 saat geçer:
| Başarısız deneme | Sonraki deneme |
|---|---|
| 1 | 5 saniye sonra |
| 2 | 5 dakika sonra |
| 3 | 30 dakika sonra |
| 4 | 2 saat sonra |
| 5 | 5 saat sonra |
| 6 | 8 saat sonra |
| 7 | 8 saat sonra |
| 8 | Vazgeçilir; teslimat "Başarısız" olur |
Art arda 50 başarısız denemeden sonra webhook otomatik olarak devre dışı kalır. Bekleyen olay teslimatları "Başarısız" işaretlenir, mağaza sahibine panelde bildirim ve e-posta gider. Sunucunuzu düzeltince "Etkinleştir" ile açarsınız; hata sayacı sıfırlanır. Her başarılı teslimat da sayacı sıfırlar.
- Tekilleştirin:
webhook-idyeniden denemelerde aynı kalır. İşlediğiniz kimlikleri saklayın ve aynısı gelirse 2xx dönüp atlayın. Otomatik denemeler yaklaşık 24 saate yayıldığı ve elle yeniden denemeler daha geç gelebildiği için kimlikleri en az bir gün, mümkünse birkaç gün tutun. - Sıraya güvenmeyin: yeniden denemeler yüzünden olaylar sıra dışı gelebilir. Durumu geliş sırasına değil, olayın
timestampalanına ve API'den okuduğunuz güncel kayda dayandırın. - Yanıt kodunu doğru seçin: geçersiz imzada 401 dönün; geçici bir hatada 5xx, işlenmiş bir olay için 2xx.
Teslimat günlüğüyle hata ayıklama
Her webhook'un Teslimat günlüğü olay türünü, teslimatın türünü (olay, test ya da yeniden oynatma), deneme sayısını, yanıt kodunu, süreyi ve zamanı listeler. Teslimat ayrıntısında gönderilen gövde, yanıt özeti, sonraki deneme zamanı ve son 20 denemenin günlüğü bulunur; webhook sayfası son 24 saatin başarılı, başarısız ve bekleyen sayısını gösterir.
- Yeniden dene: başarısız teslimatı aynı mesaj kimliğiyle hemen yeniden gönderir; başarılı teslimatta kullanılamaz.
- Yeniden oynat: aynı gövdeyi yeni bir mesaj kimliğiyle yeni bir teslimat olarak gönderir; alıcınız onu yeni bir olay gibi işler. Yeniden deneme ve oynatma için mağaza başına saatte 60 işlem sınırı vardır.
| Günlükte gördüğünüz | Olası neden ve çözüm |
|---|---|
| Yönlendirme yanıtı (301) takip edilmez | Adres başka bir adrese yönleniyor; son adresi doğrudan girin |
| HTTP 401 | İmza doğrulaması başarısız: ham gövdeyi, anahtarı ve sunucu saatini kontrol edin; bir proxy gövdeyi değiştiriyor olabilir |
| Zaman aşımı | Yanıt 10 saniyeyi aştı; olayı kuyruğa alıp hemen 2xx dönün |
| Bağlantı ya da sertifika hatası | Adres herkese açık ve geçerli bir HTTPS sertifikasına sahip olmalı; özel ağ adresleri engellenir |
Alıcı tarafı kontrol listesi
- Uç nokta herkese açık, geçerli sertifikalı bir HTTPS adresi.
- İmzalama anahtarı ortam değişkeninde; koda ve günlüklere yazılmıyor.
- İmza, ham gövde üzerinden ve sabit zamanlı karşılaştırmayla doğrulanıyor.
- Zaman damgası 5 dakikalık toleransla denetleniyor.
- Olay kuyruğa alınıp 10 saniyeden kısa sürede 2xx dönülüyor.
- webhook-id ile tekilleştirme yapılıyor; kimlikler en az bir gün saklanıyor.
- Olayların sıra dışı gelebileceği varsayılıp durum API'den okunuyor.
- Yalnızca gereken olaylara ve satış kanallarına abone olundu.
- Test bildirimi ve bir gerçek sipariş Teslimat günlüğünde başarılı görünüyor.
- Anahtar yenileme prosedürü (geçiş süresi dahil) belirlendi.
Siparişleri kendi sisteminize aktaran entegrasyonunuzu deneme süresi boyunca denemek için ücretsiz başlayın. Reklam ve ürün feed'i tarafındaki otomasyon için Google Merchant Center ürün feed'i rehberine de göz atın.
- webhook
- api
- entegrasyon
- standard-webhooks
- siparis


