Yayın ve dergi yönetim sistemleri için entegrasyon belgeleri
Scholvet Entegrasyon Belgeleri

Olaylar

Webhook'lar

Bir hakem yanıt verdiğinde ya da bir davetin süresi dolduğunda Scholvet adresinizi çağırır; sürekli sorgulamanız gerekmez.

Kurulum

Konsoldaki dergi sayfasında POST isteği kabul eden bir HTTPS adresi girin. Konsol, her isteği imzalayan bir webhook gizli anahtarı gösterir. Adres yoksa olay gönderilmez; davetleri sorgulayarak izleyin. Alan adı yalnızca herkese açık IP adreslerine çözümlenmelidir; Scholvet bunu kaydederken ve her teslimatta yeniden denetler.

Olaylar

typeAnlamı
invitation.acceptedHakem kabul etti. data.reviewer kimliğini taşır; hakemi sisteminizde atayın.
invitation.declinedHakem reddetti ya da davet beklerken hesabını sildi (declineReason other).
invitation.expiredrespondBy'a kadar yanıt gelmedi.

Kendi yaptığınız değişiklikler, yani geri çekme ve tamamlama onayı, size geri gönderilmez.

İstek

BaşlıkAnlamı
X-Scholvet-EventOlay türü; gövdedeki type ile aynı.
X-Scholvet-Event-IdOlayın tekil kimliği; gövdedeki id ile aynı. Tekrar eden teslimleri ayıklamak için kullanın.
X-Scholvet-Timestampİsteğin imzalandığı Unix zamanı (saniye).
X-Scholvet-SignatureWebhook anahtarınızla, timestamp + "." + ham gövde üzerinden hesaplanan küçük harfli hex HMAC-SHA256.
Örnek
POST /scholvet/webhook HTTP/1.1
Host: journal.example.org
Content-Type: application/json; charset=utf-8
User-Agent: Scholvet/1.0
X-Scholvet-Event: invitation.accepted
X-Scholvet-Event-Id: 3f2b8d0c-71a4-4c55-9a2e-0d6f1b7c9e41
X-Scholvet-Timestamp: 1793189653
X-Scholvet-Signature: <hex hmac_sha256(secret, timestamp + "." + body)>

{
  "id": "3f2b8d0c-71a4-4c55-9a2e-0d6f1b7c9e41",
  "type": "invitation.accepted",
  "createdAt": "2026-10-29T07:02:46Z",
  "data": { "invitationId": "6d8da67a-...", "status": "accepted", "reviewer": { "...": "..." } }
}

Gövde { id, type, createdAt, data } biçimindedir; data davet nesnesidir.

İmzayı doğrulama

  1. Ham istek gövdesini JSON'a çevirmeden önce bayt olarak okuyun. Yeniden serileştirilmiş JSON eşleşmez.
  2. X-Scholvet-Timestamp saatinizden beş dakikadan fazla sapıyorsa isteği reddedin.
  3. Webhook anahtarınızla timestamp + "." + gövde üzerinden HMAC-SHA256 hesaplayın ve X-Scholvet-Signature ile sabit sürede karşılaştırın.
  4. Ancak bundan sonra gövdeyi çözümleyip işleyin.
C# (.NET 8+)
using System.Security.Cryptography;
using System.Text;

static bool IsValidScholvetSignature(string secret, string timestamp, string rawBody, string signature)
{
    if (!long.TryParse(timestamp, out var seconds) ||
        Math.Abs(DateTimeOffset.UtcNow.ToUnixTimeSeconds() - seconds) > 300) return false;

    var expected = Convert.ToHexStringLower(HMACSHA256.HashData(
        Encoding.UTF8.GetBytes(secret), Encoding.UTF8.GetBytes(timestamp + "." + rawBody)));
    return CryptographicOperations.FixedTimeEquals(
        Encoding.ASCII.GetBytes(expected), Encoding.ASCII.GetBytes(signature.Trim().ToLowerInvariant()));
}
Node.js
const crypto = require("crypto");

function isValidScholvetSignature(secret, timestamp, rawBody, signature) {
  if (Math.abs(Date.now() / 1000 - Number(timestamp)) > 300) return false;
  const expected = crypto.createHmac("sha256", secret)
    .update(`${timestamp}.${rawBody}`, "utf8")
    .digest("hex");
  const given = String(signature).trim().toLowerCase();
  return given.length === expected.length &&
    crypto.timingSafeEqual(Buffer.from(expected), Buffer.from(given));
}
PHP
function isValidScholvetSignature(string $secret, string $timestamp, string $rawBody, string $signature): bool
{
    if (abs(time() - (int)$timestamp) > 300) {
        return false;
    }
    $expected = hash_hmac('sha256', $timestamp . '.' . $rawBody, $secret);
    return hash_equals($expected, strtolower(trim($signature)));
}
Python
import hashlib, hmac, time

def is_valid_scholvet_signature(secret: str, timestamp: str, raw_body: bytes, signature: str) -> bool:
    if abs(time.time() - int(timestamp)) > 300:
        return False
    expected = hmac.new(secret.encode(), timestamp.encode() + b"." + raw_body, hashlib.sha256).hexdigest()
    return hmac.compare_digest(expected, signature.strip().lower())

Test vektörü

Doğrulayıcınız tam olarak bu değerleri kabul etmelidir. Gövde, gösterilen bayt dizisinin aynısıdır; sonunda satır sonu yoktur.

secret
whsec_test_example
X-Scholvet-Timestamp
1793189653
body
{"id":"3f2b8d0c-71a4-4c55-9a2e-0d6f1b7c9e41","type":"invitation.accepted"}
X-Scholvet-Signature
01a26b6c6c8d0377814a5cf39dc828caaedffb08bb47cc6050df73bb280d2dae

Yanıt ve yeniden denemeler

Sonraki: Hatalar ve sürümleme →