Tous les articles
StripeStripe Connectmarketplacewebhook debugging

Webhooks Stripe Connect : guide de test local

Stripe Connect est un écosystème webhook différent de Stripe régulier. La signature est la même. Tout le reste change. Si vous cherchez pourquoi votre handler Connect ignore silencieusement account.application.deauthorized, cet article est pour vous.

Connect change les événements reçus

Stripe régulier émet depuis votre compte plateforme. Connect émet depuis les comptes connectés et depuis des événements cycle-de-vie spécifiques :

  • account.updated — vérification, capacités, exigences
  • account.application.deauthorized — un compte connecté a révoqué votre accès
  • capability.updated — activation paiements/transferts
  • person.created, person.updated — comptes Custom et Express
  • payout.failed, payout.paid — sur le compte connecté, pas la plateforme

L'en-tête Stripe-Account change tout

Quand un événement survient sur un compte connecté, Stripe ajoute un en-tête Stripe-Account avec l'ID du compte (acct_xxx). Votre handler doit router sur cet en-tête.

const connectedAccountId = req.headers['stripe-account'];
const event = stripe.webhooks.constructEvent(
  rawBody,
  req.headers['stripe-signature'],
  endpointSecret,
);

await handleConnectEvent(event, connectedAccountId);

Sans cette lecture, chaque événement est traité comme s'il venait de la plateforme. Bugs typiques : "le payout s'affiche pour le mauvais marchand".

Tester Connect en local

Setup identique au test Stripe régulier, avec une étape de plus :

  1. Lancez votre app plateforme localement.
  2. Démarrez un tunnel : npx portpreview 3000.
  3. Dans le dashboard Stripe, ajoutez l'URL tunnel comme webhook et cochez Events on Connected accounts.
  4. Utilisez un compte Express ou Custom test (Stripe inclut un créateur fictif "Jenny Rosen").
  5. Déclenchez des événements : onboarding, payout, déauthorization.

La déauthorization est le cas difficile

Quand un compte connecté révoque votre app, Stripe envoie account.application.deauthorized une seule fois. Si votre handler plante, retourne 5xx ou tarde, Stripe retente — mais le compte est déjà parti. Vos appels API suivants pour ce compte retournent 401.

Testez ce flux en utilisant le test mode Connect pour révoquer le compte, capturer le webhook, et exécuter votre logique de nettoyage contre le payload capturé. Rejouez jusqu'à ce que le chemin soit fiable.

Express vs Standard vs Custom

Le type de compte change les événements person.* et capability.* reçus. Express et Custom émettent ces événements car votre plateforme aide à compléter l'onboarding. Standard les gère via les écrans Stripe — vous recevez moins d'événements.

Ce qu'on ferait nous

Pour une marketplace réelle avec analytics plateforme et reporting par marchand, deux chemins de handler distincts dès le jour 1 : un pour les événements plateforme (sans en-tête Stripe-Account), un pour les comptes connectés. Routage en haut de fonction. Ça évite 90% des bugs "c'est pour nous ou pour le marchand".

Voir le guide vérification de signature. Rejoignez la waitlist PortPreview.

Questions fréquentes

Quelle différence entre les webhooks Stripe Connect et Stripe régulier ?
Les événements Connect viennent des comptes connectés et portent un en-tête Stripe-Account identifiant le compte. La signature est identique, mais il faut activer Events on Connected accounts dans le dashboard et router sur l'en-tête.
À quoi sert l'en-tête Stripe-Account ?
Il identifie le compte connecté qui a déclenché l'événement. Le handler doit le lire car le même type d'événement peut venir de la plateforme ou d'un compte connecté, et la logique métier diffère.
Comment tester le webhook de déauthorization en local ?
Configurez un endpoint Connect avec un tunnel, connectez un compte Express ou Custom test, puis révoquez-le depuis l'interface Connect test. L'événement account.application.deauthorized arrive sur votre handler local — rejouez-le pendant que vous peaufinez la logique.