PUBLICITÉ

Faites connaître votre entreprise sur les réseaux sociaux

Je vous accompagne pour développer votre notoriété et vous apporter plus de leads

Créer une plateforme multi-vendeurs robuste avec Stripe Connect Express

Introduction

La création d’une plateforme multi-vendeurs est un défi complexe, en particulier lorsqu’il s’agit de gérer les paiements et les comptes des vendeurs. Stripe Connect Express simplifie grandement ce processus, mais une intégration réussie nécessite une conception minutieuse pour faire face aux changements d’état et aux potentiels problèmes.

Comment les paiements circulent-ils dans une plateforme multi-vendeurs ?

Avant d’aborder l’intégration ou l’état des vendeurs, il est crucial de définir le modèle de paiement. Stripe Connect propose différentes options (Standard, Express et Custom), chacune offrant différents niveaux de contrôle et de responsabilité. Le choix du modèle dépend de la structure de votre plateforme. Dans notre cas, nous avons opté pour un modèle où :

  • Les vendeurs créent leurs propres comptes Stripe Connect Express via notre plateforme.
  • Les paiements sont effectués directement sur le compte du vendeur.
  • La plateforme prélève une commission d’application en pourcentage.

Ce modèle convient aux plateformes où les vendeurs sont des entreprises indépendantes et où Stripe gère la conformité et les paiements.

Un flux de paiement concret

Dans cette configuration, un paiement typique se déroule comme suit :

  1. Un client initie un achat sur la plateforme.
  2. La plateforme crée une session Stripe Checkout.
  3. Le paiement est effectué sur la page de paiement hébergée par Stripe.
  4. Le paiement est versé directement sur le compte du vendeur.
  5. La plateforme prélève une commission d’application.

Le code suivant illustre la création d’une session Checkout avec une commission d’application :

const session = await stripe.checkout.sessions.create({
mode: "payment",
payment_method_types: ["card"],
line_items: [
{
price_data: {
currency: "gbp",
product_data: {
name: "Gift Card",
},
unit_amount: price * 100,
},
quantity: 1,
},
],
payment_intent_data: {
application_fee_amount: Math.round(price * 0.15 * 100), // 15% application fee
transfer_data: {
destination: stripeAccountId, // ID of Stripe connected account
},
},
success_url: `${hostUrl}/${saleId}/success`,
cancel_url: `${hostUrl}/${saleId}/failure`,
});

Cette session Checkout renvoie une URL vers laquelle rediriger l’acheteur. Il est important de comprendre que le paiement dépend de l’état du compte du vendeur et de sa capacité à accepter les paiements.

Pourquoi cette distinction est-elle importante ?

Lorsque les vendeurs sont les marchands officiels et que les paiements sont créés sur leurs comptes :

  • La plateforme ne contrôle pas totalement la réussite d’un paiement.
  • Les changements de conformité et de capacité du vendeur affectent directement le processus de paiement.
  • Certains échecs surviennent après la création d’une session.

Si votre plateforme repose sur des hypothèses statiques, telles que « le vendeur est intégré » ou « les paiements sont activés », ces hypothèses finiront par devenir fausses. Il est donc essentiel de considérer l’état du vendeur comme une préoccupation primordiale et de concevoir un système capable de réagir aux changements.

Ce que représente un compte vendeur

Du point de vue de votre plateforme, un compte Stripe créé ne garantit pas que le vendeur peut accepter les paiements. Il s’agit simplement d’un conteneur susceptible de devenir capable d’accepter les paiements, en fonction de son état.

Création de compte vs. utilisabilité du compte

La création d’un compte Stripe est une opération synchrone :

const account = await stripe.accounts.create({
type: "express",
country: "GB",
default_currency: "GBP",
email,
capabilities: {
card_payments: {
requested: true
},
},
});

À ce stade, le compte existe, il possède un ID et peut être lié à un utilisateur dans votre base de données. Cependant, cela ne garantit pas que le compte puisse :

  • Accepter les paiements par carte.
  • Rester activé au fil du temps.

Ces aspects dépendent d’un processus d’intégration et de vérification qui se déroule en dehors de votre cycle requête/réponse.

L’intégration n’est pas une étape unique

Lorsque vous générez un lien d’intégration :

const accountLink = await stripe.accountLinks.create({
account: account.id,
refresh_url: `${hostUrl}/${sellerId}?success=false`,
return_url: `${hostUrl}/${sellerId}?success=true`,
type: "account_onboarding",
});

vous ne « terminez » pas l’intégration, vous donnez au vendeur la possibilité de soumettre des informations. Stripe peut les accepter, les rejeter ou en demander d’autres ultérieurement. Par ailleurs, même une fois l’intégration terminée et que le vendeur est prêt à accepter les paiements, cette situation peut évoluer.

Pourquoi les capacités du vendeur changent avec le temps

Une fois qu’un compte vendeur existe, que l’intégration est terminée et que les paiements fonctionnent, il est tentant de penser que le plus dur est fait. En réalité, c’est là que la plupart des plateformes multi-vendeurs rencontrent des problèmes, car la capacité du vendeur à accepter les paiements n’est pas stable. Cette capacité dépend de facteurs tels que :

  • L’exhaustivité et la validité des informations de vérification.
  • Les exigences de conformité spécifiques au pays.
  • Le type d’entreprise et son activité.
  • Les changements dans les obligations réglementaires de Stripe.

En fonction de ces facteurs, les capacités peuvent être révoquées ou accordées. Par conséquent, si votre système suppose que l’intégration est terminée une fois pour toutes, que la capacité du vendeur est un booléen et que les vérifications de capacité sont définitives, les changements de capacité entraîneront des échecs, tels que :

  • Des sessions Checkout qui échouent après avoir été créées.
  • Des paiements qui n’atteignent jamais le vendeur.
  • Des vendeurs signalant des problèmes que votre plateforme n’avait pas anticipés.

Une approche plus fiable consiste à traiter la capacité du vendeur comme un état dynamique, et non comme une configuration. Cela signifie :

  • Supposer que les capacités peuvent changer à tout moment.
  • Concevoir des flux de paiement qui tolèrent les échecs tardifs.
  • Éviter une logique qui repose sur des vérifications ponctuelles.

Les webhooks Stripe à la rescousse

Les webhooks sont la manière dont Stripe communique ces changements et vous fournit les dernières informations sur l’ »état » d’un vendeur. Cet état est dérivé d’événements tels que :

  • account.updated
  • account.application.deauthorized

Voici un exemple de haut niveau de la façon dont les webhooks Stripe peuvent être mis en œuvre :

  1. Créez un point de terminaison API pour recevoir les événements webhook.
import express from "express";
import Stripe from "stripe";
const router = express.Router();
const stripe = new Stripe(process.env.STRIPE_SECRET_KEY);
router.post(
"/webhooks/stripe",
express.raw({ type: "application/json" }),
(req, res) => {
const sig = req.headers["stripe-signature"];
let event;
try {
event = stripe.webhooks.constructEvent(
req.body,
sig,
process.env.STRIPE_WEBHOOK_SECRET
);
} catch (err) {
console.error("Webhook signature verification failed:", err.message);
return res.status(400).send(`Webhook Error: ${err.message}`);
}
handleStripeEvent(event);
res.json({ received: true });
}
);
  1. Enregistrez votre point de terminaison API dans Stripe Workbench (ou via API).

Dans le Dashboard Stripe :

  • Allez dans Developers → Workbench → Webhooks
  • Ajoutez un point de terminaison, par exemple : https://your-api.com/webhooks/stripe
  • Sélectionnez les événements requis, par exemple : account.updated
  • Stripe vous fournira un secret de signature Webhook à utiliser dans votre point de terminaison.
  1. Routez différents événements vers vos gestionnaires d’événements.

Ne mettez pas de logique directement dans le point de terminaison webhook. Au lieu de cela, routez les événements vers des gestionnaires petits et spécifiques, par exemple :

function handleStripeEvent(event) {
switch (event.type) {
case "account.updated":
return handleAccountUpdated(event.data.object);
default:
return;
}
}

Cette approche des webhooks transfère la responsabilité : Stripe décide quand l’état d’un vendeur change, et votre plateforme enregistre ce changement.

Posted in

Laisser un commentaire