Knowledge Base Guide

API Webservice PrestaShop : Intégration REST, client PHP & synchronisation ERP

Guide complet de l'API Webservice PrestaShop — opérations CRUD, bibliothèque PHP, authentification, filtrage, intégration ERP/POS et aperçu AdminAPI PS 9.

Qu’est-ce que le Webservice PrestaShop

Le Webservice PrestaShop est une API intégrée de type REST qui permet à des applications externes de lire et d’écrire les données de votre boutique via HTTP. Il expose des ressources — produits, commandes, clients, catégories, stocks et des dizaines d’autres — à travers une interface standardisée. Le format XML est utilisé par défaut ; le JSON est disponible à partir de PS 1.7+ grâce au paramètre &output_format=JSON.

Chaque version de PrestaShop depuis la 1.4 inclut le Webservice. Ce n’est pas un module — il fait partie du cœur du système. PS 1.6, 1.7, 8.x et 9.x le prennent tous en charge.

Le Webservice est le moyen officiel d’intégrer PrestaShop avec des systèmes externes. Les requêtes directes à la base de données contournent la validation, les hooks et la logique métier. L’API, non.

Cas d’utilisation courants : synchronisation des produits depuis un ERP ou un PIM, exportation des commandes vers des systèmes de fulfillment, maintien des stocks à jour sur plusieurs canaux, gestion des clients depuis un CRM et automatisation d’opérations en masse comme les mises à jour de prix.

Activation et configuration de l’API

Le Webservice est désactivé par défaut. Activez-le dans Paramètres avancés > Webservice, puis cliquez sur « Ajouter une nouvelle clé de webservice ». Pour chaque clé, vous définissez une description, un statut activé/désactivé et une matrice de permissions — une grille de ressources et de méthodes HTTP autorisées (GET, POST, PUT, DELETE, HEAD).

Créez des clés API séparées pour chaque intégration. Si votre ERP ne fait que lire les commandes et mettre à jour les stocks, ne lui donnez pas la permission de supprimer des produits. Principe du moindre privilège.

Le Webservice nécessite la réécriture d’URL. Apache gère cela via le fichier .htaccess dans /api/. Sous Nginx, ajoutez :

location /api/ {
    try_files $uri $uri/ /webservice/dispatcher.php?$args;
}

Authentification

HTTP Basic Auth — la clé API est placée dans le champ nom d’utilisateur, le mot de passe reste vide :

curl -u "YOUR_API_KEY:" https://your-store.com/api/products

Le HTTPS est obligatoire — les clés transitent dans chaque en-tête de requête. La restriction par IP est la mesure de sécurité la plus efficace pour les intégrations à IP fixe :

# .htaccess in /api/
<IfModule mod_authz_core.c>
    Require ip 10.0.0.5
    Require ip 192.168.1.0/24
</IfModule>

Changez vos clés tous les 6 à 12 mois. Stockez-les dans des variables d’environnement, jamais dans le code source.

Ressources disponibles

Appelez le point d’entrée racine pour voir tout ce à quoi votre clé a accès :

curl -u "KEY:" https://your-store.com/api/

Catalogue : products, combinations, categories, manufacturers, suppliers, product_features, product_feature_values, product_options (groupes d’attributs), product_option_values, tags, images

Ventes : orders, order_details (lignes de commande), order_states, order_histories (changements de statut), order_carriers (suivi), carts, cart_rules

Clients : customers, addresses, groups

Inventaire : stock_availables (ressource principale des stocks), warehouses, supply_orders

Configuration : carriers, countries, currencies, languages, taxes, zones, shops

Opérations CRUD

GET — Lecture des données

# List products (IDs only)
curl -u "KEY:" https://your-store.com/api/products

# Full details
curl -u "KEY:" "https://your-store.com/api/products?display=full"

# Selected fields only (faster)
curl -u "KEY:" "https://your-store.com/api/products?display=[id,name,price,référence]"

# Single product in JSON
curl -u "KEY:" "https://your-store.com/api/products/42?output_format=JSON"

POST — Création

Récupérez le schéma XML vierge, remplissez les champs obligatoires, puis renvoyez-le par POST :

curl -u "KEY:" -X POST -H "Content-Type: application/xml" \
  -d '<prestashop xmlns:xlink="http://www.w3.org/1999/xlink">
  <product>
    <id_category_default>2</id_category_default>
    <id_tax_rules_group>1</id_tax_rules_group>
    <active>1</active><state>1</state>
    <price>29.99</price>
    <name><language id="1">My Product</language></name>
    <link_rewrite><language id="1">my-product</language></link_rewrite>
    <description_short><language id="1">Short desc</language></description_short>
    <associations><categories><category><id>2</id></category></categories></associations>
  </product>
</prestashop>' https://your-store.com/api/products

PUT — Mise à jour

Récupérez la ressource actuelle avec GET, modifiez les champs, puis renvoyez l’intégralité du XML avec PUT. Les mises à jour partielles ne sont pas prises en charge.

curl -u "KEY:" https://your-store.com/api/products/42 -o product.xml
# Edit product.xml, then:
curl -u "KEY:" -X PUT -H "Content-Type: application/xml" \
     -d @product.xml https://your-store.com/api/products/42
Faites toujours un GET avant un PUT. Si vous construisez le XML de zéro et oubliez un champ obligatoire, l’API risque de l’effacer ou de rejeter la requête.

DELETE

curl -u "KEY:" -X DELETE https://your-store.com/api/products/42
# Multiple: DELETE "https://your-store.com/api/products/?id=[42|43|44]"

DELETE est irréversible — pas de corbeille, pas d’annulation. Préférez définir active=0 en production.

Filtrage, tri et pagination

# Exact match
?filter[référence]=ABC-123

# Range (price 10-50)
?filter[price]=[10,50]

# Date range
?filter[date_upd]=[2025-01-01,2025-12-31]

# Starts with (% URL-encoded as %25)
?filter[name]=[Nike]%25

# Combined
?filter[active]=1&filter[id_category_default]=5&display=[id,name,price]

# Sorting
?sort=[price_ASC]    ?sort=[date_upd_DESC]

# Pagination (offset,count)
?limit=50         # first 50
?limit=50,50      # results 51-100

Découverte du schéma — deux modes pour inspecter la structure d’une ressource sans documentation :

?schema=blank     # Empty XML template with all fields
?schema=synopsis  # Field types, required flags, max lengths, read-only markers

Le synopsis vous indique exactement quels champs sont obligatoires et quel format ils attendent. Consultez-le toujours avant de développer votre code d’intégration.

Travailler avec les images

Les images de produits sont envoyées via un formulaire multipart vers un point d’entrée dédié :

# Upload
curl -u "KEY:" -X POST -F "image=@photo.jpg;type=image/jpeg" \
     "https://your-store.com/api/images/products/42"

# List images for product
curl -u "KEY:" "https://your-store.com/api/images/products/42"

# Get specific image / image type
curl -u "KEY:" "https://your-store.com/api/images/products/42/15/large_default"

# Delete
curl -u "KEY:" -X DELETE "https://your-store.com/api/images/products/42/15"

Envoi en PHP :

$ch = curl_init("$shopUrl/api/images/products/$productId");
curl_setopt($ch, CURLOPT_USERPWD, "$apiKey:");
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_POSTFIELDS, [
    'image' => new CURLFile($imagePath, mime_content_type($imagePath))
]);
$response = curl_exec($ch);
Optimisez les images avant de les envoyer. Redimensionnez-les à 2048px maximum et compressez-les — des photos de 5 Mo prises avec un reflex numérique ralentiront votre boutique.

Déclinaisons et attributs

Les déclinaisons sont la partie la plus délicate de l’API. Le modèle de données comporte trois couches :

  • Product Option (groupe d’attributs) — Taille, Couleur, Matière
  • Product Option Value — S, M, L, Rouge, Bleu
  • Combination — un ensemble de valeurs pour un produit (Taille:M + Couleur:Rouge)

Créez dans l’ordre : groupe d’attributs → valeurs → déclinaison :

# Create combination linking to existing attribute values
curl -u "KEY:" -X POST -H "Content-Type: application/xml" \
  -d '<prestashop><combination>
    <id_product>42</id_product>
    <référence>PROD-42-M-RED</référence>
    <price>5.00</price>
    <minimal_quantity>1</minimal_quantity>
    <associations><product_option_values>
      <product_option_value><id>2</id></product_option_value>
      <product_option_value><id>7</id></product_option_value>
    </product_option_values></associations>
  </combination></prestashop>' "https://your-store.com/api/combinations"

Le champ price d’une déclinaison est un impact sur le prix ajouté au prix de base du produit, et non le prix final.

Stock par déclinaison

Le stock est géré via stock_availables, et non via la déclinaison elle-même :

# Find stock record
curl -u "KEY:" "https://your-store.com/api/stock_availables?filter[id_product]=42&filter[id_product_attribute]=15&display=full"

# Update (GET first, modify quantity, PUT back)
curl -u "KEY:" -X PUT -H "Content-Type: application/xml" \
  -d '<prestashop><stock_available>
    <id>89</id><id_product>42</id_product>
    <id_product_attribute>15</id_product_attribute>
    <quantity>100</quantity>
  </stock_available></prestashop>' "https://your-store.com/api/stock_availables/89"
L’enregistrement de stock au niveau du produit (id_product_attribute=0) contient la somme de toutes les déclinaisons. Mettez à jour le stock au niveau de la déclinaison et PrestaShop recalcule automatiquement le total.

Commandes et panier

# Recent orders
curl -u "KEY:" "https://your-store.com/api/orders?display=[id,référence,total_paid,current_state,date_add]&sort=[id_DESC]&limit=20"

# Full order with line items
curl -u "KEY:" "https://your-store.com/api/orders/1234?display=full"
curl -u "KEY:" "https://your-store.com/api/order_details?filter[id_order]=1234&display=full"

Mise à jour du statut de commande

Créez un nouvel enregistrement order_history — cela déclenche le changement de statut et envoie l’e-mail au client :

curl -u "KEY:" -X POST -H "Content-Type: application/xml" \
  -d '<prestashop><order_history>
    <id_order>1234</id_order>
    <id_order_state>4</id_order_state>
  </order_history></prestashop>' "https://your-store.com/api/order_histories"

Identifiants de statut par défaut : 1=En attente de paiement, 2=Paiement accepté, 3=En cours de traitement, 4=Expédié, 5=Livré, 6=Annulé, 7=Remboursé. Ces identifiants varient selon l’installation — interrogez order_states pour obtenir la liste réelle de votre boutique.

Numéros de suivi : Récupérez l’enregistrement order_carriers de la commande avec GET, ajoutez le tracking_number, puis renvoyez-le avec PUT.

Créer des commandes via l’API est techniquement possible mais déconseillé. La création d’une commande implique la validation du panier, le calcul des taxes, le traitement du paiement, la déduction du stock et l’exécution des hooks — l’API contourne la plupart de ces étapes. Pour les imports depuis une marketplace, créez un panier via l’API et traitez-le à travers un front controller personnalisé.

Bibliothèque client PHP

composer require prestashop/prestashop-webservice-lib

Ou téléchargez le fichier unique depuis GitHub.

$ws = new PrestaShopWebservice('https://your-store.com', 'API_KEY', false);

// List products
$xml = $ws->get(['resource' => 'products', 'display' => 'full', 'limit' => 10]);
foreach ($xml->products->product as $p) {
    echo $p->id . ' - ' . $p->name->language . "\n";
}

// Create product from blank schema
$blank = $ws->get(['url' => 'https://your-store.com/api/products?schema=blank']);
$blank->product->active = 1;
$blank->product->price = 29.99;
$blank->product->name->language[0] = 'New Product';
$blank->product->name->language[0]['id'] = 1;
$blank->product->link_rewrite->language[0] = 'new-product';
$blank->product->link_rewrite->language[0]['id'] = 1;
$blank->product->id_category_default = 2;
$result = $ws->add(['resource' => 'products', 'postXml' => $blank->asXML()]);

// Update stock
function updateStock($ws, int $pid, int $qty, int $combo = 0): void {
    $xml = $ws->get([
        'resource' => 'stock_availables',
        'filter[id_product]' => $pid,
        'filter[id_product_attribute]' => $combo,
        'display' => 'full'
    ]);
    $sid = (int)$xml->stock_availables->stock_available->id;
    $sxml = $ws->get(['resource' => 'stock_availables', 'id' => $sid]);
    $sxml->stock_available->quantity = $qty;
    $ws->edit(['resource' => 'stock_availables', 'id' => $sid, 'putXml' => $sxml->asXML()]);
}

// Export orders since date
$xml = $ws->get([
    'resource' => 'orders',
    'display' => '[id,référence,total_paid,current_state,date_add]',
    'filter[date_add]' => '[2025-06-01,9999-12-31]',
    'sort' => '[date_add_DESC]', 'limit' => 500
]);

Schémas d’intégration

Intégration ERP

Le scénario le plus courant. Les produits, les prix et les stocks circulent de l’ERP vers PrestaShop ; les commandes et les données clients circulent en sens inverse. Bonnes pratiques : utilisez des codes de référence (SKU/EAN) comme identifiants partagés, planifiez la synchronisation des stocks toutes les 15 minutes et celle des produits toutes les heures, suivez le dernier horodatage de synchronisation avec filter[date_upd], décidez de la résolution des conflits en amont (l’ERP l’emporte généralement) et journalisez tout.

Entrepôt et TPV

Un WMS suit un cycle : réception des marchandises → mise à jour du stock via l’API ; récupération des commandes → expédition → mise à jour du suivi via l’API. L’intégration d’un terminal de point de vente (TPV) est similaire — le stock doit se synchroniser en quasi-temps réel afin que les achats en magasin réduisent immédiatement la disponibilité en ligne.

Synchronisation avec les marketplaces

Les intégrations Allegro, Amazon et eBay nécessitent l’exportation des produits avec images, l’importation des commandes (via un panier + un traitement personnalisé plutôt qu’un POST direct de commande) et une synchronisation bidirectionnelle des stocks pour éviter les surventes.

Comptabilité

Lecture seule : récupération des commandes, factures et avoirs selon un calendrier quotidien ou hebdomadaire. Seules les permissions GET sont nécessaires.

Changements de l’API dans PrestaShop 9

Le Webservice historique continue de fonctionner dans PS 9 — il n’est pas déprécié. Les intégrations existantes fonctionnent après la mise à jour.

AdminAPI — Nouvelle API basée sur Symfony

PS 9 introduit une nouvelle AdminAPI en complément du Webservice historique. Différences principales :

  • Authentification : OAuth2 avec client credentials (vs. clé API en Basic Auth)
  • Format : JSON uniquement (vs. XML par défaut)
  • Architecture : Symfony / API Platform avec documentation OpenAPI/Swagger à /admin-api/docs
  • Couverture : En progression — ne couvre pas encore toutes les ressources du Webservice historique
# Get OAuth2 token
curl -X POST https://your-store.com/admin-api/access_token \
     -d "grant_type=client_credentials&client_id=ID&client_secret=SECRET"

# Use bearer token
curl -H "Authorization: Bearer eyJ0eXAi..." https://your-store.com/admin-api/products

Les jetons expirent (par défaut : 1 heure) — gérez le rafraîchissement dans votre intégration. Les scopes (product_read, product_write, order_read) contrôlent l’accès de manière granulaire. Créez les clients API dans Paramètres avancés > AdminAPI.

Utilisez l’AdminAPI pour les nouvelles intégrations PS 9+. Utilisez le Webservice historique pour une couverture large des ressources ou une compatibilité ascendante avec PS 1.6/1.7/8.x. Vous pouvez utiliser les deux dans la même intégration.

Problèmes courants

401 Unauthorized : Clé incorrecte (vérifiez les espaces), clé désactivée, Webservice désactivé, ou clé envoyée en paramètre d’URL au lieu de l’en-tête Basic Auth.

403 Forbidden : La clé n’a pas la permission pour la ressource ou la méthode HTTP demandée. Vérifiez la matrice de permissions.

404 Not Found : La ressource n’existe pas ou la réécriture d’URL est cassée. Test : curl -u "KEY:" "https://store.com/webservice/dispatcher.php?url=products" — si cela fonctionne mais que /api/products ne fonctionne pas, corrigez les règles de réécriture.

Erreurs d’analyse XML : Utilisez CDATA pour les caractères spéciaux (<![CDATA[HTML & more]]>), encadrez toujours avec l’élément racine <prestashop>, et envoyez en UTF-8 avec l’en-tête Content-Type adéquat.

Opérations en masse lentes : L’API traite une requête à la fois. Pour plus de 10 000 éléments :

  • Ne demandez que les champs nécessaires avec display — évitez display=full sur les gros catalogues
  • Filtrez par date_upd pour ne synchroniser que les enregistrements modifiés
  • Réutilisez les handles curl pour maintenir des connexions persistantes
  • Pour les imports initiaux de plus de 50 000 articles, envisagez un accès direct à la base de données avec vidage du cache
// Efficient bulk stock update — reuse handle
$ch = curl_init();
curl_setopt($ch, CURLOPT_USERPWD, "$apiKey:");
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_HTTPHEADER, ['Content-Type: application/xml']);
foreach ($updates as $stockId => $qty) {
    curl_setopt($ch, CURLOPT_URL, "$url/api/stock_availables/$stockId");
    curl_setopt($ch, CURLOPT_CUSTOMREQUEST, 'PUT');
    curl_setopt($ch, CURLOPT_POSTFIELDS,
        "<prestashop><stock_available><id>$stockId</id><quantity>$qty</quantity></stock_available></prestashop>");
    curl_exec($ch);
}
curl_close($ch);

Bonnes pratiques de sécurité

  • Une clé par intégration — révoquez-en une sans casser les autres
  • Permissions minimales — la synchronisation de stock n’a pas besoin du DELETE sur les produits
  • Toujours en HTTPS — les clés en HTTP sont visibles par les outils d’écoute réseau
  • Restriction par IP — la mesure individuelle la plus efficace pour les intégrations serveur à serveur
  • Rotation des clés — tous les 6 à 12 mois
  • Variables d’environnement — ne commitez jamais de clés dans le contrôle de version
  • Limitation du débit — l’API n’en intègre aucune nativement ; ajoutez-la au niveau du serveur web
# Nginx rate limiting
limit_req_zone $binary_remote_addr zone=api:10m rate=30r/s;
location /api/ {
    limit_req zone=api burst=50 nodelay;
    try_files $uri $uri/ /webservice/dispatcher.php?$args;
}

Journalisation d’audit : PrestaShop ne dispose pas de journalisation API intégrée. Analysez les logs d’accès du serveur web pour les requêtes vers /api/, ou surchargez WebserviceRequest pour enregistrer l’horodatage, l’IP, la ressource, la méthode et le code de réponse. Indispensable pour la conformité RGPD/PCI lorsque des données clients sont accédées.

Alternatives au Webservice

Accès direct à la base de données

Des ordres de grandeur plus rapide pour les opérations en masse, mais contourne la validation, les hooks et l’invalidation du cache. Approprié pour les imports ponctuels, les rapports en lecture seule et les corrections d’urgence. Inapproprié pour la synchronisation continue ou tout ce qui touche aux commandes ou aux paiements. Videz toujours les caches après des modifications directes en base.

Hooks de modules pour la synchronisation en temps réel

Au lieu d’interroger l’API régulièrement, poussez les données via des hooks lorsque des événements se produisent :

public function hookActionProductUpdate($params) {
    $product = $params['product'];
    $payload = json_encode([
        'id' => $product->id, 'référence' => $product->référence,
        'price' => $product->price,
        'quantity' => StockAvailable::getQuantityAvailableByProduct($product->id),
    ]);
    $ch = curl_init('https://erp.example.com/webhook/product-update');
    curl_setopt($ch, CURLOPT_POST, true);
    curl_setopt($ch, CURLOPT_POSTFIELDS, $payload);
    curl_setopt($ch, CURLOPT_HTTPHEADER, ['Content-Type: application/json']);
    curl_setopt($ch, CURLOPT_TIMEOUT, 5);
    curl_exec($ch); curl_close($ch);
}

Points d’entrée personnalisés via module

Pour les opérations que le Webservice gère mal, construisez une API personnalisée sous forme de front controller de module. Contrôle total sur le format, l’authentification et la logique métier — traitez les opérations en masse en une seule requête tout en utilisant les classes natives de PrestaShop pour la validation.

Choisir la bonne approche

ScénarioMeilleure approche
Intégration ERP/WMS standardAPI Webservice
Nouvelle intégration PS 9+AdminAPI (OAuth2, JSON)
Import en masse de 50 000+ produitsAccès direct à la BDD + vidage du cache
Synchronisation en temps réelHooks de modules (webhook push)
Logique métier personnaliséePoint d’entrée de module personnalisé
Rapports en lecture seuleRequêtes directes à la BDD

Le Webservice PrestaShop est stable depuis plus d’une décennie. Pour PS 9+, l’AdminAPI offre une alternative moderne. Choisissez le bon outil pour chaque besoin, implémentez-le avec la sécurité et la gestion des erreurs dès le départ, et testez toujours sur la version spécifique de PrestaShop que vous ciblez.

More guides available

Browse our knowledge base for more practical PrestaShop tutorials, or reach out if you need help.

Loading...
Back to top