Table des matières :
- Webservice PrestaShop : REST historique, contraintes et place face à l’Admin API
- Activation, authentification et durcissement minimal (HTTPS, droits, filtrage réseau)
- GET : explorer les ressources, schémas, filtres, pagination et champs
- POST/PUT : créer et modifier proprement (XML, validation, associations, stocks)
- DELETE et intégrité : ce que vous cassez réellement, stratégies de suppression
- Industrialiser un CRUD : performances, reprise sur erreur, observabilité, CI
- Ressources développeur et checklists (libs, outils, docs, pièges récurrents)
Sur PrestaShop 8.1 → 9.1 (PHP 8.2/8.3), l’API Webservice PrestaShop reste l’interface “legacy” la plus utilisée pour intégrer un ERP, un PIM, un WMS, ou automatiser des imports/exports. Elle est REST-like (endpoints ressources, verbes HTTP), mais son implémentation est directement branchée sur ObjectModel et ses règles (champs requis, validations, associations), ce qui impose une méthode de travail différente d’une API modernisée.
Pré-requis implicites : accès Back Office, capacité à capturer/rejouer des requêtes HTTP (curl/Postman), et un environnement de pré-production. Si vous touchez au catalogue/commandes en prod, faites au minimum un dump DB + un snapshot FS.
Deux points de cadrage qui évitent 80% des surprises :
- Le Webservice est un “transport”, pas un moteur métier : il reflète le modèle interne PrestaShop (et ses contraintes), il ne le simplifie pas.
- Votre intégration doit conserver une “source de vérité” (ERP/PIM/MDM, ou PrestaShop selon les cas) et gérer le mapping (IDs, références, états) de manière explicite. Sans table de correspondance (ex.
external_id ↔ id_product), une synchro CRUD finit vite en bricolage.
Webservice PrestaShop : REST historique, contraintes et place face à l’Admin API
Le Webservice expose un endpoint unique, généralement https://boutique.tld/api/, puis des sous-ressources : products, customers, orders, stock_availables, etc. Le contrat est proche d’un CRUD pur : GET pour lire, POST pour créer, PUT pour remplacer, DELETE pour supprimer. Dans les faits, le “remplacement” via PUT est souvent le point qui surprend : l’API est très stricte sur les champs requis, et le “PATCH” (mise à jour partielle) n’est pas nativement disponible.
Ce que ça implique concrètement pour une intégration “terrain” (ERP/PIM/WMS) :
- Faible tolérance aux payloads incomplets : un champ requis manquant peut produire une erreur côté Webservice, parfois peu explicite.
- Risque de “perte de données” lors d’un PUT si vous renvoyez un XML partiel : vous pouvez écraser des champs non maîtrisés (ex. associations, valeurs multilingues, catégories…).
- Couplage fort au modèle PrestaShop : si un module ajoute des validations ou modifie des règles (ou si vous changez de version), votre pipeline doit être testé.
En 2026, il faut aussi être clair : PrestaShop pousse de plus en plus une Admin API moderne (scopes, ergonomie OpenAPI/Swagger, logique Symfony) et la stratégie headless se construit plutôt autour de ces briques. Mais tant que tout l’écosystème (modules, connecteurs tiers, scripts internes) dépend du Webservice, vous allez devoir le maîtriser. Pour cadrer le périmètre, l’article PrestaShop Admin API : sécuriser secret et scopes par client est un bon complément : PrestaShop Admin API : sécuriser secret et scopes par client
Le bon réflexe architectural : ne pas faire porter au Webservice des opérations métier complexes (calculs de prix, règles de stock avancées, composition de bundles, etc.). Le Webservice est une interface de synchronisation. Si vous avez besoin d’orchestration (files, retries, dead-letter, idempotence), construisez une couche d’intégration (worker) — voir Intégration ERP e‑commerce : architecture API, webhooks et files RabbitMQ : Intégration ERP e‑commerce : architecture API, webhooks et files RabbitMQ
Mini-scenario réaliste (souvent vu en France/UE sur des SI distribués) : un PIM alimente des fiches produit, un ERP pilote les prix/TVA, et un WMS pilote les stocks. Dans ce cas, le Webservice sert d’interface de “projection” vers PrestaShop, mais vous devez décider où vivent les arbitrages (ex. priorité des updates, résolution des conflits, fenêtres de gel pendant un inventaire).
Activation, authentification et durcissement minimal (HTTPS, droits, filtrage réseau)
Côté Back Office : Paramètres avancés → Webservice. Activez le Webservice, générez une clé, puis attribuez des droits par ressource (lecture/écriture/modification/suppression). Ne donnez jamais “toutes les permissions” par défaut : segmentez par client (ERP, PIM, script d’import) et créez une clé par usage. En multi-boutique, la gestion fine devient vite pénible : documentez quelle clé pointe vers quel périmètre (shops, langues, devises).
Une pratique simple qui tient bien en audit : matrice “clé → ressources → droits” (à garder dans votre doc d’exploitation). Exemple minimal :
| Usage | Ressources | Droits recommandés |
|---|---|---|
| ERP (commandes) | orders, order_histories, customers (lecture), addresses (lecture) |
lecture + ajout (selon flux), éviter DELETE |
| PIM (catalogue) | products, categories, manufacturers, images |
lecture/ajout/modif, DELETE uniquement en préprod |
| WMS (stock) | stock_availables |
lecture/modif, pas besoin d’accès catalogue complet |
L’authentification est basée sur HTTP Basic (la clé d’API comme identifiant, mot de passe vide selon les clients) ou sur le paramètre ?ws_key=... (à éviter, car vous allez la leak dans des logs, des referers ou des screenshots). Le point non négociable : TLS. Le standard le dit explicitement. RFC 7617 : “The Basic authentication scheme is not considered to be a secure method of user authentication unless used in conjunction with some external secure system such as TLS …” (RFC 7617, section 4).
Durcissement concret, côté infra :
- Forcez HTTPS (redirect 301 + HSTS), et bloquez HTTP en frontal. Pour le volet configuration serveur et cache/opcache, adaptez les patterns de déploiement (FPM, Nginx) décrits ici : Symfony 7 – déploiement PHP‑FPM/Nginx/cache/opcache
- Ajoutez une allowlist IP (VPN / IP ERP / NAT iPaaS) au niveau reverse-proxy/WAF, parce que l’auth Basic ne vous protège pas d’un bruteforce à faible coût.
- Mettez du rate limiting (par clé et/ou par IP) et des logs structurés. Une API sans limite devient un DoS “fonctionnel” en quelques lignes.
Checklist rapide “prod-ready” (souvent oubliée) :
- Rotation/expiration : planifiez la rotation des clés (même si PrestaShop ne l’impose pas), et prévoyez une période de recouvrement.
- Séparation des environnements : clés différentes entre préprod et prod, et endpoints explicitement distincts (évite les erreurs humaines).
- Journalisation côté reverse-proxy : ne logguez pas d’URL contenant des secrets, et évitez
ws_keyen query string. - Politique de sécurité API : en complément, le projet OWASP API Security est une bonne base de menaces/contrôles : OWASP API Security
GET : explorer les ressources, schémas, filtres, pagination et champs
Le Webservice se découvre “par introspection”. Premier call utile : lister les ressources disponibles.
curl -u 'VOTRE_CLE_API:' 'https://boutique.tld/api/'
Vous obtenez un XML (format de référence). Pour une ressource donnée, deux endpoints sont indispensables pour comprendre ce que PrestaShop attend :
?schema=blank: squelette des champs (utile pour POST)?schema=synopsis: description des champs (utile pour savoir ce qui est requis)
curl -u 'VOTRE_CLE_API:' \
'https://boutique.tld/api/products?schema=blank'
Pour lire des données en production sans faire exploser la DB, jouez avec :
display=(fullest verbeux, préférezdisplay=[id,name,price]quand possible)limit=offset,countpour paginersort=[field]_ASC|DESCfilter[field]=valueet surtout les filtres de dates (date_upd) pour l’incrémental
curl -u 'VOTRE_CLE_API:' \
'https://boutique.tld/api/products?display=[id,reference,price,date_upd]&sort=[date_upd]_DESC&limit=0,50'
Sur des catalogues > 50k produits, le coût du display=full est rarement acceptable (XML massif, latence, CPU PHP, mémoire). La lecture incrémentale “à la date” est le pattern le plus stable.
Deux astuces très utiles en opération :
- Filtrer par intervalle (quand supporté) pour “découper” un rattrapage : typiquement vous rejouez par tranches temporelles (ex. après un incident de connecteur).
- Limiter le nombre de champs non seulement pour la taille de réponse, mais aussi pour réduire le travail de sérialisation PHP et la pression mémoire.
Exemple de lecture incrémentale (schéma courant) : vous stockez un last_sync_date_upd, puis vous récupérez les produits modifiés depuis cette date. Attention : selon votre stratégie, vous pouvez inclure une marge (ex. -5 minutes) pour éviter les trous en cas d’horodatage ou de traitements concurrents.
Enfin, côté erreurs GET, apprenez à reconnaître le format d’erreur PrestaShop (souvent un XML avec une section errors). Gardez une règle simple : logguer le body d’erreur (sans données sensibles) est souvent la seule manière d’identifier le champ fautif.
POST/PUT : créer et modifier proprement (XML, validation, associations, stocks)
Le POST démarre presque toujours par un schema=blank, puis remplissage minimal. Exemple typique : création d’un produit (très simplifié) ; en réel, vous devrez aussi gérer catégories, taxes, images, déclinaisons.
# 1) Récupérer le template
curl -u 'VOTRE_CLE_API:' \
'https://boutique.tld/api/products?schema=blank' > product.xml
Ensuite, modifiez product.xml et POSTez-le :
curl -u 'VOTRE_CLE_API:' \
-X POST \
-H 'Content-Type: application/xml' \
--data-binary @product.xml \
'https://boutique.tld/api/products'
Le piège : ce que vous considérez comme “un produit” côté PIM n’a rien à voir avec l’entité PrestaShop côté ObjectModel. Vous devrez alimenter correctement les champs multilingues (name, link_rewrite), la disponibilité (active, available_for_order), la TVA (id_tax_rules_group), et les associations (catégories, features, images). Si vous créez des déclinaisons, vous sortez du CRUD naïf : il faut gérer combinations, product_option_values, puis synchroniser stock_availables (stock par combinaison, par shop).
Checklist “création produit” (pragmatique, pour éviter des allers-retours) :
- Identité :
reference(si vous l’utilisez comme clé métier),name+link_rewritedans toutes les langues ciblées - Publication :
active,state/visibilité (selon version/config), et une catégorie par défaut cohérente - Fiscalité :
id_tax_rules_groupaligné avec votre ERP (sinon écarts prix TTC/HT) - Associations : catégories, marque/fournisseur si utilisés, features si vous filtrez le catalogue
- Stock : stratégie claire (stock global vs par déclinaison), et mise à jour via
stock_availablessi c’est votre source de vérité opérationnelle
Dépendances typiques (utile pour ordonner un import) :
| Entité cible | Dépend de | Commentaire |
|---|---|---|
products |
categories, tax_rules_groups, languages |
Les IDs doivent exister avant POST produit |
combinations |
products, product_options, product_option_values |
Souvent la partie la plus coûteuse en mapping |
images |
products |
Upload séparé (flux binaire), puis association |
Cas fréquent : vous importez un nouveau catalogue depuis un PIM. Si vous tentez de créer des produits avant d’avoir créé/aligné vos catégories et règles de taxes, vous allez “réparer” ensuite via PUT, ce qui augmente les coûts (CPU, temps, risques). En pipeline, mieux vaut précharger les référentiels (catégories, taxes, attributs) puis traiter les produits.
Pour les mises à jour, le PUT a une sémantique de remplacement. Le standard HTTP le rappelle : “The PUT method requests that the state of the target resource be created or replaced with the state defined by the representation enclosed in the request message payload.” (RFC 9110, HTTP Semantics). Dans PrestaShop Webservice, ça se traduit par : vous devez généralement renvoyer l’entité complète (ou au moins un ensemble de champs cohérent). La stratégie robuste en prod est donc :
GET /api/resource/{id}- Modifiez uniquement ce que vous maîtrisez
PUT /api/resource/{id}avec le XML complet
C’est verbeux, mais c’est le seul moyen de ne pas casser des champs calculés ou des associations.
Astuce d’industrialisation : lorsque vous faites un GET→PUT, conservez le XML original et appliquez un “patch” applicatif (mapping) en gardant :
- les champs que vous ne gérez pas (vous les réinjectez tels quels),
- les champs que vous gérez (vous les remplacez),
- et surtout une normalisation (ex. décimales, encodage, trimming) pour éviter des mises à jour inutiles.
DELETE et intégrité : ce que vous cassez réellement, stratégies de suppression
DELETE paraît simple jusqu’à ce que vous touchiez à des ressources “liées” (produits ↔ déclinaisons ↔ stocks, clients ↔ adresses ↔ commandes). Le Webservice vous laisse supprimer, mais ne vous protège pas d’un modèle de données que vous ne contrôlez pas. Attendez-vous à des 500 “génériques” si vous cassez une contrainte applicative, même si la DB n’a pas de contrainte FK stricte.
En pratique, supprimez rarement en dur. Pour le catalogue, préférez souvent :
active=0(désactivation)- suppression des associations (catégories, prix spécifiques)
- gestion de l’état de stock (mettre à 0 + désactiver la vente)
C’est plus proche d’un “soft delete” et ça préserve la traçabilité. Si votre but est SEO (retirer un produit), vous devez aussi piloter le front : redirections, statut “discontinued”, pages catégorie. Le Webservice seul n’est pas l’outil SEO ; il alimente des données.
Deux stratégies opérationnelles (à choisir selon votre métier) :
- “Désactivation + déréférencement” : bon compromis pour garder l’historique, éviter les trous en back-office et limiter les risques sur les commandes passées.
- “Suppression stricte” (staging / jeux de test / synchro miroir) : nécessite de définir un ordre de suppression (ex. déclinaisons → stocks → produit) et de gérer les erreurs de dépendance.
Si vous devez vraiment DELETE (données test, staging, sync stricte), implémentez une logique d’idempotence côté client. RFC 9110 définit l’idempotence : “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.” En théorie PUT/DELETE sont idempotents ; en pratique, sur PrestaShop Webservice, vous devez traiter un second DELETE comme “déjà supprimé” (404) sans crasher votre pipeline.
Petit garde-fou : ne jamais déclencher un DELETE sur prod sans dry-run. Exemple concret : votre ERP envoie une liste d’articles “non présents” (erreur de filtre, mauvais scope multi-boutique) et votre connecteur interprète ça comme “à supprimer”. Un mode “simulation” qui journalise les actions, sans les exécuter, évite des catastrophes.
Industrialiser un CRUD : performances, reprise sur erreur, observabilité, CI
Un connecteur sérieux ne fait pas “curl en boucle” depuis un cron opaque. Vous devez gérer : timeouts, retries exponentiels, backoff, découpage en lots, et une file de tâches persistée (DB, queue). Le Webservice peut devenir le goulot, surtout si vous faites des display=full en lecture et des PUT volumineux en écriture.
Le pattern qui tient la charge : pipeline API-first avec journalisation de chaque mutation (request id, ressource, payload hash, statut, latence, code HTTP). Ça permet de rejouer un lot, d’identifier les erreurs récurrentes (validation, champ manquant, collision de référence), et de prouver ce qui a été envoyé. Pour une approche structurée d’import catalogue, recoupez avec Import catalogue PrestaShop : pipeline API-first automatisé et supervisé : Import catalogue PrestaShop : pipeline API-first automatisé et supervisé
Exemple de “contrat d’exécution” côté connecteur (simple, mais très efficace) :
- Timeouts : connect court (ex. 2–5s), read plus long (ex. 30–60s) selon payload
- Retries :
- 429/503/504 : retry avec backoff exponentiel + jitter
- 400 (validation) : pas de retry automatique, c’est un bug de mapping
- 401/403 : stop immédiat, alerte (clé invalide / droits)
- Batching : découper les imports (ex. 50–200 items) pour limiter l’effet blast radius
- Reprise : checkpoint (dernier
date_upd, dernier ID, ou curseur interne) + rejouabilité
Côté observabilité : corrélez logs Nginx/Apache + logs applicatifs + slow query log. Si vos endpoints Webservice déclenchent des requêtes non indexées, vous allez le voir dans le slow log. Pour la méthode, voir PrestaShop MySQL : analyser slow query log et optimiser index : PrestaShop MySQL : analyser slow query log et optimiser index et, plus généralement, Sécurité MySQL : pare-feu, TLS, privilèges minimaux et audit : Sécurité MySQL : pare-feu, TLS, privilèges minimaux et audit
Point souvent négligé : mesurer. Même sans stack lourde, vous pouvez a minima suivre :
- taux d’erreur par ressource (products vs stocks vs orders),
- latence médiane et p95,
- volume (nb de PUT/POST/jour),
- top des codes erreurs métier (champ requis manquant, association invalide…).
Enfin, testez en CI : validez que votre XML reste compatible après mise à jour de PrestaShop/module (champs requis qui changent, comportement multi-boutique). La génération d’environnements éphémères est un accélérateur net pour ce type d’intégration : PrestaShop CI/CD : générer des demos à la demande en minutes
Ressources développeur et checklists (libs, outils, docs, pièges récurrents)
Pour coder côté PHP, la librairie historique est PrestaShop-webservice-lib (SOAP-like client minimaliste mais pratique pour démarrer) : PrestaShop-webservice-lib (GitHub). Pour des besoins sérieux (timeouts, retries, circuit breaker), vous finirez souvent sur un client HTTP type Guzzle/Symfony HttpClient + votre propre couche de sérialisation XML.
Documentation et références utiles (externes) :
- DevDocs PrestaShop (Webservice + architecture)
- RFC 7617 (HTTP Basic Auth)
- RFC 9110 (HTTP Semantics : PUT, idempotence, etc.)
Pièges récurrents à mettre dans votre checklist :
- Clé exposée (URL avec
ws_key, logs, outils de monitoring). Ne mettez jamais la clé dans un repo ni dans une URL partagée. - Multi-langue : oublis de
link_rewrite/namepar langue → erreurs 400/500 selon validation. - Stocks : confusion entre
products.quantity(plus vraiment la source de vérité) etstock_availables(ce que beaucoup de shops utilisent réellement). - Taille payload : PUT “full entity” trop gros → timeouts, memory limit, et régressions perf. Découpez.
- Sécurité réseau : sans allowlist IP + rate limit, vous aurez tôt ou tard un incident. Pour l’approche globale API/modules/WAF/SBOM, voir : PrestaShop : sécuriser APIs et modules avec SBOM/WAF/CI/CD
- Conflits de mises à jour : deux pipelines qui modifient le même objet (ex. prix vs descriptions) via PUT peuvent s’écraser. Si vous ne pouvez pas séparer par ressource, imposez un orchestrateur (file unique) ou des fenêtres de traitement.
- Mapping des IDs : ne faites pas confiance aux “références” comme identifiant universel sans règle stricte (unicité, format, gestion des réassignations). Conservez un mapping durable.
Si votre objectif final est une intégration ERP/PIM propre, le Webservice est souvent juste le tuyau. Le vrai travail est la modélisation, la gestion d’erreurs, et la gouvernance des données (source de vérité). Sur ce point, l’article Intégration API PrestaShop : créer un connecteur ERP sur mesure sert de fil conducteur : Intégration API PrestaShop : créer un connecteur ERP sur mesure




