Développeurs

Webhooks

Lorsqu'une facture change d'état, CryBit envoie une requête POST signée avec un corps JSON à l'URL de webhook de votre marchand.

Configuration

Définissez l'URL de webhook et cochez les événements dans les paramètres du marchand, sur l'onglet intégration : paid, expired, refunded, cancelled. L'URL doit être une adresse HTTP ou HTTPS publique sur le port 80, 443, 8080 ou 8443 ; les redirections ne sont pas suivies. Elle se configure sur le marchand, pas dans la requête de facture.

En-têtes

En-têteValeur
X-CryBit-EventLe nom de l'événement, par exemple payment.paid.
X-CryBit-Signaturet=<unix time>,v1=<hex> : HMAC-SHA256 de "<t>.<raw body>" avec votre clé de signature.

Vérifier la signature

La clé de signature est affichée dans les paramètres du marchand, à côté de l'URL de webhook. Calculez la signature sur le corps brut, comparez-la en temps constant et rejetez les requêtes de plus de cinq minutes.

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
}

Livraison et nouvelles tentatives

  • Répondez rapidement avec un statut 2xx : CryBit attend environ douze secondes.
  • Si vous ne répondez pas, CryBit relance après 15 secondes, 1 minute, 5, 15 et 30 minutes, puis 2, 6 et 24 heures.
  • Une réponse 4xx, sauf 429, arrête les nouvelles tentatives.
  • Le même événement peut arriver plusieurs fois : traitez-le de façon idempotente, en vous basant sur order_id ou l'uuid de la facture.
  • Si vous avez manqué un webhook, consultez le statut avec GET /api/v1/payments/{uuid} : c'est toujours la source de vérité.

FAQ

Puis-je voir ce qui a été livré ?

Oui. La page des journaux API du compte marchand liste les requêtes et les livraisons de webhooks avec le code de statut et le corps.

Plus

Obtenir une clé API