Entegrasyonlar
Webhooks

Webhooks

HeptaCert, belirli olaylar gerçekleştiğinde kayıtlı endpoint'inize imzalı bir HTTP POST isteği göndererek sistemlerinizi gerçek zamanlı olarak tetikler. Polling yapmak yerine olayların size gelmesini sağlar.

Nasıl Çalışır?

Endpoint kaydedin

Admin paneli → Webhooks sayfasından (veya API/CLI ile) bir URL ve dinlemek istediğiniz olayları seçin. HeptaCert size endpoint'e özel bir secret üretir.

Olay gerçekleşir

Sertifika yayımlanması gibi bir olay tetiklendiğinde HeptaCert, o olaya abone tüm aktif endpoint'lere POST isteği gönderir.

İmzayı doğrulayın

Gövdeyi (raw body) endpoint secret'ınızla HMAC-SHA256 ile imzalayıp X-HeptaCert-Signature başlığıyla karşılaştırın.

2xx dönün

10 saniye içinde 2xx yanıt verin. Aksi halde HeptaCert yeniden dener (aşağıya bakın).

Olaylar

Şu an aşağıdaki olaylar yayımlanır. Bir endpoint, bu olayların herhangi bir alt kümesine veya * ile tümüne abone olabilir.

OlayTetiklenme
cert.issuedBir sertifika yayımlandığında
cert.revokedBir sertifika iptal edildiğinde
cert.bulk_completedToplu sertifika üretimi işi tamamlandığında
cert.expiring_soonBir sertifikanın son kullanma tarihi yaklaştığında
crm.profile_updatedBir CRM kişi profili güncellendiğinde
crm.lead_score_changedBir kişinin lead skoru değiştiğinde

Tüm olaylara abone olmak için events listesinde tek bir "*" değeri gönderin. Yeni olay tipleri eklendiğinde otomatik olarak almaya başlarsınız.

Payload Formatı

Her istek şu zarf (envelope) yapısında JSON gönderir:

{
  "event": "cert.issued",
  "timestamp": "2026-09-15T10:30:00.000000+00:00",
  "data": {
    "certificate_id": 9001,
    "public_id": "abc123xyz",
    "attendee_name": "Ahmet Yılmaz",
    "attendee_email": "ahmet@example.com",
    "event_id": 42,
    "event_name": "Python Summit 2026",
    "verify_url": "https://heptacert.com/verify/abc123xyz"
  }
}
  • event — olay tipi (yukarıdaki tablodan).
  • timestamp — ISO 8601, UTC. İmza güvenliği için bu değeri X-HeptaCert-Timestamp ile karşılaştırabilirsiniz.
  • data — olaya özel yük. Olay tipine göre alanlar değişir.

İstek Başlıkları

Her teslimat şu başlıkları içerir:

BaşlıkAçıklama
Content-TypeHer zaman application/json
X-HeptaCert-EventOlay tipi (örn. cert.issued)
X-HeptaCert-Signaturesha256=<hex> formatında HMAC imzası
X-HeptaCert-TimestampPayload zaman damgası
X-HeptaCert-AttemptKaçıncı deneme olduğu (13)
⚠️

İmza formatı sha256= ön ekiyle gelir. Karşılaştırma yaparken ya beklenen değerinize aynı ön eki ekleyin ya da gelen başlıktan sha256= kısmını çıkarın. Çıplak hex ile karşılaştırma her zaman başarısız olur.

İmza Doğrulama

İmza, ham istek gövdesinin (parse edilmemiş byte'ların) endpoint secret'ınızla alınmış HMAC-SHA256 değeridir. Gövdeyi JSON'a çevirmeden önce ham haliyle doğrulayın — yeniden serialize etmek byte'ları değiştirip imzayı bozar.

import hashlib
import hmac
 
def verify_webhook(raw_body: bytes, signature_header: str, secret: str) -> bool:
    # signature_header: "sha256=abcdef..."
    expected = "sha256=" + hmac.new(
        secret.encode(), raw_body, hashlib.sha256
    ).hexdigest()
    return hmac.compare_digest(expected, signature_header or "")

FastAPI ile:

from fastapi import FastAPI, Request, HTTPException, Header
 
app = FastAPI()
 
@app.post("/webhooks/heptacert")
async def receive(request: Request, x_heptacert_signature: str = Header(None)):
    raw = await request.body()
    if not verify_webhook(raw, x_heptacert_signature, WEBHOOK_SECRET):
        raise HTTPException(status_code=401, detail="Invalid signature")
    payload = await request.json()
    if payload["event"] == "cert.issued":
        ...  # CRM'e bildir, Slack mesajı gönder, vb.
    return {"ok": True}
⚠️

Sabit-zamanlı karşılaştırma kullanın (hmac.compare_digest, crypto.timingSafeEqual, hash_equals). Normal == karşılaştırması timing attack'lara açıktır.

Yeniden Deneme Politikası

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

DenemeBekleme (öncesinde)
1— (hemen)
22 saniye
34 saniye

Toplam 3 deneme yapılır (exponential backoff). Üçü de başarısız olursa teslimat failed olarak kaydedilir. Her teslimat denemesi — başarılı veya başarısız — teslimat kayıtlarına (webhook deliveries) yazılır; admin panelinden geçmişi inceleyebilirsiniz.

Yeniden denemeler kısa aralıklıdır (saniyeler), saat/gün değil. Endpoint'iniz uzun süre kapalı kalırsa o olaylar kaçırılır. Kritik veri için ek olarak periyodik bir senkronizasyon (örn. GET /admin/events/{id}/certificates) düşünün.

İdempotanlık

Yeniden denemeler nedeniyle aynı olayı birden fazla kez alabilirsiniz. İşleyicinizi idempotent yapın: data içindeki certificate_id gibi benzersiz kimlikleri kullanarak daha önce işlenmiş olayları atlayın.

Güvenlik: SSRF Koruması

HeptaCert, webhook hedef URL'lerini doğrular ve özel/iç ağ adreslerine teslimat yapmaz. Şu hedefler reddedilir:

  • localhost, 127.0.0.1 ve loopback adresleri
  • Özel aralıklar (10.0.0.0/8, 192.168.0.0/16, 172.16.0.0/12)
  • Link-local, reserved ve multicast adresler

Bu, webhook sisteminin iç servislere istek yapmak için kötüye kullanılmasını (SSRF) önler. Endpoint'iniz herkese açık (public) bir adreste olmalıdır.

Webhook'ları Yönetme

Admin panelinin yanı sıra API ve CLI ile de yönetebilirsiniz:

# CLI
hc webhooks list
hc webhooks create https://myapp.com/hooks/heptacert \
  --events "cert.issued,cert.revoked"
hc webhooks delete 3

MCP araçlarıyla (AI asistanları): list_webhooks, create_webhook, delete_webhook.

Lokal Geliştirme

Lokal endpoint'inizi internete açmak için bir tünel kullanın (HeptaCert özel adreslere teslimat yapmadığı için localhost doğrudan çalışmaz):

ngrok http 3000
# https://xxxx.ngrok.io → localhost:3000

Üretilen public URL'yi webhook hedefi olarak kaydedin, ardından bir test olayı tetikleyin (örn. bir test sertifikası yayımlayın) ve isteğin geldiğini doğrulayın.

Sonraki Adımlar