Webhooks
Webhook'lar, sunucunuzu sürekli sorgulamak (polling) yerine olayları anlık olarak
almanızı sağlar. Bir olay gerçekleştiğinde Rabisu, kayıtlı URL'nize imzalı bir
POST isteği gönderir.
1. Endpoint Kaydı — POST /webhooks
curl -X POST https://api.rabisu.com/api/v1/webhooks \
-u "rsk_live_xxx:rsks_yyy" \
-H "Content-Type: application/json" \
-d '{
"url": "https://bayi.com/modules/addons/rabisu/webhook.php",
"event_types": ["service.*", "credit.added"],
"description": "Üretim webhook"
}'
Yanıtta HMAC secret yalnızca bir kez döner — güvenli saklayın:
{
"success": true,
"data": {
"id": 12,
"url": "https://bayi.com/.../webhook.php",
"event_types": ["service.*", "credit.added"],
"secret": "whsec_...TEK_SEFER...",
"is_active": true
},
"meta": { "trace_id": "...", "timestamp": "..." }
}
URL Kuralları (SSRF Koruması)
https://zorunludur.- URL'de
user:pass@bulunamaz. - DNS çözümlenen tüm IP'ler public olmalıdır (özel/dahili IP'ler reddedilir).
2. Abonelik Pattern'leri
event_types dizisi şu biçimleri destekler:
| Pattern | Anlamı |
|---|---|
* | Tüm olaylar (catch-all) |
service.* | Namespace wildcard — service ile başlayan tüm olaylar |
service.created | Tam olay adı (exact) |
Geçerli namespace'ler: service, product, credit. Geçersiz bir pattern
gönderirseniz kayıt 422 ile reddedilir (sessizce "hiç olay almama" yerine net hata).
3. Olay Kataloğu
| Olay | Ne zaman | Payload alanları (özet) |
|---|---|---|
service.created | VPS provizyonu tamamlandı (aktif) | provision_id, service_id, order_id, product_id, status |
service.suspended | Servis askıya alındı | service_id, reason |
service.unsuspended | Askı kaldırıldı | service_id |
service.terminated | Servis iptal edildi | service_id |
product.price_changed | Ürün fiyatı değişti (bildirim) | product_id |
product.stock_changed | Ürün stok durumu değişti | product_id, stock_active |
product.disabled | Ürün satışa kapatıldı | product_id |
credit.added | Bayi kredisi eklendi (iade/manuel) | reseller_id, amount, currency, reason, new_balance |
Not:
product.*olayları yalnızca bildirim taşır. Güncel veriyiGET /products/{id}ile çekin (hibrit notification + pull).
Her payload'ın kökünde schema_version alanı bulunur (şu an 1).
4. İmza Doğrulama (KRİTİK)
Her teslimatta iki imza başlığı gönderilir:
| Başlık | İçerik | Kullanım |
|---|---|---|
X-Rabisu-Signature-V2 | t=<unix>,v1=<hex> — HMAC-SHA256(secret, "{t}.{X-Rabisu-Event-Type}.{ham gövde}") | Önerilen. Replay ve olay tipi değiştirme koruması sağlar |
X-Rabisu-Signature | sha256=<hex> — yalnızca ham gövdenin HMAC-SHA256'sı | Eski alıcılar için. Replay koruması yok, yeni entegrasyonlarda kullanmayın |
Alıcı, |şimdi - t| <= 300 saniye olduğunu ve imzalanan olay tipini
(X-Rabisu-Event-Type) doğrulamalıdır.
Doğrulama (PHP, V2):
$raw = file_get_contents('php://input');
$eventType = $_SERVER['HTTP_X_RABISU_EVENT_TYPE'] ?? '';
$header = $_SERVER['HTTP_X_RABISU_SIGNATURE_V2'] ?? '';
parse_str(str_replace(',', '&', $header), $parts); // t=..., v1=...
$t = (int) ($parts['t'] ?? 0);
$v1 = (string) ($parts['v1'] ?? '');
if (abs(time() - $t) > 300) {
http_response_code(401); // Zaman penceresi dışında (replay)
exit;
}
$expected = hash_hmac('sha256', $t . '.' . $eventType . '.' . $raw, $webhookSecret);
if (!hash_equals($expected, $v1)) {
http_response_code(401); // Geçersiz imza
exit;
}
// Güvenli: payload işlenebilir
$payload = json_decode($raw, true);
- İmzayı her zaman doğrulayın — yoksa sahte istekler kabul edersiniz.
- Karşılaştırmada
hash_equalsgibi sabit zamanlı fonksiyon kullanın. - Gövdeyi JSON'a çevirmeden önce ham hali üzerinden doğrulayın (yeniden serialize edilen JSON imzayı bozar).
5. Teslim ve Yanıt Sözleşmesi
Endpoint'iniz aşağıdaki HTTP kodlarını döndürmelidir:
| Yanıt | Anlamı | Rabisu davranışı |
|---|---|---|
2xx | Başarıyla işlendi | Teslim tamam |
4xx (401 dahil) | Kalıcı hata (imza/format) | Tekrar denenmez |
5xx | Geçici hata | Üstel backoff ile tekrar denenir |
Yeniden deneme takvimi: 1dk → 5dk → 15dk → 1s → 6s → 24s. 6 denemeden sonra olay
"dead letter" olarak işaretlenir. Art arda 5 başarısızlıkta endpoint otomatik
pasifleştirilir (circuit breaker) — düzeltince PATCH /webhooks/{id} ile yeniden
aktifleştirin.
6. Yönetim Uç Noktaları
GET /webhooks— kayıtlı endpoint'leri listele (pasif dahil)GET /webhooks/{id}— detayPATCH /webhooks/{id}— yeniden aktifleştir /event_typesveyadescriptiongüncelleDELETE /webhooks/{id}— sil (soft delete)