Sipariş Bildirimi (Webhook)

Sipariş bildirimi açıksa, ödemesi alınan her sipariş mağaza tarafından sizin belirlediğiniz adrese POST edilir. Böylece siparişleri listeyi sürekli sorgulamadan, ödeme alındığı anda alabilirsiniz.

Bildirimi açtırma

Bildirim adresi ve imza anahtarı TEY Bilişim tarafından tanımlanır. Mağaza adını, bildirimin gönderileceği HTTPS adresini ve imza için kullanılacak gizli anahtarı bilgi@teybilisim.com adresine iletin. Gizli anahtarı e-postayla düz metin olarak göndermek yerine telefonla ya da ayrı bir kanaldan paylaşmanızı öneririz.

Ne zaman gönderilir?

  • Siparişin ödeme durumu ödendi (Paid) olduğunda gönderilir: kartla ödemede ödeme onaylanınca, havalede mağaza ödemeyi onaylayınca, kapıda ödemede tahsilat teslimde kaydedilince.
  • Her sipariş için bir kez gönderilir. Olay adı order.paid'dir.
  • Bildirimler kuyruktan dakikada bir gönderilir. Ödeme ile bildirim arasında bir dakikaya kadar gecikme olabilir.

İstek

POST /sizin/adresiniz HTTP/1.1
Content-Type: application/json; charset=utf-8
X-HSM-Event: order.paid
X-HSM-Tenant: demomarket
X-HSM-Signature: 3q2+7wQh0sY1xV8m5b9Kc1nO4pR6tU8wY0zA2cE4gI0=
{
  "event": "order.paid",
  "tenantSlug": "demomarket",
  "orderId": "d2a7c9e4-5f13-4b8a-9c60-3e1f7a2b8d45",
  "orderNumber": "HM20261020123456789",
  "paidAt": "2026-10-20T09:15:03.902Z",
  "currency": "TRY",
  "grandTotal": 499.70,
  "subTotal": 499.80,
  "taxTotal": 83.28,
  "installmentFee": 0,
  "installmentCount": 1,
  "paymentFee": 0,
  "paymentMethod": "paytr",
  "shippingMethod": null,
  "deliverySlotStart": null,
  "deliverySlotEnd": null,
  "isStorePickup": false,
  "pickupAddress": null,
  "paymentProviderRef": "HM20261020123456789",
  "customerNote": "Lütfen zile basmayın.",
  "internalNote": null,
  "customer": {
    "email": "ayse.yilmaz@example.com",
    "firstName": "Ayşe",
    "lastName": "Yılmaz",
    "phone": "05321234567"
  },
  "billingAddressJson": "{\"FirstName\": \"Ayşe\", ...}",
  "items": [
    {
      "productId": "8f1c2a4e-3b5d-4c6e-9f70-1a2b3c4d5e6f",
      "sku": "KUPA-350",
      "name": "Seramik Kupa 350 ml",
      "quantity": 2,
      "unitPrice": 249.90,
      "lineTotal": 499.80
    }
  ]
}

Bildirimde siparişin özeti bulunur. Teslimat adresi, kalem KDV oranları ve indirim gibi ayrıntılar için orderId ile tek sipariş ucunu çağırın.

İmzayı doğrulama

X-HSM-Signature başlığı, isteğin ham gövdesinin gizli anahtarla alınmış HMAC-SHA256 değerinin Base64 karşılığıdır. İsteğin gerçekten mağazadan geldiğinden emin olmak için imzayı doğrulayın. Gövdeyi JSON olarak çözüp yeniden yazmadan, geldiği gibi kullanın. Gizli anahtar tanımlanmamışsa bu başlık gönderilmez. Bildirimi mutlaka bir gizli anahtarla açtırın.

Gövdedeki Türkçe karakterler JSON kaçışıyla gelebilir ("Ayşe"). Bütün JSON kütüphaneleri bunu Ayşe olarak okur.

PHP:

$govde = file_get_contents('php://input');
$beklenen = base64_encode(hash_hmac('sha256', $govde, $gizliAnahtar, true));
if (!hash_equals($beklenen, $_SERVER['HTTP_X_HSM_SIGNATURE'] ?? '')) {
    http_response_code(401);
    exit;
}

C#:

using var hmac = new HMACSHA256(Encoding.UTF8.GetBytes(gizliAnahtar));
var beklenen = Convert.ToBase64String(hmac.ComputeHash(Encoding.UTF8.GetBytes(govde)));
var gelen = Request.Headers["X-HSM-Signature"].ToString();
if (!CryptographicOperations.FixedTimeEquals(Encoding.UTF8.GetBytes(beklenen), Encoding.UTF8.GetBytes(gelen)))
    return Unauthorized();

Node.js:

const beklenen = crypto.createHmac('sha256', gizliAnahtar).update(hamGovde).digest('base64');
const gelen = req.get('X-HSM-Signature') || '';
const esit = gelen.length === beklenen.length &&
  crypto.timingSafeEqual(Buffer.from(gelen), Buffer.from(beklenen));
if (!esit) return res.sendStatus(401);

Yanıt ve yeniden deneme

  • Bildirimi aldığınızda 2xx (örneğin 200) dönün. 30 saniye içinde yanıt vermeyin ya da 2xx dışında bir kod dönerseniz bildirim başarısız sayılır.
  • Başarısız bildirim artan aralıklarla yeniden gönderilir: 1, 5, 15, 60 ve 240 dakika sonra. Toplam 6 deneme yapılır.
  • Denemeleri tükenen bildirimi mağaza yönetici paneldeki sipariş detayından yeniden kuyruğa alabilir.
  • Aynı bildirim birden fazla gelebilir (örneğin yanıtınız zaman aşımına uğradıysa). Siparişi orderId ile eşleştirin, ikinci kez işlemeyin.

Ağır işleri (fatura kesme, stok düşme) bildirimin içinde yapmayın. Bildirimi kaydedip hemen 200 dönün, işi arka planda yapın.