Table des matières :
- Portail client et périmètre ERP/WMS/TMS : arrêter de confondre “Mon compte” et intégration SI
- API, fichiers et webhooks : critères de choix (et pourquoi vous finirez souvent en hybride)
- Points d’ancrage PrestaShop : Webservice legacy, API d’admin PrestaShop 9, hooks et CLI
- Webhooks robustes : idempotence, signatures, retries et outbox pattern (sinon vous dupliquez tout)
- Échanges de fichiers (CSV/EDI) : pipeline SFTP reproductible, staging SQL et reprise sur incident
- Mise en production : cohérence des données, performance portail, supervision et anti-régressions
Portail client et périmètre ERP/WMS/TMS : arrêter de confondre “Mon compte” et intégration SI
Un portail client (B2B ou B2C avancé) n’est pas un thème PrestaShop avec deux onglets de plus. C’est une surface d’exposition de données “post-achat” (factures, BL, SAV, tracking multi-colis, encours, RMA, contrats, conditions de paiement) qui vivent rarement dans PrestaShop, mais dans l’ERP, le WMS et le TMS. Dès que vous affichez autre chose que les objets natifs (ps_orders, ps_order_detail, etc.), vous êtes dans une problématique d’intégration SI, pas d’UX.
En pratique, les premiers malentendus arrivent sur le vocabulaire :
- “Mon compte” = consultation de données e‑commerce (commandes, adresses, retours) majoritairement dans PrestaShop.
- “Portail client” = consolidation de données inter-systèmes (ERP/WMS/TMS/CRM), avec des règles de vérité, des latences, et des litiges métier (“mon BL n’est pas ma facture”, “mon colis est scindé en 3 expéditions”, “ma commande est en préparation mais le tracking existe déjà”).
Côté versions, les choix d’implémentation divergent fortement entre PrestaShop 8.1.x (cœur encore très “legacy”) et PrestaShop 9.x (plus Symfony, services et API d’admin modernisée). Les exemples ci-dessous supposent PHP 8.2+ (8.3 si votre stack et vos modules sont prêts) et un accès serveur minimal (cron, logs, configuration TLS). Sans cron, pas de batch fiable ; sans logs centralisés, pas de support exploitable.
Le périmètre doit être écrit comme un contrat : quelles entités sont “source of truth” (ERP généralement), quels champs sont dérivés (ex. tracking consolidé), quels identifiants font foi (UUID, références métier, id_order), et quelles latences sont acceptables. Un tracking “temps réel” (TMS) tolère mal un batch nocturne ; à l’inverse, un export comptable quotidien n’a pas besoin d’une API synchrone. Pour cadrer les patterns d’intégration ERP (connecteurs, référentiels, synchronisation), voir aussi : Intégration ERP : API, connecteurs et donnée unique en temps réel.
Un moyen simple de lever l’ambiguïté en atelier est de formaliser une mini-matrice “données ↔ système” (exemple volontairement réaliste côté logistique) :
| Donnée portail | Source de vérité | Canal conseillé | Latence cible | Commentaire d’exploitation |
|---|---|---|---|---|
| Factures PDF + statut “payée/échue” | ERP | API (lecture) + cache | minutes/heures | Souvent sensible (B2B) : tracer les accès et limiter les PII |
| BL / preuve de livraison | WMS / TMS | Fichier (batch) ou API | heures | Les BL arrivent parfois après expédition selon processus d’entrepôt |
| Tracking multi-colis (1 commande → n expéditions) | TMS | Webhook + API détail | secondes/minutes | Éviter le polling, gérer les replays |
| Encours / limite de crédit | ERP | API synchrone (si stable) | minutes | Prévoir “mode dégradé” (valeur en cache + avertissement) |
| RMA / retours | ERP ou module SAV | Webhook (événement) | minutes | Attention aux doublons (retour créé deux fois) |
Prérequis concrets (sinon vous allez bricoler et le support sera un enfer) :
- un mapping de statuts PrestaShop ⇄ ERP/WMS/TMS (commande, préparation, expédition, facturation, retour) ;
- un stockage de corrélation (table d’intégration) pour lier
id_orderàorder_ref_erp,shipment_id_tms,warehouse_code; - une stratégie d’auth (API keys, OAuth2, mTLS) et de rotation des secrets ;
- un runbook d’incident : “ERP down”, “doublon de commande”, “tracking incohérent”.
Ajoutez un point souvent oublié dans les portails B2B en France : la qualité des identifiants métier. Si l’ERP raisonne en code_client, code_site_livraison, num_commande_erp, votre portail doit les stocker/afficher sans les “réinterpréter”. Sinon, le support bascule en “capture d’écran” et la résolution devient lente et coûteuse.
API, fichiers et webhooks : critères de choix (et pourquoi vous finirez souvent en hybride)
Trois canaux dominent l’intégration d’un portail client : API synchrones, échanges de fichiers (CSV/EDI via SFTP/FTPS/Share) et webhooks (événements push). Chacun a des modes de panne spécifiques : l’API tombe (timeouts, rate limit), le fichier arrive en retard (ou incomplet), le webhook est reçu deux fois (ou jamais). Le choix ne se fait pas “par préférence”, mais par contraintes : latence, volume, criticité, et capacité du SI à opérer l’intégration 24/7.
Une grille de décision (simple mais utile) :
| Critère | API synchrone | Webhook | Fichier (CSV/EDI) |
|---|---|---|---|
| Latence attendue | Bonne si SI stable | Excellente si rejouable | Moyenne à faible (batch) |
| Rejouabilité | À concevoir (idempotence côté endpoints) | Indispensable (dedup + retries) | Naturelle si vous versionnez/tracez les fichiers |
| Gros volumes (stocks/catalogue) | Risqué sans pagination/limites | Inadapté (trop d’événements) | Très adapté (batch, delta, compression) |
| Exploitabilité | Nécessite métriques de latence/erreurs | Nécessite journaux d’événements | Nécessite pipeline et archivage |
| Couplage SI | Fort (temps réel) | Moyen (asynchrone) | Faible (décorrélé) |
Les webhooks sont souvent présentés comme “temps réel”, mais le point dur n’est pas la vitesse : c’est la fiabilité et la rejouabilité. Stripe résume correctement le principe : “Webhooks are a way for an app to provide other applications with real-time information.” (Stripe Docs – Webhooks). Dans une intégration ERP/WMS/TMS, ça se traduit par “événements d’expédition”, “mise à jour de stock”, “facture générée”, injectés côté portail client sans polling constant.
L’API synchrone est pertinente quand le portail doit rendre une page (ex. liste de factures) avec des données fraîches, et que l’ERP a une latence stable. Les fichiers sont pertinents quand : (1) le SI n’a pas d’API, (2) vous avez de gros volumes (catalogues, stocks multi-entrepôts), (3) vous devez garantir une traçabilité batch (ex. EDI). En pratique, les architectures les plus stables sont hybrides : webhooks pour déclencher, API pour récupérer le détail, fichiers pour les gros deltas.
Mini-scenario typique (très courant en logistique) :
- Le TMS pousse
shipment.updateddès qu’un colis change d’état (pris en charge, en transit, livré). - Votre portail reçoit l’événement, l’écrit en base (ou en queue), puis appelle l’API TMS pour récupérer le détail (liste colis, liens transporteur, POD si disponible).
- Une fois par nuit, le WMS dépose un fichier de stock consolidé par entrepôt (trop volumineux pour un flux événementiel fiable).
- Le matin, l’ERP dépose (ou expose) les factures du J‑1.
Pour éviter de réinventer les fondamentaux REST côté connecteurs, gardez un rappel propre sur les endpoints, méthodes, statuts et conventions : Endpoint API : définition, méthodes HTTP et bonnes pratiques REST. Et si vos flux passent par une passerelle (auth centralisée, throttling, routage), le cadrage est ici : API Gateway : authentification, rate limiting et routage des microservices.
Points d’ancrage PrestaShop : Webservice legacy, API d’admin PrestaShop 9, hooks et CLI
PrestaShop fournit deux axes “API” très différents : le Webservice legacy (souvent XML, modèle historique) et l’API d’administration PrestaShop 9 (API Platform v3, OAuth, endpoints CQRS). Le Webservice est rapide à activer, mais limité sur des cas métiers complexes (multi-entrepôts, statuts custom, agrégations) et rarement optimisé pour de forts volumes. Pour le Webservice, les bases sont ici : Webservice PrestaShop : activer l’API et créer une clé d’accès.
Sur PrestaShop 9, l’API d’admin est plus structurante si vous construisez un portail client “propre” (backoffice headless, intégration modernisée, scopes OAuth). Mais attention : “disponible” ne veut pas “couvre tout”. Beaucoup d’objets utiles à un portail (documents, logistique, états métier, champs de modules) restent hors périmètre standard et nécessitent des endpoints custom, ou un service de lecture dédié. Détails techniques : API d’administration PrestaShop 9 : OAuth, API Platform v3, endpoints CQRS.
Pour émettre des événements (webhooks) ou déclencher des exports, vous retombez vite sur les hooks PrestaShop et/ou des commandes CLI. Exemple typique : au hook actionValidateOrder, vous écrivez dans une table “outbox” l’événement order.created, puis un worker (cron/queue) pousse vers l’ERP. Ne faites pas l’appel HTTP vers l’ERP dans le hook : vous allez rallonger le checkout et introduire des pannes aléatoires. Pour l’outillage : Hooks PrestaShop : rechercher et identifier les hooks dynamiques et Commandes CLI PrestaShop : liste, catégories et options d’aide.
Un point d’attention spécifique “portail client” : vous aurez vite deux types de flux, avec deux exigences différentes :
- Flux “lecture” (portail affiche) : privilégier des endpoints dédiés, cache, et timeouts stricts (sinon la page se met à dépendre de la santé de l’ERP).
- Flux “écriture/synchronisation” (portail pousse) : privilégier l’asynchrone, l’outbox, et une observabilité forte (sinon vous ne saurez pas où la commande s’est perdue).
Enfin, côté performance et qualité de code, méfiez-vous des intégrations “ORM partout” : les connecteurs mal écrits créent des N+1 destructeurs (lecture d’items commande, adresses, taxes, transporteurs). Sur des boutiques à gros volume, ça explose en CPU et en latence portail. Rappel utile : ORM : limites, requêtes N+1 et quand préférer le SQL brut.
Webhooks robustes : idempotence, signatures, retries et outbox pattern (sinon vous dupliquez tout)
Un webhook fiable n’est pas “un POST vers une URL”. C’est un mini-protocole avec : identifiant d’événement, version de schéma, signature, gestion des rejets, et mécanisme de retry. Si vous ne concevez pas l’idempotence, vous allez créer des commandes en double, des statuts incohérents, des stocks négatifs. L’HTTP vous donne une boussole : “A request method is considered ‘idempotent’ if the intended effect on the server of multiple identical requests with that method is the same as the effect for a single such request.” (RFC 9110 – HTTP Semantics, définition de l’idempotence : RFC 9110 – HTTP Semantics).
Concrètement, vous devez inclure un event_id unique (UUID v4 ou ULID), et côté récepteur conserver un journal de déduplication (ex. table received_events(event_id, received_at, status)). Le récepteur répond 2xx uniquement quand l’événement est durablement pris en charge (au minimum écrit en base / en queue). Si vous répondez 200 “trop tôt”, vous perdez des événements lors d’un crash. Et si vous répondez 500 à tort, vous provoquez des retries et des doublons.
Un payload “minimal mais opérable” (exemple) :
{
"event_id": "01J3Q9MZ1B6R2J9W2D2VQH4H9K",
"event_type": "shipment.updated",
"schema_version": 2,
"occurred_at": "2026-07-27T09:12:44Z",
"data": {
"order_ref_erp": "CDE-458772",
"shipment_id_tms": "SHP-9911827",
"status": "IN_TRANSIT"
}
}
La partie “outbox pattern” (côté émetteur) évite un piège classique : écrire en base PrestaShop mais rater l’appel sortant. Le principe : vous persistez l’événement dans la même transaction (ou le même contexte de cohérence) que la donnée métier, puis un worker se charge de l’envoi. Exemple de colonnes utiles (sans sur-ingénierie) :
id(auto)event_id(ULID/UUID)type(order.created,invoice.published, etc.)payload(JSON)status(pending,sent,failed)retry_count,next_attempt_at,last_error
La sécurité n’est pas optionnelle : signature HMAC (ex. X-Signature: sha256=...), timestamp + fenêtre de validité (anti-replay), rotation de secrets, et limitation de débit. À ce niveau, ne partez pas “au feeling” : appliquez les briques de durcissement API (gestion des clés, throttling, scopes, journaux d’audit) décrites ici : API : sécuriser apikey, limiter le débit et renforcer la conformité. Et si vous utilisez un orchestrateur low-code type n8n pour prototyper (ou opérer) des webhooks, faites-le en connaissance de cause (auth, retry, stockage) : n8n : automatiser la gestion des commandes e‑commerce via webhooks.
Côté retries, évitez les extrêmes :
- retry immédiat en boucle (effet “DDoS involontaire”),
- ou pas de retry du tout (perte silencieuse).
Une stratégie simple et robuste : backoff exponentiel (ex. 1 min, 5 min, 30 min, 2 h…) avec un plafond (ex. 24 h) + une dead-letter queue (ou statut failed) pour traitement manuel.
Pour le debug et l’industrialisation, standardisez vos erreurs avec Problem Details (RFC 7807) afin que l’ERP/WMS/TMS puisse interpréter vos retours : RFC 7807 – Problem Details. Exemple : sur un 409 Conflict (doublon d’événement), renvoyez un JSON qui explicite la cause et l’event_id — et logguez-le côté émetteur pour arrêter de “réessayer dans le vide”.
Échanges de fichiers (CSV/EDI) : pipeline SFTP reproductible, staging SQL et reprise sur incident
Quand vous intégrez un WMS/TMS “old school” (ou un ERP verrouillé), le fichier reste la réalité. Le piège : traiter le CSV “en direct” dans PrestaShop ou via un script ad hoc lancé à la main. La version exploitable en prod est un pipeline : dépôt (SFTP), quarantaine (scan), validation (schéma + checks métier), ingestion (staging), puis application (écriture métier) avec logs et métriques.
Côté dépôt, imposez des conventions strictes : nommage avec horodatage et séquence (stock_warehouseA_20260727_0001.csv), checksum (SHA-256) et éventuellement fichier .ok d’acquittement pour éviter de consommer un fichier en cours d’écriture. En ingestion, chargez dans une table de staging (ex. import_stock_lines) puis validez en SQL (doublons, SKU inconnus, quantités négatives, entrepôt inexistant) avant d’impacter les tables PrestaShop. Oui, ça ajoute une étape, mais c’est ce qui rend les imports rejouables et auditables.
Quelques détails “terrain” qui réduisent drastiquement les incidents :
- imposez un encodage (UTF‑8) et un séparateur (
,ou;) documentés ; beaucoup de “bugs stock” sont des bugs de parsing ; - exigez un en-tête de colonnes et une version de format (même en CSV) ;
- si les volumes sont importants, acceptez des fichiers compressés (ex.
.gz) et traitez en streaming pour éviter l’explosion mémoire ; - archivez le fichier “source” (et le log associé) : c’est votre preuve en cas de litige (“l’entrepôt a envoyé quoi, exactement ?”).
Côté exécution, passez par une commande CLI (ou un cron) pour ne pas dépendre d’un backoffice et pour maîtriser la mémoire/timeout. Le cœur PrestaShop n’est pas conçu pour traiter des flux batch lourds via HTTP. Les bases CLI sont ici : Commandes CLI PrestaShop : liste, catégories et options d’aide. Et pour rendre ça opérable, vous devez journaliser par fichier : nombre de lignes, lignes rejetées, durée, identifiants corrélés. Sans ça, votre “portail client” devient une boîte noire.
Enfin, prévoyez explicitement la reprise sur incident : que se passe-t-il si vous ingérez deux fois le même fichier ? si un fichier est partiel ? si l’ERP renvoie une correction (delta négatif) ? Le design minimal est : (1) une table processed_files avec hash + statut, (2) un verrou par entrepôt pour éviter des traitements concurrents, (3) un mécanisme de “reprocess” contrôlé (rejouer un fichier précis). Sans ces garde-fous, le support finira par “vider la table” en prod.
Un bon test de maturité : êtes-vous capables, sans bricoler, de répondre à ces 3 questions en 10 minutes ?
- “Quel fichier a mis le stock de la référence X à 0 ?”
- “Combien de lignes ont été rejetées hier, et pourquoi ?”
- “Quel est le dernier stock validé par entrepôt (et son horodatage) ?”
Si non, la priorité n’est pas “ajouter un champ au portail”, mais rendre le pipeline exploitable.
Mise en production : cohérence des données, performance portail, supervision et anti-régressions
La cohérence “métier” est le vrai sujet d’un portail client intégré. Le stock en temps réel est rarement “vrai” : entre la réservation panier, la préparation WMS et la facturation ERP, vous êtes en éventuelle consistance. Documentez-le et choisissez où s’applique la règle : stock affiché = stock WMS ? stock ERP ? stock PrestaShop “disponible à la vente” ? Si vous avez multi-entrepôts, imposez des codes d’entrepôt immuables, et ne mappez pas ça à la volée dans des champs texte de modules.
Sur la performance, un portail client qui agrège ERP/WMS/TMS peut facilement dégrader la boutique si vous le greffez naïvement (appels synchrones, requêtes lourdes, jointures multiples). Séparez les charges : cache applicatif (Redis), jobs asynchrones, et endpoints dédiés “lecture” plutôt que surcharger les contrôleurs front. Une règle pragmatique côté UX : si une page “portail” dépend d’un SI externe, prévoyez systématiquement :
- un timeout court (ex. 1–2 s) pour ne pas bloquer le rendu,
- un fallback (cache, ou message “données temporairement indisponibles”),
- une trace corrélée (request id) pour diagnostiquer sans débat.
Pour l’approche performance sur gros volumes (catalogue, backoffice, Core Web Vitals), référence utile : PrestaShop performance : optimiser gros catalogues et Core Web Vitals.
Enfin, l’exploitation : si vous n’avez pas de logs propres, vous ne pourrez pas distinguer une panne ERP d’un bug module. Centralisez les erreurs (PHP, JS, SQL), tracez les appels externes (latence, code HTTP, timeouts), et mettez des alertes sur les files d’attente (backlog) et les taux d’échec. Sur PrestaShop, vous avez des bases méthodologiques ici : PrestaShop monitoring d’erreurs : logs PHP, MySQL, JavaScript et alertes e-mail. Et si vous mettez un WAF ou un reverse-proxy, vérifiez qu’il ne casse pas vos callbacks (webhooks) : WAF PrestaShop : réduire les faux positifs et sécuriser le checkout.
Avant go-live, une checklist qui évite 80% des incidents :
- Idempotence implémentée (API + webhooks + import fichiers) + tables de déduplication.
- Timeouts maîtrisés (connect/read) et retries exponentiels avec plafond.
- Contrats de schéma versionnés (payload webhook, format CSV/EDI) et tests de non-régression.
- Sécurité (rotation secrets, scopes, IP allowlist si possible, TLS strict).
- Runbook : mode dégradé si ERP/WMS/TMS indisponible (cache, message “données temporairement indisponibles”, re-synchronisation).
Complétez-la avec 5 contrôles “anti-surprise” très concrets, souvent décisifs en prod :
- Corrélation bout-en-bout : un identifiant unique (request/event id) traverse logs portail, worker, et appel externe.
- Capacité de rattrapage : un job “rebuild” (sur une période) pour recoller un historique si l’ERP a été indisponible 6 heures.
- Gestion des pics : si 10 000 événements d’expédition arrivent (soldes, Noël), la file absorbe et le portail reste stable.
- Qualité des données affichées : expliciter les dates (date d’expédition vs date de facturation vs date de livraison) pour réduire les tickets.
- Séparation des droits : un client connecté ne doit accéder qu’à ses documents (attention aux endpoints “par référence” mal protégés).
