E-commerce Performance

Moteur d'achat produit

Rôle
Développeur Full Stack
Durée
~1 mois
Année
2023
Schéma du projet
01

Contexte

La plateforme e-commerce multi-sites vend des licences logicielles dématérialisées. Sur chaque site, deux types de pages présentent des produits à l'achat : les fiches produit (une page par produit, accessible via une URL avec slug) et les landings (pages dédiées à une marque, comme Microsoft, pouvant accueillir plusieurs moteurs simultanément). L'ancien moteur d'achat tournait sur les sites PHP legacy et n'était pas compatible avec la nouvelle instance Laravel. Un nouveau moteur, conçu pour Laravel et pensé pour évoluer, était nécessaire.

02

Problème

L'ancien moteur d'achat était structurellement lié aux sites PHP legacy, incompatible avec la nouvelle instance Laravel. La logique de combinaisons produit existait mais était dispersée dans le code HTML sans structure centralisée ni cohérente. Une réécriture complète était plus rapide qu'un portage et permettait d'apporter des fonctionnalités absentes de l'ancien système.

03

Solution

Le nouveau moteur d'achat repose sur deux couches distinctes : un backend PHP/Laravel et un frontend en vanilla JavaScript.

Architecture et configuration

Chaque site dispose d'un fichier de configuration PHP dédié, structuré en tableau associatif. Ce fichier définit une configuration par défaut applicable à tous les moteurs du site, ainsi que les configurations individuelles de chaque moteur. Chaque moteur possède un identifiant numérique unique (utilisé pour la logique interne) et un slug human-readable (ex. pc-0004), pensé pour faciliter le débogage et préparer une future gestion des configurations via un BO. Sur le site FR, le fichier de configuration couvre plus de 230 moteurs. Deux moteurs ont un rôle spécifique : l'ID 1 pour la fiche produit classique, l'ID 2 pour la fiche produit à intervalles de quantité (licences vendues par tranches). Tous les autres IDs correspondent à des moteurs positionnables librement sur n'importe quelle page du site.

Logique de matrice et filtrage des options

Chaque moteur affiche des champs de sélection (durée, plateforme, nombre de postes…) dont les combinaisons possibles sont définies dans une matrice centralisée dans la config PHP. La matrice associe une combinaison d'options (ex. A+D) à une référence produit. Lorsqu'un utilisateur sélectionne une option, le moteur JS désactive dynamiquement toutes les options des autres champs qui ne forment aucune combinaison valide avec le choix effectué. Les options absentes de la matrice sont désactivées dès le chargement. Sur les landings, la matrice est définie dans le fichier de configuration. Sur les fiches produit, la matrice est construite dynamiquement côté serveur à partir des produits partageant le même slug, en filtrant les produits non visibles ou non disponibles à la vente sur le site actif.

Fiche produit et SEO

Sur une fiche produit, ProductController::show() récupère les produits du slug directement et les retourne dans la vue Blade via un attribut data sur l'élément conteneur du moteur. Le moteur JS consomme ces données immédiatement sans déclencher d'appel XHR. Ce choix garantit que le contenu produit est présent dans le HTML dès le chargement de la page, ce qui est essentiel pour l'indexation SEO. Si l'URL contient un paramètre article=xxx, le moteur affiche ce produit par défaut ; sinon, il détermine et affiche le produit le moins cher en parcourant les données disponibles.

Appel XHR et sécurité

Sur les landings, un unique appel XHR est déclenché au chargement de la page, quel que soit le nombre de moteurs présents. Le JS collecte les IDs des moteurs et les références produit associées à chacun, puis envoie une seule requête. Le backend retourne une collection de DTOs (nom, prix TTC/HT, référence, images, données de promotion, etc.) puisée dans le cache Redis. Cette liste est mise en commun dans une classe JS dédiée, et chaque moteur y pioche les données qui le concernent.

La requête est protégée contre les attaques XHR replay par un token à usage unique, généré côté PHP au chargement de la page, et invalidé dès la première utilisation. Une limite de requête est également appliquée côté JS. Toute tentative de replay retourne une erreur.

Balisage et manipulation du DOM

Les éléments HTML à dynamiser sont balisés avec des attributs x-pc-ref (sur le même principe que les x-ref d'Alpine.js). Chaque moteur opère dans son propre scope DOM et manipule uniquement les éléments balisés dans son conteneur. Le JS ne génère pas de HTML, il met à jour les éléments existants. L'affichage de messages contextuels (hors-stock, mentions légales, promotions, etc.) est géré par le moteur selon les flags présents dans le DTO et selon des règles métier complexes : par exemple, selon que la licence est stockée directement en base de données (livraison immédiate) ou récupérée en temps réel auprès du fournisseur lors de la commande.

Ajout au panier

Lorsqu'un utilisateur clique sur « Acheter », le moteur JS émet un événement vanilla intercepté par un composant Livewire dédié à la gestion du panier. Le moteur n'intègre pas lui-même la logique d'ajout, cette séparation des responsabilités étant intentionnelle.

Alertes catalogue

Lors de chaque appel XHR, si un produit référencé dans la configuration d'un moteur est absent du cache ou si la configuration d'un moteur est invalide, une alerte email est envoyée automatiquement au pôle catalogue et à l'équipe technique. Un mécanisme de fichiers évite le spam : l'alerte pour un produit donné sur un moteur donné n'est renvoyée qu'après l'expiration d'un délai configuré, tant que le problème persiste.

Choix technique du vanilla JS

Alpine.js a été évalué en premier lieu, mais la communication entre composants imbriqués s'est révélée trop contraignante pour la complexité du moteur. Le vanilla JS, organisé en plusieurs classes distinctes, a été retenu pour sa flexibilité et sa capacité à répondre aux besoins présents et futurs sans dépendance externe.

04

Résultat

Le moteur d'achat est déployé sur l'ensemble des marchés de la plateforme multi-site. Le site FR recense à lui seul plus de 230 moteurs configurés. Sur les landings, jusqu'à une dizaine de moteurs tournent simultanément sur une page en ne déclenchant qu'un seul appel XHR sécurisé. Les fiches produit bénéficient d'un affichage immédiat du contenu sans latence, favorable à l'indexation SEO. Le filtrage dynamique des options selon la matrice garantit qu'un client ne peut sélectionner que des combinaisons produit existantes. Le système d'alertes assure une détection proactive des anomalies de configuration sans intervention manuelle. L'architecture du moteur (IDs uniques, configs par fichier PHP) est pensée pour évoluer vers une gestion depuis un BO couplé à des tables en base de données, sans réécriture.

Un projet Laravel en tête ?

Réponse sous 24 h. Missions en régie ou au forfait.

  • Île-de-France Sur site ou hybride
  • Partout en France Présentiel ponctuel à négocier — ex. Lyon, 2 jours par mois
  • International Full remote

Les données saisies servent uniquement à vous répondre. Politique de confidentialité.