Oramus

← Dossiers · Plugin sur-mesure

L'agence refusait de signer sans le bon freelance — six mois plus tard, ×10 sur le CA en ligne

Synchro ERP et intégration d'un simulateur bancaire pour un grand groupe français. Debug d'une API en aveugle. Six mois solo en sous-traitance, vs deux ans à trois personnes auparavant.

Client Un grand groupe français de distribution d'engins motorisés (jusqu'à 350 M€ de chiffre d'affaires) · Distribution & loisirs Anonymisé

Publié le

Tags #wordpress #woocommerce #erp-integration #integration-bancaire #swagger #openai #sous-traitance

Un grand groupe français pèse jusqu’à 350 millions d’euros de chiffre d’affaires sur la distribution d’engins motorisés. Son site web fait à peine 50 000 euros de CA par mois — un chiffre dérisoire pour une activité de cette taille, mais l’outil précédent ne fait plus le travail. Une nouvelle agence digitale est sollicitée pour reprendre le projet. Elle pose une condition à sa propre signature : trouver d’abord le bon freelance technique. Six mois plus tard, le CA en ligne est à 500 000 euros par mois.

Le contexte

Un groupe historique de distribution, plusieurs dizaines de concessions sur le territoire, des engins motorisés à fort ticket (camping-cars, automobiles, autres véhicules de loisirs et utilitaires) — chaque produit fini se vend entre 50 000 et 200 000 euros pièce. Le site internet est en théorie une vitrine secondaire, mais en pratique c’est devenu le point d’entrée naturel pour des clients qui cherchent en ligne avant de se déplacer.

Deux ans plus tôt, une équipe de trois personnes a livré une version du site qui ne donne pas satisfaction. Architecture vieillissante, mise à jour du catalogue laborieuse, pas de simulation de financement en ligne, conversion faible. Quand le sujet revient sur la table, le groupe consulte une nouvelle agence digitale.

L’agence, prudente, refuse de s’engager tant qu’elle n’a pas identifié le freelance technique capable de tenir l’intégration ERP et l’intégration bancaire. C’est mon profil — quinze ans de WordPress, plugins métier, intégrations API — qui débloque la décision. L’agence signe, je signe avec l’agence en sous-traitance technique. L’agence pilote le design, la conception commerciale, le pilotage de projet. Je pilote la partie technique de mon périmètre.

Le problème

Le site précédent était sur WordPress / WooCommerce, mais avec une intégration ERP fragile et aucun mécanisme de simulation de financement en ligne. Deux problèmes structurels :

  • Pas de catalogue à jour. Les 5 000+ véhicules en stock dans l’ERP du groupe n’étaient remontés sur le site qu’à la main ou via un import semi-manuel. Décalages permanents, fiches obsolètes, véhicules vendus encore affichés disponibles.
  • Pas de simulateur de financement. Or, sur un véhicule à 80 000 euros, le visiteur ne décroche pas le téléphone tant qu’il n’a pas une estimation de mensualités. C’est le frein de conversion numéro un sur ce ticket.

L’agence avait identifié la solution à intégrer : un simulateur de prêt édité par un grand partenaire bancaire français, leader sur le financement de véhicules de loisirs. Reste à l’intégrer techniquement — et c’est là que les choses se compliquent.

L’approche technique

L’architecture cible tient en deux briques principales : la synchronisation ERP → WordPress, et l’intégration WordPress → simulateur du partenaire bancaire. Tout le reste (design, parcours commercial, contenu éditorial) est pris en charge par l’agence.

Synchronisation ERP → WordPress

L’ERP du groupe expose les données catalogue en XML. Le plugin que je développe orchestre la chaîne suivante :

  1. Récupération du flux XML depuis l’ERP, deux fois par jour (12h00 et 00h00). La cadence est négociée avec le groupe : suffisamment fréquente pour que les vendeurs en concession n’aient pas à expliquer en visio qu’un véhicule affiché disponible ne l’est plus, suffisamment espacée pour ne pas saturer l’ERP.
  2. Transformation XML → CSV via un script de mapping. Le format de sortie est calibré pour l’import natif WooCommerce, ce qui évite de réinventer la couche d’écriture en base WordPress.
  3. Import WooCommerce : création / mise à jour / archivage des produits selon leur statut dans le flux. Dédoublonnage par référence ERP, stockée en post meta.
  4. Garbage collection : les véhicules absents du flux pendant N synchros consécutives sont basculés en statut “vendu / archivé” — pas supprimés, pour conserver les URLs SEO et les rediriger proprement.

5 000 véhicules au catalogue à un instant T, deux synchros par jour, sur un hébergement mutualisé renforcé : l’enjeu performance est réel. Chaque cycle de synchro doit boucler en moins de 10 minutes pour ne pas mordre sur les heures ouvrées des concessions.

Intégration du simulateur bancaire

Le simulateur ne tourne pas dans le navigateur du visiteur — il tourne côté serveur du partenaire bancaire. Le mécanisme :

  1. Le plugin WordPress génère un catalogue JSON enrichi : pour chaque véhicule, les champs nécessaires au calcul de financement (prix, type de motorisation, année, kilométrage, catégorie, identifiant interne, etc.). Le format JSON est strict, défini par une documentation Swagger fournie par le partenaire bancaire.
  2. Le plugin pousse ce JSON via cURL en POST vers un endpoint dédié du partenaire bancaire, un envoi quotidien par concession (chaque concession ayant son identifiant wm_name distinct). Le JSON dans le corps de la requête, avec authentification API.
  3. Côté partenaire, le catalogue est traité et les mensualités sont calculées. Le plugin récupère ensuite les résultats via une requête GET et les stocke localement pour servir le widget de simulation intégré au site, sans aller-retour serveur à chaque visiteur.

En théorie, c’est simple. En pratique, c’est l’épisode du dossier qui demande le plus de cran.

Le pivot du récit — debugger une API bancaire en aveugle

Première intégration, premier POST de test, première erreur. La documentation Swagger devait servir de contrat strict : décrire les champs attendus, leurs types, leurs valeurs autorisées, les codes d’erreur en retour. Plusieurs semaines d’exploration plus tard, l’inventaire des écarts entre la doc et l’API réelle est éloquent.

Inventaire des bugs Swagger réellement rencontrés

Mismatch sur le nom du paramètre principal. Le Swagger documentait wm_name (snake_case avec underscore). L’API attendait wmName (camelCase, sans underscore). Une seule lettre de différence, mais 100 % des requêtes en échec tant qu’on n’avait pas identifié l’écart. Aucune erreur explicite côté serveur — juste un comportement incorrect.

Paramètre date documenté à tort dans le body de la requête GET. Le Swagger l’incluait. L’API le refusait. Pour récupérer les mensualités d’un catalogue, il fallait au contraire passer wmName en query parameter dans l’URL, ce qui n’était pas documenté du tout.

Aucun exemple de requête GET fonctionnelle dans la documentation. Or c’est la requête de récupération des résultats — celle dont on a besoin tout de suite après le POST. Méthode : déduire le format correct par essais successifs, sous contrainte de 2 requêtes par jour.

Codes de catégorisation véhicule à sens caché. Les codes lettre — A pour automobile, C pour caravane, V pour van/camping-car — n’étaient associés à aucune règle business explicite. En pratique, le contrat client définissait silencieusement le périmètre autorisé : envoyer un véhicule en catégorie A quand le contrat couvrait C et V retournait un succès apparent (Job is running, 200 OK) mais aucun résultat de simulation utilisable. Bug invisible — on croit que le système fonctionne, il refuse silencieusement.

Règles d’éligibilité non documentées. Le partenaire bancaire refuse de financer les véhicules trop anciens — 144 mois maximum pour les camping-cars, vans et fourgons, 84 mois maximum pour les caravanes. Cette règle n’apparaissait nulle part dans le Swagger. Découverte uniquement parce qu’un véhicule de plus de 12 ans présent dans le catalogue de test ramenait une erreur, et qu’un retour humain (au bout de plusieurs semaines) a fini par mentionner cette règle au détour d’un mail. « Nous avions mis en place, lors de l’intégration la première fois de la box de simulation pour [un autre site], une exclusion sur les véhicules les plus anciens — c’est un point qu’il faudrait également reprendre de votre côté. » Mention orale d’une règle business, à intégrer rétroactivement dans la logique de filtrage côté plugin.

Headers d’authentification approximatifs. Certains headers documentés étaient inutiles. D’autres, nécessaires, n’étaient pas documentés. Le JSESSIONID et les cookies de session devaient être correctement propagés mais leur rôle n’était pas explicité.

Headers CORS manquants côté serveur, contre-documentés. Le guide d’implémentation affirmait : « pour fonctionner et éviter les blocages CORS des navigateurs il est OBLIGATOIRE d’utiliser des sites en SSL ». Sauf que côté navigateur, le serveur partenaire ne renvoyait pas le header Access-Control-Allow-Origin, rendant tout appel direct depuis le browser impossible. Toutes les implémentations Ajax / Fetch côté front échouaient avec un blocage CORS sec — la seule voie d’intégration possible était server-side avec cURL depuis PHP.

Incohérence des constantes URL dans le kit de démarrage. Le fichier JavaScript fourni pour la version staging pointait, via une constante interne (const BOXA_URL = "..."), vers l’environnement de production. Quand on développe en staging, on s’attend à ce que le code fourni vise staging. Sinon, première mise en ligne, on s’aperçoit qu’on tape sur les serveurs de prod depuis le premier jour.

Erreur de syntaxe HTML dans le guide d’intégration. En page 14, un snippet à recopier contenait une balise <script> non fermée. Copié-collé tel quel : page cassée. Sept ans de WordPress permettent de repérer ça en deux secondes, un débutant pouvait y passer une journée.

Limite de requêtes confuse. Présentée d’abord comme « 1 POST par jour total » côté staging. En réalité : 1 POST par jour par wm_name (donc une dizaine pour les concessions du client). Plus une limitation distincte sur la taille du body — un catalogue de 42 véhicules passait, un catalogue de 526 véhicules ne passait pas. La limite exacte n’a jamais été documentée, juste pointée a posteriori après plusieurs erreurs CAT-003.

Affectation incorrecte des véhicules au premier wm_name de la requête. Bug côté serveur, pas dans la doc : si on envoyait dans un même POST 32 véhicules avec wm_name = A et 10 véhicules avec wm_name = B, le serveur retournait 42 véhicules tous affectés à A. Reproduit deux fois indépendamment, confirmé côté support comme un comportement non spécifié.

L’astuce qui change la donne — construire son propre banc de test

Face à la contrainte de 2 tests par jour côté serveur partenaire, attendre 24 heures entre chaque hypothèse à valider rendait la convergence quasi impossible. J’ai donc construit en parallèle un simulateur local du contrat d’API, hébergé sur un sous-domaine du projet de pré-production : génération du JSON catalogue via WooCommerce, transformation au format Swagger, retour mocké des mensualités avec des valeurs aléatoires plausibles, journalisation complète des erreurs côté serveur, base de données SQLite pour persister les requêtes / réponses.

L’objectif n’était pas de simuler la logique de calcul de financement — c’était de simuler le contrat technique : authentification, format du body, headers attendus, codes de retour, gestion des erreurs HTTP. Une fois ce contrat reproduit fidèlement en local, je pouvais itérer cent fois par jour sur la couche d’intégration au lieu de deux. Les vraies requêtes vers les serveurs partenaires étaient ensuite réservées à la validation finale d’une hypothèse précise.

Cette méthode — mocker localement un contrat externe contraignant pour s’affranchir de ses limitations — n’est pas nouvelle, mais elle est trop rarement pratiquée en intégration métier. Elle vaut autant pour une API bancaire avec quota qu’une API qui coûte cher au call, ou un endpoint partenaire en maintenance pour la nuit. Le ratio temps investi / temps gagné est massif.

Méthode adoptée pendant les 15 jours-homme

  • Maximiser l’information par requête vers le vrai serveur. Chaque appel devait permettre de valider ou invalider plusieurs hypothèses simultanément. Plus question d’envoyer un test pour “voir ce qui se passe”.
  • Tenir un journal d’observation rigoureux. Chaque requête envoyée, chaque réponse reçue, chaque hypothèse formulée, chaque déduction. Sans ce carnet de bord, on perd le fil au bout de trois jours et on recommence des tests déjà faits.
  • Déduire les règles cachées par recoupements. Un véhicule à 12 ans refusé, un véhicule à 8 ans accepté, code d’erreur identique dans les deux cas → règle silencieuse sur l’âge. Faire varier les valeurs intermédiaires pour borner la règle.
  • Communiquer factuellement et constructivement avec le partenaire. Ne pas se contenter de remonter des bugs — proposer des corrections de documentation, formuler chaque demande comme une hypothèse précise à confirmer ou infirmer en une réponse. Sur la durée, c’est ce qui débloque les retours utiles vs les réponses automatiques.

À la sortie, le plugin envoie des JSON propres, conformes à la fois au Swagger documenté et aux règles non documentées. Le simulateur de financement fonctionne sur l’intégralité du catalogue. Aucune erreur silencieuse, aucun véhicule “perdu”.

La mise en œuvre — six mois en sous-traitance, ChatGPT comme accélérateur

Le projet entier — de la première spec à la mise en production — a tenu en six mois calendaires, en sous-traitance technique solo pour l’agence. Pour rappel, l’équipe précédente avait travaillé deux ans à trois personnes sans aboutir à une version satisfaisante.

Pendant ces six mois, ChatGPT (interface navigateur) a fait partie de la boîte à outils, dans des rôles très précis :

  • Rédaction accélérée de code. Notamment pour les helpers répétitifs : mappers XML→CSV, parsers JSON, validateurs de schéma. Du code que je sais écrire de tête mais qui prend du temps à taper.
  • Relecture critique. Particulièrement utile sur les snippets sensibles : authentification, gestion d’erreurs, edge cases. Un deuxième regard, même imparfait, soulève des questions qu’on ne se pose pas seul.
  • Génération d’hypothèses pendant le debug Swagger. “Voici un code 400 sur ces données, voici ce que dit la doc Swagger, qu’est-ce qui pourrait expliquer l’écart ?” — pas une réponse magique, mais des pistes à tester quand on en manque.

Ce que ChatGPT n’a pas fait :

  • L’architecture. La conception du plugin, le découpage en modules, les choix techniques (XML → CSV → WooCommerce import plutôt qu’écriture directe en base, garbage collection plutôt que delete, lock TTL sur la synchro, cron côté hébergeur plutôt que wp_cron) — ce sont des décisions issues de quinze ans d’expérience, pas d’un prompt.
  • Le métier. Comprendre les contraintes business du client, anticiper les besoins du commercial en concession, savoir pourquoi un véhicule en statut “vendu” ne doit pas être supprimé immédiatement — ce sont des choses qu’on apprend en travaillant avec des clients, pas en interrogeant un modèle.
  • Le debug Swagger. Aucune IA ne pouvait deviner que le partenaire bancaire refusait silencieusement les véhicules de plus de 10 ans. Cette information ne se trouve nulle part dans les corpus d’entraînement.

Estimation honnête : sans ChatGPT, le projet aurait pris environ 18 mois solo — toujours largement en dessous des deux ans à trois personnes de la précédente équipe, mais nettement plus long que les six mois effectivement réalisés. L’IA fait gagner du temps d’écriture, pas du temps de réflexion.

Résultats mesurables

Le site relooké et techniquement refondu est mis en ligne. L’effet est quasi instantané — pas de courbe d’apprentissage utilisateur, pas d’effet de levier SEO progressif, juste un outil qui marche enfin et qui laisse passer une demande latente.

PériodeCA mensuel du site
Avant refonte (ancienne version)~50 000 €
Après mise en ligne~500 000 €

×10 sur le CA en ligne, à effectif marketing constant, à budget publicitaire constant, à inventaire identique.

Lecture : la demande était là. L’outil précédent ne la laissait pas passer. Une fois le catalogue à jour deux fois par jour, la simulation de financement disponible en ligne sans friction, et le tunnel de contact propre, le marché a fait son travail.

Côté l’agence, le projet sécurise une relation client à fort tickets sur les années suivantes. Côté Oramus, le dossier devient une référence pour positionner le sous-traitance technique sur des projets à enjeu commercial fort.

Leçons à reprendre

1. Le bon profil débloque la signature, pas seulement la livraison. Une agence digitale qui prend ses précautions sur un projet à fort enjeu refuse parfois de s’engager sans la garantie technique. C’est une opportunité pour un freelance senior : être le profil qui rassure suffisamment pour permettre la signature. Cette position ne se construit pas avec un portfolio — elle se construit avec une réputation et des références techniques claires sur des projets antérieurs comparables.

2. La documentation officielle d’une API tierce n’est jamais la vérité. Spécialement pour les API bancaires, métier, ou de grands acteurs où la doc est rédigée par des équipes différentes de celles qui maintiennent l’API. La méthode de debug en aveugle (journal d’observation, hypothèses falsifiables, recoupements) doit faire partie de la boîte à outils, au même titre que les frameworks. Et quand le partenaire impose un quota de tests qui rend l’itération impossible, construire son propre banc de test qui reproduit le contrat technique de l’API permet de gagner des semaines : le banc local devient le terrain d’itération, les vraies requêtes ne servent plus qu’à valider une hypothèse précise. Quand on bute, ce n’est jamais “l’API est bizarre” — c’est qu’il existe une règle qu’on n’a pas encore comprise.

3. L’IA ne remplace pas l’expertise — elle multiplie le rendement d’un expert. Un développeur senior avec ChatGPT en 2024 est trois fois plus rapide qu’un développeur senior sans. Un développeur junior avec ChatGPT reste un junior, qui produit plus vite du code que personne ne sait relire. Le facteur multiplicateur s’applique sur l’expertise existante, pas sur son absence. C’est une vérité à rappeler à chaque conversation sur “l’IA va remplacer les développeurs”.

Pour aller plus loin