Passer au contenu principal
Cette page est la référence des événements émis par Boble. Pour chacun, vous trouverez :
  • Quand il se déclenche — en langage clair, avec la transition technique sous-jacente.
  • Ce que ça veut dire — ce qui vient de se passer pour votre business.
  • Ce que vous pouvez en faire — des idées concrètes que des créateurs utilisent aujourd’hui.
  • Payload complet — un exemple réel, prêt à coller dans votre handler.
Tous les événements user_promotion.* partagent les mêmes objets imbriqués (user, promotion). Seuls le type au niveau racine, le status et les champs de dates changent entre les transitions. L’enveloppe commune est documentée dans Structure du payload.

user_promotion.access_granted

Un acheteur vient d’obtenir l’accès à l’une de vos promotions.

Quand il se déclenche

  • Un acheteur a complété un checkout payant en one-off.
  • Un acheteur a démarré un abonnement (Stripe customer.subscription.created).
  • Un acheteur a réclamé une promotion gratuite.
  • Vous avez accordé l’accès manuellement depuis votre dashboard.

Ce que ça veut dire

Cette personne est désormais membre actif de cette promotion. Elle peut consommer le contenu, assister aux sessions, ou tout ce que la promotion débloque. C’est le moment où votre business a gagné un nouveau client sur ce produit.

Ce que vous pouvez en faire

  • Envoyer une notif ”🎉 Nouvelle vente” à votre équipe sur Discord ou Slack avec le nom, l’email de l’acheteur et le titre de la promotion.
  • Ajouter l’acheteur à une liste Mailchimp / Brevo / ConvertKit, taggé avec la promotion achetée, pour l’embarquer dans votre séquence d’onboarding.
  • Lui donner un rôle sur votre Discord, un accès dans un workspace Notion ou toute autre ressource gatée derrière la promotion.
  • Ajouter une nouvelle ligne dans une Google Sheet pour votre log des ventes.

Payload

{
  "id": "0d6d31a3-2b9e-4d9f-9a51-3b9c3f8e6c10",
  "type": "user_promotion.access_granted",
  "api_version": "2026-01-01",
  "created": 1717497600,
  "livemode": true,
  "data": {
    "object": {
      "id": "f3e4c9e2-31a8-4d1c-9c4a-e8d2b3a17a44",
      "user_id": "2c47a8d4-5e3a-4b1c-9f8d-71a2b8c3d4e5",
      "promotion_id": "6a5c1b3e-2f8d-4a9b-9c7d-8e1f2a3b4c5d",
      "promotion_payment_id": "b9d8c7e6-5a4b-3c2d-1e0f-9a8b7c6d5e4f",
      "status": "active",
      "start_date": "2026-06-04T12:00:00.000Z",
      "end_date": null,
      "user": {
        "id": "2c47a8d4-5e3a-4b1c-9f8d-71a2b8c3d4e5",
        "email": "lea.martin@example.com",
        "firstname": "Léa",
        "lastname": "Martin",
        "username": "lea.m",
        "avatar": "https://cdn.boble.app/uploads/users/2c47.../avatar.jpg",
        "preferred_language": "fr",
        "created_at": "2026-04-12T09:31:00.000Z"
      },
      "promotion": {
        "id": "6a5c1b3e-2f8d-4a9b-9c7d-8e1f2a3b4c5d",
        "title": "Pro membership",
        "type": "subscription",
        "currency": "EUR",
        "amount": 19
      }
    }
  }
}

Champs à retenir

  • status vaut active.
  • start_date est le moment exact où l’accès a commencé.
  • end_date vaut null pour les abonnements ouverts et les accès en cours.
  • promotion.type vous dit s’il s’agit d’une réclamation free, d’un achat one_time ou d’un démarrage d’abonnement subscription.
  • promotion_payment_id vaut null pour les promotions gratuites et les attributions manuelles.

user_promotion.canceled

L’accès d’un acheteur vient d’être annulé.

Quand il se déclenche

  • L’acheteur a annulé son abonnement depuis son compte.
  • Vous avez annulé son accès manuellement depuis votre dashboard.
  • Stripe a reporté l’abonnement comme supprimé (customer.subscription.deleted).

Ce que ça veut dire

Cet acheteur n’a plus accès à la promotion. Pour un abonnement, c’est l’équivalent de “il s’est désabonné”. Pour un one-off, c’est une révocation manuelle de votre côté.

Ce que vous pouvez en faire

  • Glisser une note discrète dans votre canal Discord/Slack pour savoir que quelqu’un a churné et lui écrire si vous le souhaitez.
  • Retirer le tag de l’acheteur dans votre outil email, ou le déplacer dans un segment “ancien client” pour une séquence de win-back.
  • Révoquer le rôle que vous lui aviez donné sur votre Discord, ou retirer son accès Notion.
  • Mettre à jour votre dashboard de churn.

Payload

{
  "id": "1b6e22c8-9d11-4f0e-8b2a-7c5d9e0f1a23",
  "type": "user_promotion.canceled",
  "api_version": "2026-01-01",
  "created": 1719312800,
  "livemode": true,
  "data": {
    "object": {
      "id": "f3e4c9e2-31a8-4d1c-9c4a-e8d2b3a17a44",
      "user_id": "2c47a8d4-5e3a-4b1c-9f8d-71a2b8c3d4e5",
      "promotion_id": "6a5c1b3e-2f8d-4a9b-9c7d-8e1f2a3b4c5d",
      "promotion_payment_id": "b9d8c7e6-5a4b-3c2d-1e0f-9a8b7c6d5e4f",
      "status": "canceled",
      "start_date": "2026-06-04T12:00:00.000Z",
      "end_date": "2026-06-25T08:13:20.000Z",
      "user": {
        "id": "2c47a8d4-5e3a-4b1c-9f8d-71a2b8c3d4e5",
        "email": "lea.martin@example.com",
        "firstname": "Léa",
        "lastname": "Martin",
        "username": "lea.m",
        "avatar": "https://cdn.boble.app/uploads/users/2c47.../avatar.jpg",
        "preferred_language": "fr",
        "created_at": "2026-04-12T09:31:00.000Z"
      },
      "promotion": {
        "id": "6a5c1b3e-2f8d-4a9b-9c7d-8e1f2a3b4c5d",
        "title": "Pro membership",
        "type": "subscription",
        "currency": "EUR",
        "amount": 19
      }
    }
  }
}

Champs à retenir

  • status vaut canceled.
  • end_date est le moment exact où l’accès a pris fin.
  • Le même id que l’access_granted d’origine — c’est le même user_promotion, juste passé à un autre statut.

user_promotion.expired

Un abonnement est arrivé à terme sans être renouvelé.

Quand il se déclenche

  • Un abonnement coincé en past_due est définitivement abandonné (Stripe a arrêté d’essayer de le débiter).
  • Un accès à durée fixe a atteint sa date de fin.

Ce que ça veut dire

L’acheteur a perdu l’accès parce que son abonnement est arrivé au bout. C’est différent de canceled : l’acheteur n’a pas choisi d’annuler, l’accès s’est simplement éteint (le plus souvent après plusieurs tentatives de prélèvement infructueuses).

Ce que vous pouvez en faire

  • Déclencher une séquence email différente de celle de canceled — typiquement un rappel “votre abonnement a expiré, voici le lien pour vous réabonner” plutôt qu’un win-back.
  • Retirer ses accès dans vos outils externes, comme pour canceled.
  • Logguer l’expiration dans votre dashboard pour monitorer le succès de votre dunning.

Payload

{
  "id": "2c7f33d9-ae22-501f-9c3b-8d6e0f1b2c34",
  "type": "user_promotion.expired",
  "api_version": "2026-01-01",
  "created": 1721904000,
  "livemode": true,
  "data": {
    "object": {
      "id": "f3e4c9e2-31a8-4d1c-9c4a-e8d2b3a17a44",
      "user_id": "2c47a8d4-5e3a-4b1c-9f8d-71a2b8c3d4e5",
      "promotion_id": "6a5c1b3e-2f8d-4a9b-9c7d-8e1f2a3b4c5d",
      "promotion_payment_id": "b9d8c7e6-5a4b-3c2d-1e0f-9a8b7c6d5e4f",
      "status": "expired",
      "start_date": "2026-06-04T12:00:00.000Z",
      "end_date": "2026-07-25T12:00:00.000Z",
      "user": {
        "id": "2c47a8d4-5e3a-4b1c-9f8d-71a2b8c3d4e5",
        "email": "lea.martin@example.com",
        "firstname": "Léa",
        "lastname": "Martin",
        "username": "lea.m",
        "avatar": "https://cdn.boble.app/uploads/users/2c47.../avatar.jpg",
        "preferred_language": "fr",
        "created_at": "2026-04-12T09:31:00.000Z"
      },
      "promotion": {
        "id": "6a5c1b3e-2f8d-4a9b-9c7d-8e1f2a3b4c5d",
        "title": "Pro membership",
        "type": "subscription",
        "currency": "EUR",
        "amount": 19
      }
    }
  }
}

Champs à retenir

  • status vaut expired.
  • end_date est le moment où l’accès a effectivement pris fin (typiquement après la fenêtre de dunning).

user_promotion.suspended

Un prélèvement récurrent a échoué et l’accès de l’acheteur est mis en pause.

Quand il se déclenche

  • Une facture d’abonnement n’a pas pu être débitée. Stripe reporte l’abonnement comme past_due et Boble suspend l’accès.

Ce que ça veut dire

L’acheteur existe toujours en tant que client, mais son accès est temporairement bloqué jusqu’à ce que le paiement aboutisse. C’est votre fenêtre de dunning — la plupart du temps, les paiements repassent à la deuxième ou troisième tentative et vous recevrez un nouvel access_granted à ce moment-là. S’ils ne repassent jamais, vous recevrez finalement un expired.
Cet événement n’est émis qu’à l’entrée dans le statut past_due. Une reprise réussie ne redéclenche pas suspended — elle déclenche access_granted.

Ce que vous pouvez en faire

  • Envoyer un email à l’acheteur avec un lien pour mettre à jour son moyen de paiement. C’est une des actions à plus fort ROI qu’on puisse brancher sur un webhook.
  • Mettre en pause son accès dans vos outils externes, mais sans le révoquer définitivement — il y a de bonnes chances qu’il revienne.
  • L’ajouter à un segment “dunning” dans votre CRM pour assurer le suivi.

Payload

{
  "id": "3d8044ea-bf33-612a-ad4c-9e7f1a2c3d45",
  "type": "user_promotion.suspended",
  "api_version": "2026-01-01",
  "created": 1720008400,
  "livemode": true,
  "data": {
    "object": {
      "id": "f3e4c9e2-31a8-4d1c-9c4a-e8d2b3a17a44",
      "user_id": "2c47a8d4-5e3a-4b1c-9f8d-71a2b8c3d4e5",
      "promotion_id": "6a5c1b3e-2f8d-4a9b-9c7d-8e1f2a3b4c5d",
      "promotion_payment_id": "b9d8c7e6-5a4b-3c2d-1e0f-9a8b7c6d5e4f",
      "status": "past_due",
      "start_date": "2026-06-04T12:00:00.000Z",
      "end_date": null,
      "user": {
        "id": "2c47a8d4-5e3a-4b1c-9f8d-71a2b8c3d4e5",
        "email": "lea.martin@example.com",
        "firstname": "Léa",
        "lastname": "Martin",
        "username": "lea.m",
        "avatar": "https://cdn.boble.app/uploads/users/2c47.../avatar.jpg",
        "preferred_language": "fr",
        "created_at": "2026-04-12T09:31:00.000Z"
      },
      "promotion": {
        "id": "6a5c1b3e-2f8d-4a9b-9c7d-8e1f2a3b4c5d",
        "title": "Pro membership",
        "type": "subscription",
        "currency": "EUR",
        "amount": 19
      }
    }
  }
}

Champs à retenir

  • status vaut past_due (et non suspendedsuspended est le nom de l’événement, le statut sous-jacent est past_due).
  • end_date reste à null car l’accès est en pause, pas terminé.

webhook.test

Un événement de test que vous avez déclenché manuellement depuis votre dashboard.

Quand il se déclenche

Vous avez cliqué sur le bouton “Envoyer un événement de test” (ou appelé l’API correspondante). L’événement de test est envoyé même si votre endpoint est désactivé, pour que vous puissiez valider la connectivité avant de l’activer.

Ce que ça veut dire

Rien ne s’est passé sur un vrai acheteur. C’est un test de bon fonctionnement pour confirmer que :
  • Votre endpoint est joignable.
  • Votre handler accepte une livraison de webhook Boble.
  • Votre vérification de signature fonctionne.

Ce que vous pouvez en faire

  • L’utiliser après chaque déploiement de votre handler pour confirmer que tout marche encore, sans attendre une vraie vente.
  • L’utiliser une fois au moment de l’intégration pour valider votre code de vérification.

Payload

{
  "id": "8c00aabb-ccdd-eeff-1122-334455667788",
  "type": "webhook.test",
  "api_version": "2026-01-01",
  "created": 1717497600,
  "livemode": false,
  "data": {
    "object": {
      "message": "This is a test event",
      "endpoint_id": "8c12e3f4-1a2b-3c4d-5e6f-7a8b9c0d1e2f",
      "sent_at": "2026-06-04T12:00:00.000Z"
    }
  }
}

Champs à retenir

  • data.object est volontairement minimal — pas d’acheteur, pas de promotion, juste un marqueur indiquant qu’il s’agit d’un test.
  • livemode vaut false en dehors de la production.
  • La livraison de test apparaît quand même dans votre log d’événements, pour que vous puissiez inspecter ce que votre endpoint a répondu.