Entwickler

Webhooks

Sobald sich der Status einer Rechnung ändert, sendet CryBit eine signierte POST-Anfrage mit einem JSON-Body an die Webhook-URL Ihres Händlers.

Einrichtung

Legen Sie die Webhook-URL fest und aktivieren Sie die Events in den Händlereinstellungen auf der Registerkarte Integration: paid, expired, refunded, cancelled. Die URL muss eine öffentliche HTTP- oder HTTPS-Adresse auf Port 80, 443, 8080 oder 8443 sein; Weiterleitungen werden nicht verfolgt. Sie wird beim Händler festgelegt, nicht in der Rechnungsanfrage.

Header

HeaderWert
X-CryBit-EventDer Event-Name, zum Beispiel payment.paid.
X-CryBit-Signaturet=<unix time>,v1=<hex>: HMAC-SHA256 von "<t>.<raw body>" mit Ihrem Signing Secret.

Signatur überprüfen

Das Signing Secret wird in den Händlereinstellungen neben der Webhook-URL angezeigt. Berechnen Sie die Signatur über den Raw Body, vergleichen Sie sie in konstanter Zeit und lehnen Sie Anfragen ab, die älter als fünf Minuten sind.

PHP

$secret = getenv('CRYBIT_WEBHOOK_SECRET');
$body   = file_get_contents('php://input');
$header = $_SERVER['HTTP_X_CRYBIT_SIGNATURE'] ?? '';

parse_str(str_replace(',', '&', $header), $p);   // t=…&v1=…
$t = (int) ($p['t'] ?? 0);
$expected = hash_hmac('sha256', $t . '.' . $body, $secret);

if (abs(time() - $t) > 300 || !hash_equals($expected, $p['v1'] ?? '')) {
    http_response_code(400);
    exit;
}
// the request is genuine: store the event, answer 200, do the rest later
http_response_code(200);

Node.js

import crypto from 'node:crypto'

export function verify(rawBody, header, secret) {
  const parts = Object.fromEntries(header.split(',').map((kv) => kv.split('=')))
  const t = Number(parts.t)
  const expected = crypto.createHmac('sha256', secret).update(t + '.' + rawBody).digest('hex')
  const ok = parts.v1 && parts.v1.length === expected.length
    && crypto.timingSafeEqual(Buffer.from(parts.v1), Buffer.from(expected))
  return ok && Math.abs(Date.now() / 1000 - t) <= 300
}

Zustellung und Wiederholungsversuche

  • Antworten Sie zügig mit einem 2xx-Status: CryBit wartet etwa zwölf Sekunden.
  • Antworten Sie nicht, wiederholt CryBit den Versuch nach 15 Sekunden, 1 Minute, 5, 15 und 30 Minuten, danach nach 2, 6 und 24 Stunden.
  • Eine 4xx-Antwort, außer 429, stoppt die Wiederholungsversuche.
  • Dasselbe Event kann mehrfach eintreffen: Verarbeiten Sie es idempotent, indiziert nach order_id oder der Rechnungs-uuid.
  • Falls Sie einen Webhook verpasst haben, lesen Sie den Status mit GET /api/v1/payments/{uuid} aus: Er ist stets die maßgebliche Quelle.

FAQ

Kann ich sehen, was zugestellt wurde?

Ja. Die Seite mit den API-Logs im Händlerkonto listet Anfragen und Webhook-Zustellungen mit Statuscode und Body auf.

Mehr

API-Schlüssel erhalten