Webhooks

Async + webhook üretimde önerilen yoldur. Ne zaman sync, ne zaman polling kullanılacağı için sync/async karar rehberine bakın.

Webhook nedir, ne zaman kullanılır?

Webhook, doğrulama tamamlandığında veya başarısız olduğunda sizin belirlediğiniz HTTPS URL’ye sunucunun POST ile bildirim göndermesidir. Polling yerine veya polling ile birlikte kullanılır; özellikle asenkron iş yüklerinde önerilir.

Webhook URL tanımlama

Kontrol panelinde ilgili uygulamanın ayarlarından webhook URL alanını doldurun. İstekler JSON gövde ve aşağıdaki imza başlıkları ile gönderilir.

Olaylar ve bildirim gövdesi

event alanı:

  • verification.completed — Doğrulama başarıyla tamamlandı.
  • verification.failed — Doğrulama başarısız.

Örnek gövde (PII içermez):

{
  "event": "verification.completed",
  "request_id": "550e8400-e29b-41d4-a716-446655440000",
  "reference_id": "order-123",
  "app_id": 1,
  "timestamp": "2026-03-31T12:00:00+00:00",
  "data": {
    "status": "completed",
    "verified": true,
    "from_cache": false,
    "cached_at": null,
    "processed_at": "2026-03-31T12:00:05+00:00"
  }
}

İmza doğrulama

  • X-TCDogrula-Signature — sha256=<hmac> formatında.
  • X-TCDogrula-Timestamp — Payload içindeki timestamp ile uyumlu ISO 8601 zaman damgası.
  • Algoritma: gönderilen JSON gövdenin aynı bayt dizisi üzerinde HMAC-SHA256, uygulama secret değeri ile.

PHP

$raw = file_get_contents('php://input');
$payload = json_decode($raw, true);
// Bu değer, uygulama ayarlarından alınan gizli anahtardır (her uygulama için farklı)
$secret = getenv('APP_WEBHOOK_SECRET');
$expected = 'sha256=' . hash_hmac('sha256', $raw, $secret);
$sig = $_SERVER['HTTP_X_TCDOGRULA_SIGNATURE'] ?? '';
if (!hash_equals($expected, $sig)) {
    http_response_code(401);
    exit;
}

Node.js

const crypto = require('crypto');
const express = require('express');
const app = express();

// Bu değer, uygulama ayarlarından alınan gizli anahtardır (her uygulama için farklı)
const secret = process.env.APP_WEBHOOK_SECRET;

app.post('/webhook', express.raw({ type: 'application/json' }), (req, res) => {
  const raw = req.body;
  const expected = 'sha256=' + crypto.createHmac('sha256', secret).update(raw).digest('hex');
  const sig = req.get('x-tcdogrula-signature');
  if (expected !== sig) return res.sendStatus(401);
  const payload = JSON.parse(raw.toString());
  res.sendStatus(200);
});

Python (Flask benzeri)

import hmac
import hashlib
import os

# Bu değer, uygulama ayarlarından alınan gizli anahtardır (her uygulama için farklı)
secret = os.environ['APP_WEBHOOK_SECRET'].encode()
raw = request.get_data()
expected = b'sha256=' + hmac.new(secret, raw, hashlib.sha256).hexdigest().encode()
sig = request.headers.get('X-TCDogrula-Signature', '').encode()
if not hmac.compare_digest(expected, sig):
    abort(401)

Yeniden deneme politikası

Başarısız teslimatlar için 3 deneme yapılır: hemen, yaklaşık +30 saniye ve +5 dakika sonra (bekleme aralıkları: 0, 30, 300 saniye).