Webhook'lar

Invozon webhook'ları, sisteminizin Invozon'da gerçekleşen olayları gerçek zamanlı öğrenmesini sağlar. REST polling yerine push tabanlı entegrasyon önerilir.

Desteklenen olaylar

Olay Tetiklenir Payload
order.created Bir pazaryerinden yeni sipariş gelir Order objesi
order.updated Sipariş statüsü değişir (paketlendi, kargolandı, teslim) Order
order.cancelled Sipariş iptal edilir (müşteri veya pazaryeri) Order
order.returned Sipariş iade akışına girer Order
product.stock_changed Bir ürünün stok seviyesi değişir {product_id, sku, old_stock, new_stock}
product.sold_out Bir ürün tükenir (stock=0) Product
invoice.created Otomatik e-fatura kesilir Invoice
invoice.failed e-Fatura entegrasyonu hata verir {invoice_id, error}
marketplace.connected Yeni pazaryeri bağlanır {marketplace, supplier_id}
marketplace.disconnected Pazaryeri bağlantısı koparılır {marketplace, reason}

Webhook URL'i kaydetme

POST /v1/webhooks
Authorization: Bearer YOUR_TOKEN
Content-Type: application/json

{
  "url": "https://yourapp.com/webhooks/invozon",
  "events": ["order.created", "order.updated", "invoice.created"],
  "active": true
}

Yanıt:

{
  "id": "whk_abc123",
  "url": "https://yourapp.com/webhooks/invozon",
  "events": ["order.created", "order.updated", "invoice.created"],
  "active": true,
  "secret": "whsec_xyz789..."
}

⚠️ secret yalnız bu yanıtta görünür. Güvenli sakla — imza doğrulamada kullanılır.

Webhook payload örneği

POST /webhooks/invozon HTTP/1.1
Host: yourapp.com
Content-Type: application/json
X-Invozon-Event: order.created
X-Invozon-Signature: t=1717228800,v1=5257a869e7ecebeda32...
X-Invozon-Webhook-Id: whk_abc123
User-Agent: Invozon-Webhook/1.0

{
  "id": "evt_xyz",
  "type": "order.created",
  "created": 1717228800,
  "data": {
    "id": "ord_123",
    "marketplace": "trendyol",
    "marketplace_order_id": "TY-2026-789456",
    "customer": { "name": "Ali Yılmaz", "phone": "5xx-xxx-xx-xx" },
    "items": [
      { "sku": "ABC123", "title": "Örnek Ürün", "quantity": 1, "price": 199.90 }
    ],
    "total": 199.90,
    "currency": "TRY",
    "shipping_address": { ... },
    "status": "created"
  }
}

İmza doğrulama (kritik)

Her webhook isteğinde X-Invozon-Signature başlığı bulunur. Bu imzayı doğrulamadan endpoint'inizde işlem yapmayın.

import hmac, hashlib, time

WEBHOOK_SECRET = "whsec_xyz789..."

def verify_signature(payload: bytes, signature_header: str) -> bool:
    # Format: t=1717228800,v1=5257a869...
    parts = dict(p.split("=") for p in signature_header.split(","))
    timestamp = parts["t"]
    expected_sig = parts["v1"]

    # 5 dakikadan eski = replay attack
    if abs(time.time() - int(timestamp)) > 300:
        return False

    signed_payload = f"{timestamp}.".encode() + payload
    actual_sig = hmac.new(
        WEBHOOK_SECRET.encode(),
        signed_payload,
        hashlib.sha256
    ).hexdigest()

    return hmac.compare_digest(actual_sig, expected_sig)

Node.js karşılığı:

const crypto = require("crypto")
const WEBHOOK_SECRET = "whsec_xyz789..."

function verifySignature(payload, signatureHeader) {
  const parts = Object.fromEntries(
    signatureHeader.split(",").map((p) => p.split("="))
  )
  const { t: timestamp, v1: expectedSig } = parts

  if (Math.abs(Date.now() / 1000 - parseInt(timestamp)) > 300) return false

  const signedPayload = `${timestamp}.${payload}`
  const actualSig = crypto
    .createHmac("sha256", WEBHOOK_SECRET)
    .update(signedPayload)
    .digest("hex")

  return crypto.timingSafeEqual(
    Buffer.from(actualSig),
    Buffer.from(expectedSig)
  )
}

Idempotency

Webhook'lar at-least-once garanti eder; aynı olay birden fazla kez gelebilir. evt_* ID'sini kaydedip işlenmiş ID'leri filtreleyin:

def handle_webhook(event):
    if event_already_processed(event["id"]):
        return {"received": True, "duplicate": True}, 200
    # process event
    mark_processed(event["id"])
    return {"received": True}, 200

Geri çekilme (retry) politikası

Endpoint'iniz 2xx dışı yanıt verirse veya 10 saniye içinde yanıt vermezse Invozon yeniden dener:

Deneme Bekleme
1. yeniden 1 dakika
2. yeniden 5 dakika
3. yeniden 30 dakika
4. yeniden 2 saat
5. yeniden 8 saat

7 başarısız denemeden sonra event "ölü" işaretlenir; panel → Webhook'lar sekmesinden manuel yeniden gönderilebilir.

Test etme

Geliştirme aşamasında ngrok veya Cloudflare Tunnel ile lokal endpoint'inizi internete açın, sonra Invozon paneli → Webhook'lar → "Test gönder" ile örnek payload tetikleyin.

Endpoint güvenliği

  • HTTPS zorunlu — HTTP URL'ler reddedilir
  • İmza doğrula — yukarıdaki örneği uygula
  • IP allowlist — Invozon webhook IP'leri: 95.216.171.140, 95.216.171.141 (yedek)
  • Idempotency uygula
  • ❌ Endpoint'i Basic Auth ile koruma (Invozon kullanıcı/şifre göndermez)