Intégration Bsport : Gestion des cours et abonnements pour Swell Dance

Sommaire

Je souhaite être accompagné(e) pour intégrer Bsport sur mon site Webflow.

Contacter Justa

Le contexte

Swell Dance est un studio de danse parisien qui propose des cours réguliers et des ateliers ponctuels. Toute la gestion, planning, réservations, paiements, vit dans Bsport, l'outil métier de référence pour ce type d'activité.

Bsport propose un widget natif à coller sur n'importe quel site. Il fonctionne, mais il est moche : design figé, typographies imposées, mises en page qu'on ne contrôle pas, et un rendu qui jure avec la charte d'un studio qui mise sur l'identité visuelle.

L'objectif : afficher le programme et la fiche d'un atelier directement dans Webflow, avec un design 100 % custom, sans renoncer à la fiabilité de Bsport pour le checkout.

L'architecture

Bonne nouvelle : Bsport expose une API publique en lecture. Pas besoin de proxy, pas besoin de Worker, pas de clé à protéger. Le navigateur appelle directement l'API depuis la page Webflow.

Deux briques :

  1. L'API Bsport (api.production.bsport.io/api/v1)
  2. Un script vanilla JS sur la page Webflow qui appelle l'API et remplit le DOM

Pour la réservation à proprement parler, on n'essaie pas de réinventer la roue. Le bouton « Réserver » envoie l'utilisateur sur le checkout Bsport. On s'occupe de la vitrine, Bsport s'occupe du paiement.

Étape 1 : Comprendre les deux endpoints qui comptent

Toute la mécanique tient sur deux endpoints qu'il faut savoir orchestrer.

/offer/ retourne les sessions disponibles : un cours précis à une date précise, avec son nombre de places, sa durée, son statut. Une offer est l'instance d'un atelier dans le calendrier.

/meta-activity/ retourne les ateliers eux-mêmes : le nom, la description longue, l'image de couverture. Une meta-activity est le « modèle » qui peut générer plusieurs offers.

Chaque offer porte un champ meta_activity qui pointe vers son atelier parent. C'est ce lien qu'il faut résoudre côté front.

// 1. On récupère les prochaines sessions
fetch('/offer/?company=5124&is_workshop=true&only_future=true&available=true&page_size=4')
// 2. On récupère les ateliers liés en un seul appel
fetch('/meta-activity/?id__in=' + metaIds.join(','))

Plutôt que de faire un appel par session (et donc N requêtes), on collecte les meta_activity uniques et on les charge en un seul id_in=…. Une requête, peu importe le nombre d'offres.

Étape 2 : La page « Programme » : les 4 prochaines sessions

Sur la home et la page programme, Swell affiche les 4 prochaines sessions. Le script :

  1. Appelle /offer/ filtré sur les sessions futures et disponibles
  2. Récupère en parallèle les meta-activities concernées
  3. Construit la map meta_activity.id → atelier
  4. Génère une carte par offer en croisant les deux jeux de données

Chaque carte affiche la date, l'heure, la durée, le nom de l'atelier, l'image du cover et le studio. Le lien pointe vers /atelier?id=<meta_activity_id> — la page détail.

<div id="sw-list"></div>

Côté Webflow, un seul wrapper. Le script construit le HTML des cartes par concaténation de strings. C'est volontairement simple — pas de framework, pas de templating engine, et tout tient dans un fichier.

intégration custom bsport sur Webflow

Étape 3 : La page « Atelier » : un événement, ses sessions

Quand un visiteur clique sur une carte, il atterrit sur /atelier?id=<id>. Le script de cette page :

  1. Lit l'id dans l'URL
  2. Lance en parallèle deux fetchs : la meta-activity (pour le contenu éditorial) et toutes les offers liées à cet atelier
  3. Remplit la page : titre, image, description, et la liste de toutes les sessions à venir

Pour la liste des sessions, chaque ligne devient un lien vers le checkout Bsport : https://backoffice.bsport.io/customer/payment/offer/<offer_id>. On ne ré-implémente pas le panier - on délègue.

intégration personnalisé session bsport

Étape 4 : Le pattern data-attributes : Webflow pilote le design

Pour que l'équipe Swell puisse repositionner ou restyler n'importe quel élément sans toucher au code, le script ne crée jamais de structure HTML par lui-même sur la page atelier. Il remplit des éléments existants, identifiés par des data-attributes :

<p data-atelier="titre"></p>
<img data-atelier="image" />
<div data-atelier="content"></div>
<div data-atelier="sessions"></div>

Au runtime, le script fait :

document.querySelectorAll('[data-atelier="titre"]').forEach(el => {
  el.textContent = atelier.name;
});

Avantage : si demain Swell veut déplacer le titre, ajouter un sous-titre, ou dupliquer l'image en deux endroits, il suffit d'ajouter un nouveau bloc avec le bon data-atelier. Le script suit, sans modification.

Étape 5 : Le checkout : sortir du chemin

Réimplémenter un panier de réservation, c'est ouvrir une boîte de Pandore : gestion des places en temps réel, paiement, e-mails de confirmation, gestion des remboursements, RGPD…

On évite proprement. Le bouton « Réserver » est un simple lien :

let bookingUrl = 'https://backoffice.bsport.io/customer/payment/offer/' + offer.id;

Bsport gère tout ce qui se passe après le clic. L'utilisateur revient ensuite sur le site Swell. Côté maintenance, c'est zéro effort  quand Bsport améliore son tunnel de paiement, on en bénéficie sans rien toucher.

Étape 6 : Les détails qui changent l'expérience

Trois finitions valent la mention.

Le statut « en cours ». Pour chaque session affichée, on calcule en temps réel sa position vis-à-vis de l'instant courant (now vs date_start vs date_start + duration). Une session en cours est badgée visuellement avec un point qui pulse. C'est un détail, mais il rassure le visiteur qui passe le matin pour vérifier que le cours du soir tient toujours.

function offerStatus(offer) {
  var now = Date.now();
  var start = new Date(offer.date_start).getTime();
  var end = start + offer.duration_minute * 60000;
  if (now >= end) return 'past';
  if (now >= start) return 'ongoing';
  return 'future';
}

Le partage natif. Sur mobile, un bouton déclenche la Web Share API du système (iOS, Android) pour partager l'atelier en un clic vers WhatsApp, Messages, Mail, etc. Si l'API n'est pas disponible (desktop sur certains navigateurs), le bouton se masque tout seul.

Le format français. Bsport renvoie des dates ISO standard. Le script reformatte tout côté client : « MERCREDI 14 MAI », « 19H30 - 20H45 », « 1h15 ». Pas de dépendance à Intl ni à une librairie de dates - quelques fonctions utilitaires suffisent et le bundle reste léger.

Pourquoi pas le widget natif Bsport ?

  • Design figé. Le widget impose ses propres styles. Difficile à thématiser, impossible à fondre dans une charte forte comme celle de Swell.
  • Iframe = boîte noire. Le contenu n'est pas crawlable par Google, les ancres internes ne fonctionnent pas, l'expérience mobile est imposée.
  • Mises en page imposées. On affiche ce que Bsport veut bien afficher, dans l'ordre que Bsport décide. Pas de cartes éditoriales, pas de mise en avant d'un atelier phare.

L'API publique change la donne : on récupère la donnée brute, on la met en forme librement, et on garde la fiabilité de Bsport pour ce qui compte vraiment -> la transaction.

Le résultat

Une page programme et une page atelier intégralement à la marque Swell, alimentées en temps réel par Bsport, sans serveur intermédiaire à maintenir. La réservation reste sur les rails de Bsport - pas de risque sur le paiement, pas de risque sur la disponibilité. Et l'équipe Swell peut redessiner ses pages dans Webflow sans appeler un développeur, tant que les data-attributes sont conservés. Vous voulez faire pareil ? Faites appel à notre agence Webflow.

Voir d'autres intégrations

Je veux lancer mon projet avec Justa

Nous contacter