Passer au contenu principal
Les webhooks sont des messages automatisés envoyés par Hyperline lorsque quelque chose se produit sur notre système. Ils ont une charge utile spécifique pour chaque action qu’ils notifient et sont envoyés à une URL unique, un endpoint HTTPS sur votre serveur. Les webhooks sont un excellent moyen d’intégrer votre application à Hyperline car vous pouvez affiner les flux produits et construire des intégrations plus profondes selon vos besoins, avec peu de travail de développement de votre côté.

Ajouter un endpoint webhook

Pour commencer à écouter les messages webhook envoyés par Hyperline, allez dans vos paramètres webhooks dans l’application, cliquez sur « Add Endpoint », fournissez l’URL de terminaison que vous contrôlez, et sélectionnez les types d’événements que vous souhaitez écouter. Vous pouvez ajouter autant d’URLs que nécessaire si vous voulez séparer les événements que vous écoutez.
C’est tout ! Vous recevrez désormais des appels webhook lorsque l’événement se produit sur le système Hyperline.

Types d’événements

Une liste complète des types d’événements et la forme de la charge utile des événements peuvent être trouvées sur la page Webhooks du produit, dans l’onglet « Event Catalog ».
Voici un aperçu des événements pour lesquels vous pouvez être notifié :
  • customer.created, customer.updated, customer.archived, customer.recovered, customer.deleted
  • subscription.created, subscription.trial_ended, subscription.activated, subscription.reactivated, subscription.contract_started, subscription.contract_renewed, subscription.paused, subscription.phase_activated, subscription.updated, subscription.cancellation_scheduled, subscription.cancelled, subscription.voided, subscription.errored, subscription.charged, subscription.commitment_renewed, subscription.reinstated, subscription.analytics_updated
  • subscription_transition.completed
  • invoice.created, invoice.grace_period.started, invoice.late, invoice.ready, invoice.reminder_sent, invoice.settled, invoice.errored, invoice.chargeback, invoice.voided, invoice.uncollectible, invoice.deleted
  • invoice.batch.creation_succeeded, invoice.batch.creation_failed
  • credit_note.ready, credit_note.settled, credit_note.voided
  • checkout.created, checkout.completed
  • payment_method.created, payment_method.activated, payment_method.errored, payment_method.deleted, payment_method.expiring_soon, payment_method.expired
  • wallet.credited, wallet.debited, wallet.low_projected_balance
  • credit.created, credit.updated, credit.balance_refreshed, credit.low_balance, credit.balance_at_zero, credit.topup_transaction_created, credit.usage_transaction_created, credit.expiration_transaction_created
  • quote.created, quote.updated, quote.approval_requested, quote.approved, quote.sent, quote.viewed, quote.signed, quote.voided
  • bank_account.created, bank_account.deleted, bank_account.errored
  • custom_property.created, custom_property.updated, custom_property.deleted, custom_property.value_created, custom_property.value_updated
  • product.created, product.updated, product.archived, product.recovered, product.deleted
  • plan.created, plan.updated, plan.deleted
  • coupon.created, coupon.updated, coupon.deleted
  • pricebook.created, pricebook.updated, pricebook.deleted
  • approval_workflow.created, approval_workflow.updated, approval_workflow.deleted
  • approval_request.created, approval_request.step_approved, approval_request.step_rejected, approval_request.approved, approval_request.rejected, approval_request.cancelled
  • daily_analytics.ready
  • dataloader.failed
  • aggregator.updated, aggregator.threshold_crossed
  • event.price_calculated
  • agent.run.completed

Consommer les webhooks

Les appels webhook seront toujours des requêtes HTTPS POST contenant un corps JSON avec ce format :
{
  "event_type": "<group>.<event>",
  "data": {}
}
Votre endpoint doit rapidement retourner une réponse 2xx (code de statut 200-299) avant toute logique complexe qui pourrait provoquer un timeout (max 15 s). Un autre aspect important du traitement des webhooks est de vérifier la signature et l’horodatage lors de leur traitement.

Tester les événements

La façon la plus simple d’avoir confiance dans la configuration de votre endpoint est de commencer à recevoir des événements le plus rapidement possible. L’onglet « Testing » est là pour vous aider à envoyer des exemples d’événements à votre endpoint.
Après l’envoi d’un exemple d’événement, vous pouvez cliquer sur le message pour visualiser la charge utile du message, toutes les tentatives d’envoi du message, et savoir si elles ont réussi ou échoué. De plus, la section Logs est là pour vous aider à avoir une vue complète des tentatives d’appel passées avec leur date, statut et charge utile.

Distribution des événements

Rejouer des événements

Si vous souhaitez rejouer un événement (ou plusieurs), vous pouvez retrouver le message depuis l’UI, ouvrir le menu d’options à côté de l’une des tentatives, et cliquer sur « Resend ». C’est d’une grande aide si votre service a eu un temps d’indisponibilité ou si votre endpoint était mal configuré.

Calendrier de relance

Chaque message est tenté selon le calendrier suivant, où chaque période commence après l’échec de la tentative précédente :
  • Immédiatement
  • 5 secondes
  • 5 minutes
  • 30 minutes
  • 2 heures
  • 5 heures
  • 10 heures
  • 10 heures (en plus de la précédente)
Si un endpoint est supprimé ou désactivé, les tentatives de distribution vers cet endpoint seront également désactivées.

Ordonnancement des événements

Hyperline ne garantit pas la distribution des événements dans l’ordre dans lequel ils sont générés. Vous pouvez trouver plus de détails sur les raisons pour lesquelles garantir l’ordre ne fonctionne pas vraiment dans cet article. Votre endpoint ne doit pas s’attendre à la distribution des événements dans un ordre spécifique. Nous recommandons de concevoir votre système de manière à ne pas exiger d’ordre. De plus, vous pouvez utiliser l’API pour récupérer tout objet manquant (par exemple, vous pouvez récupérer les détails de l’abonnement en utilisant l’ID fourni dans la charge utile de l’événement subscription.created).

Adresses IP source statiques

Au cas où votre endpoint de réception webhook se trouve derrière un pare-feu ou un NAT, vous pourriez avoir besoin d’autoriser le trafic provenant des adresses IP statiques de nos serveurs webhook. Dans ces cas, nous vous recommandons d’autoriser les adresses IP suivantes :
52.215.16.239
54.216.8.72
63.33.109.123
2a05:d028:17:8000::/56

Bonnes pratiques

Gérer les événements en double

Les endpoints webhook peuvent occasionnellement recevoir le même événement plus d’une fois. Vous pouvez vous prémunir contre les réceptions d’événements en double en rendant votre traitement d’événements idempotent. Une façon de procéder est de journaliser les événements que vous avez traités, puis de ne pas traiter les événements déjà journalisés.

Éviter les données obsolètes

Comme les webhooks peuvent être retentés, une autre mise à jour peut survenir une fois que votre serveur est enfin capable de traiter l’événement. Par conséquent, nous vous conseillons d’interroger la dernière version de l’entité associée à la réception d’un webhook.

Vérifier les webhooks

La vérification des webhooks est une part importante de leur consommation. En raison de la manière dont fonctionnent les webhooks, des attaquants peuvent usurper l’identité de services en envoyant simplement un faux webhook à un endpoint. C’est une faille de sécurité potentielle pour votre application. Afin de l’éviter, chaque webhook et ses métadonnées sont signés avec une clé unique pour chaque endpoint. Cette signature peut ensuite être utilisée pour vérifier que le webhook provient bien d’Hyperline et de ne le traiter que si tel est le cas. Une autre faille de sécurité potentielle est ce qu’on appelle les attaques par rejeu. Une attaque par rejeu se produit lorsqu’un attaquant intercepte une charge utile valide (y compris la signature) et la retransmet à votre endpoint. Cette charge utile passera la validation de signature et sera donc traitée. Pour atténuer cette attaque, un horodatage (en-tête webhook-timestamp) est inclus dans chaque requête pour indiquer quand la tentative de webhook s’est produite. Nous recommandons de rejeter les webhooks dont l’horodatage est éloigné de plus de cinq minutes (dans le passé ou le futur) de l’heure actuelle. Vérification des signatures Chaque appel webhook inclut trois en-têtes avec des informations supplémentaires utilisées pour la vérification :
  • webhook-id : l’identifiant unique du message webhook. Cet identifiant est unique parmi tous les messages, mais sera le même lorsque le même webhook est renvoyé (par exemple, en raison d’un échec précédent).
  • webhook-timestamp : horodatage en secondes depuis l’époque.
  • webhook-signature : la liste encodée en Base64 des signatures (séparées par des espaces).
Construire le contenu signé Le contenu à signer est composé en concaténant l’ID, l’horodatage et la charge utile, séparés par le caractère point (.). En code, cela ressemblera à :
signedContent = "${webhook_id}.${webhook_timestamp}.${body}"
body est le corps brut de la requête. La signature est sensible à tout changement, donc même un petit changement dans le corps fera que la signature sera complètement différente. Cela signifie que vous ne devez pas modifier le corps avant la vérification. Déterminer la signature attendue HMAC avec SHA-256 est utilisé pour signer les webhooks. Donc pour calculer la signature attendue, vous devez HMAC le signed_content ci-dessus en utilisant la partie base64 de votre secret de signature (c’est la partie après le préfixe whsec_) comme clé. Par exemple, étant donné le secret whsec_MfKQ9r8GKYqrTwjUPD8ILPZIo2LaLaSw, vous voudrez utiliser MfKQ9r8GKYqrTwjUPD8ILPZIo2LaLaSw. Voici un exemple de calcul de signature en Node.js :
const crypto = require("crypto");

const signedContent = `${webhook_id}.${webhook_timestamp}.${body}`;
const secret = "whsec_MfKQ9r8GKYqrTwjUPD8ILPZIo2LaLaSw";

// Need to base64 decode the secret
const secretBytes = new Buffer(secret.split("_")[1], "base64");
const signature = crypto
  .createHmac("sha256", secretBytes)
  .update(signedContent)
  .digest("base64");

console.log(signature);
Cette signature générée doit correspondre à l’une de celles envoyées dans l’en-tête webhook-signature. Cet en-tête est composé d’une liste de signatures séparées par des espaces et de leurs identifiants de version correspondants. La liste de signatures est le plus souvent de longueur un. Cependant, il peut y avoir n’importe quel nombre de signatures. Par exemple :
v1,g0hM9SsE+OTPJTGt/tmIKtSyZlE3uFJELVlNIOLJ1OE= v1,bm9ldHUjKzFob2VudXRob2VodWUzMjRvdWVvdW9ldQo= v2,MzJsNDk4MzI0K2VvdSMjMTEjQEBAQDEyMzMzMzEyMwo=
Assurez-vous de retirer le préfixe de version et le délimiteur (par exemple v1,) avant de vérifier la signature.