Ürün Event'leri — product.created · updated · deleted ✓ Canlı

Ürün kataloğu değiştiğinde eklentinin webhookUrl'ine async imzalı POST edilir. Menü/stok senkronu yapan eklentilerin delta kaynağıdır: ilk yükleme products/list, sonrası bu event'ler.

← Event Kataloğu

Ne zaman tetiklenir?

EventTetikdata
product.createdYeni ürün eklendiğindeYeni ürün
product.updatedÜrün düzenlendiğindeÜrünün güncel hâli
product.deletedÜrün silindiğindeSilinen ürünün son hâli

Üçü de async webhook (fire-and-forget; yanıtın işlemi etkilemez). Şekil aynı, yalnız type farklı.

Abonelik

  • Manifest: events: ["product.created", "product.updated", "product.deleted"] + events:subscribe.
  • products:read zorunlu — yoksa data boş ({}) gelir.

HTTP, imza & teslimat

POST {webhookUrl}
Content-Type: application/json
X-Restomenum-Signature: t=<unixSec>,v1=<HMAC_SHA256(webhookSecret, "<t>.<rawBody>")>
X-Restomenum-Event: product.created | product.updated | product.deleted
X-Restomenum-Delivery: <deliveryId>
  • İmzayı ham gövde üzerinden doğrula ("<t>.<rawBody>"), ±5 dk replay — bkz. imza şeması.
  • Header'lar: X-Restomenum-Event: <type>, X-Restomenum-Delivery: <id>.
  • Idempotency: envelope id tekildir (at-least-once → dedup, 200 dön).
  • Ack: 2xx → işlendi. 5xx/timeout → retry → dead-letter.

Tam örnek payload

product.created (canlı)
{
  "id": "evt_<uuid>",
  "type": "product.created",
  "version": "1",
  "tenantId": "<tenantId>",
  "occurredAt": 1781000000000,
  "data": {
    "id": "3b5d-f6d0",
    "title": "Menemen",
    "category": "a0-62",
    "price": 19,
    "tax": 0,
    "active": true,
    "image": "https://d37x2wx7jj7xm7.cloudfront.net/server/SM9M.../products/.../original.jpeg",
    "barcode": "",
    "barcodeType": "Product",
    "stock": 59,
    "languages": { "US": { "title": "Menemen", "description": "" } },
    "options": [
      {
        "id": 1780871104983, "title": "", "min": 0, "max": 99, "multiple": true,
        "choices": [
          { "id": 1661781517624, "title": "Sade", "price": 0 },
          { "id": 1661781517374, "title": "Peynir", "price": 1 },
          { "id": 1661781517278, "title": "Kavurma", "price": 5 },
          { "id": 1661781517482, "title": "Sucuk", "price": 2 }
        ]
      }
    ]
  }
}

product.updated aynı şekilde güncel ürünü; product.deleted silinen ürünün son hâlini taşır — yalnız type farklı.

data alanları

AlanTipZorunluAçıklama
idstringÜrün id'si (products/get?id= ile aynı).
titlestringÜrün adı.
categorystringKategori id'si (categories/list'teki id).
pricenumberBirim fiyat (₺).
taxnumberKDV/vergi oranı (%).
activebooleanSatışta mı.
imagestring | nullGörsel CDN URL'i; yoksa null.
barcode / barcodeTypestringBarkod / tipi.
stocknumberStok adedi (negatif olabilir).
languagesobjectDil çevirileri (yoksa dönmeyebilir).
options[]array{ id, title, min, max, multiple, choices[] }; choices[]: { id, title, price }.

Sızıntı önlemi

Ham ürün objesindeki cost (maliyet) ve recete (reçete/BOM) ASLA dönmez — ticari sır.
  • Görsel: Restomenum S3 → CloudFront CDN'e çevrilir; başka host (cloudinary) olduğu gibi kalır.
  • data yalnız products:read onaylıysa dolu; yoksa {}.
Menü senkronu: ilk yüklemede products/list (tam katalog) + categories/list; sonrasında delta için bu event'ler + category.*. Tek ürün detayı: products/get.