Guides

Webhooks

Les webhooks envoient à votre serveur une requête POST signée pour chaque événement suivi. Ils suivent la spécification Standard Webhooks, dont la bibliothèque officielle vérifie les signatures.
  1. Dans la console, écran Webhooks, déclarez un point de réception : URL, mode et événements suivis (propriétaire et administrateurs seulement).
  2. Copiez le secret de signature (whsec_…), affiché une seule fois.
  3. Vérifiez chaque signature et répondez 2xx en moins de 10 secondes.
  4. Validez avec Envoyer un test.
Règles d’un point de réception :
  • URL HTTPS sur le port 443, sans identifiants ni fragment. L’hôte doit résoudre vers des adresses IP publiques, à la déclaration et à chaque envoi.
  • Mode fixé à la création : un point de test reçoit les événements des clés de test ; un point réel, ceux des clés réelles et du solde.
  • 20 points au plus par organisation, tous modes confondus.
  • Un événement qu’aucun point actif du bon mode ne suit n’est pas produit, ni rattrapé ensuite.
typeDéclencheur
generation.succeededGénération terminée avec succès.
generation.failedGénération échouée, remboursée.
generation.canceledGénération annulée, remboursée.
balance.lowSolde passé sous le seuil de la recharge automatique, ou sous 5,00 € HT sans elle, à chaque franchissement.
balance.recharge_failedPaiement de la recharge automatique refusé, ou 3 recharges en 24 h atteintes : recharge automatique désactivée.
balance.expiringUne partie du solde expire dans 30 jours ou moins (une fois par recharge ou crédit offert).
Les événements du solde sont toujours du mode réel (voir Facturation).
Chaque envoi porte Content-Type: application/json et User-Agent: RenderThink-Webhooks/1.0 :
json
{
"id": "evt_4Kp9WmT2xQr7LbN3vZc8Hd",
"type": "balance.low",
"created_at": 1791453648,
"livemode": true,
"data": {
"object": {
"object": "balance",
"amount": 420,
"currency": "eur",
"unit": "cents",
"low_balance_threshold": 500
}
}
}
ChampTypeDescription
idchaîneevt_…, égal à l’en-tête webhook-id.
typechaîneType de l’événement.
created_atentierHorodatage Unix en secondes.
livemodebooléenfalse en mode test.
data.objectobjetLa génération, comme GET /v1/generations/{id} la renvoie, ou le solde (balance).
  • La génération est relue à chaque envoi : ses output[].url valent 15 minutes à partir de l’envoi.
  • Le solde, en centimes HT, porte amount et, selon l’événement, low_balance_threshold, failed_recharge (amount, auto_recharge_enabled) ou expiring (amount, expires_at).
  • Ignorez les champs inconnus : de nouveaux champs peuvent s’ajouter, dans les événements comme dans les réponses de l’API.
webhook-signature vaut v1, suivi du HMAC-SHA256 en base64 de {webhook-id}.{webhook-timestamp}.{corps}, calculé avec le secret du point ; pendant un changement de secret, deux signatures séparées par une espace. La bibliothèque vérifie la signature et refuse un webhook-timestamp écarté de plus de 5 minutes. Vérifiez le corps brut, avant d’analyser le JSON. Sans la bibliothèque, comparez les signatures en temps constant (crypto.timingSafeEqual, hmac.compare_digest), jamais avec ==. RENDERTHINK_WEBHOOK_SECRET contient le secret complet, préfixe whsec_ compris.
// npm install standardwebhooks express
import express from 'express'
import { Webhook } from 'standardwebhooks'
​
const webhook = new Webhook(process.env.RENDERTHINK_WEBHOOK_SECRET)
const app = express()
​
app.post(
'/webhooks/renderthink',
express.raw({ type: 'application/json' }),
(req, res) => {
let event
try {
event = webhook.verify(req.body, req.headers)
} catch {
return res.sendStatus(400)
}
res.sendStatus(204)
handleEvent(event)
},
)
​
app.listen(3000)
Répondez 2xx en moins de 10 secondes, puis traitez l’événement. Tout autre statut, une redirection (jamais suivie), un délai dépassé ou une connexion impossible compte comme un échec.
Un envoi en échec est retenté automatiquement, à intervalles croissants, pendant 72 heures après l’événement, soit environ 16 tentatives.
TentativeDélai après l’échec précédent
230 secondes
31 minute
42 minutes
5 à 12Le double du délai précédent : 4 min, 8 min, 16 min, 32 min, 1 h 04, 2 h 08, 4 h 16, 8 h 32
13 et suivantes12 heures
  • Les délais varient de 10 % au plus. Un en-tête Retry-After dans votre réponse est respecté, jusqu’à 12 heures.
  • Passé 72 heures, l’événement n’est plus renvoyé automatiquement ; il reste dans le journal des envois de la console.
  • Un événement peut arriver plusieurs fois, avec le même webhook-id : ignorez un identifiant déjà traité, en répondant 2xx. L’ordre n’est pas garanti : fiez-vous à created_at.
  • Après 72 heures d’échecs sans aucun succès, ou dès une réponse 410 Gone, le point est désactivé, ses envois prévus annulés, et le propriétaire et les administrateurs reçoivent un e-mail. Réactivé, il ne reçoit que les nouveaux événements.
Chaque point a un journal des envois, gardé 30 jours, et se désactive ou se réactive à la main.
  • Renvoyer relance un envoi une fois, avec le même webhook-id.
  • Envoyer un test adresse un événement d’exemple d’un type suivi, aux identifiants fictifs et sans image.
  • Changer le secret affiche le nouveau secret une fois. Pendant 24 heures, chaque envoi porte les deux signatures. Un second changement dans ce délai retire aussitôt le premier secret.
Renvoi et test : point actif exigé, jamais retentés.