Knowledge Base Guide

PrestaShop Webservice API: REST-Integration, PHP-Client & ERP-Synchronisation

Vollständiger Leitfaden zur PrestaShop Webservice API — CRUD-Operationen, PHP-Client, Authentifizierung, Filterung, ERP/POS-Integration und PS 9 AdminAPI-Vorschau.

Was ist der PrestaShop Webservice

Der PrestaShop Webservice ist eine integrierte REST-ähnliche API, die es externen Anwendungen ermöglicht, Shop-Daten über HTTP zu lesen und zu schreiben. Er stellt Ressourcen bereit — Produkte, Bestellungen, Kunden, Kategorien, Lagerbestand und Dutzende mehr — über eine standardisierte Schnittstelle. XML ist das Standardformat; JSON ist ab PS 1.7+ über den Parameter &output_format=JSON verfügbar.

Jede PrestaShop-Version seit 1.4 enthält den Webservice. Er ist kein Modul — er ist Teil des Kerns. PS 1.6, 1.7, 8.x und 9.x unterstützen ihn alle.

Der Webservice ist der offizielle Weg, PrestaShop mit externen Systemen zu integrieren. Direkte Datenbankabfragen umgehen Validierung, Hooks und Geschäftslogik. Die API tut das nicht.

Häufige Anwendungsfälle: Synchronisierung von Produkten aus einem ERP- oder PIM-System, Export von Bestellungen an Fulfillment-Systeme, Lagerabgleich über mehrere Kanäle, Kundenverwaltung aus einem CRM und Automatisierung von Massenoperationen wie Preisaktualisierungen.

Aktivierung und Konfiguration der API

Der Webservice ist standardmäßig deaktiviert. Aktivieren Sie ihn unter Erweiterte Einstellungen > Webservice und klicken Sie dann auf „Neuen Webservice-Schlüssel hinzufügen“. Für jeden Schlüssel legen Sie eine Beschreibung, den Status (aktiviert/deaktiviert) und eine Berechtigungsmatrix fest — ein Raster aus Ressourcen und erlaubten HTTP-Methoden (GET, POST, PUT, DELETE, HEAD).

Erstellen Sie separate API-Schlüssel für jede Integration. Wenn Ihr ERP nur Bestellungen liest und den Lagerbestand aktualisiert, geben Sie ihm keine Berechtigung, Produkte zu löschen. Prinzip der geringsten Berechtigung.

Der Webservice erfordert URL-Rewriting. Apache handhabt dies über .htaccess in /api/. Für Nginx fügen Sie hinzu:

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

Authentifizierung

HTTP Basic Auth — der API-Schlüssel wird im Benutzernamen-Feld eingetragen, das Passwort bleibt leer:

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

HTTPS ist Pflicht — Schlüssel werden in jedem Reqüst-Header übertragen. IP-Whitelisting ist die wirksamste einzelne Sicherheitsmaßnahme für Integrationen mit fester IP:

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

Rotieren Sie Schlüssel alle 6–12 Monate. Speichern Sie sie in Umgebungsvariablen, niemals im Quellcode.

Verfügbare Ressourcen

Rufen Sie den Root-Endpunkt auf, um alles zu sehen, worauf Ihr Schlüssel Zugriff hat:

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

Katalog: products, combinations, categories, manufacturers, suppliers, product_features, product_feature_values, product_options (Attributgruppen), product_option_values, tags, images

Verkauf: orders, order_details (Positionen), order_states, order_histories (Statusänderungen), order_carriers (Sendungsverfolgung), carts, cart_rules

Kunden: customers, addresses, groups

Lagerbestand: stock_availables (Haupt-Lagerressource), warehouses, supply_orders

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

CRUD-Operationen

GET — Daten lesen

# 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,reference]"

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

POST — Erstellen

Holen Sie das leere XML-Schema, füllen Sie die Pflichtfelder aus und senden Sie es per POST zurück:

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 — Aktualisieren

Holen Sie die aktuelle Ressource per GET, ändern Sie die Felder und senden Sie das gesamte XML per PUT zurück. Teilaktualisierungen werden nicht unterstützt.

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
Führen Sie immer zuerst ein GET vor dem PUT durch. Wenn Sie XML von Grund auf erstellen und ein Pflichtfeld vergessen, kann die API es leeren oder die Anfrage ablehnen.

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 ist endgültig — kein Papierkorb, kein Rückgängigmachen. Bevorzugen Sie in Produktionsumgebungen das Setzen von active=0.

Filtern, Sortieren und Paginierung

# Exact match
?filter[reference]=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

Schema-Erkennung — zwei Modi, um die Ressourcenstruktur ohne Dokumentation zu untersuchen:

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

Die Synopsis zeigt Ihnen genau, welche Felder erforderlich sind und welches Format sie erwarten. Konsultieren Sie sie immer, bevor Sie Integrationscode schreiben.

Arbeiten mit Bildern

Produktbilder werden per Multipart-Formulardaten an einen separaten Endpunkt hochgeladen:

# 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"

PHP-Upload:

$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);
Optimieren Sie Bilder vor dem Hochladen. Skalieren Sie auf maximal 2048px und komprimieren Sie — 5 MB große DSLR-Fotos werden Ihren Shop verlangsamen.

Kombinationen und Attribute

Kombinationen sind der komplexeste Teil der API. Das Datenmodell hat drei Ebenen:

  • Product Option (Attributgruppe) — Größe, Farbe, Material
  • Product Option Value — S, M, L, Rot, Blau
  • Combination — eine Menge von Werten für ein Produkt (Größe:M + Farbe:Rot)

Erstellen Sie in dieser Reihenfolge: Attributgruppe → Werte → Kombination:

# 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>
    <reference>PROD-42-M-RED</reference>
    <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"

Der price-Wert einer Kombination ist ein Preisaufschlag, der zum Grundpreis des Produkts addiert wird — nicht der Endpreis.

Lagerbestand pro Kombination

Der Lagerbestand wird über stock_availables verwaltet, nicht über die Kombination selbst:

# 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"
Der Lagerbestandsdatensatz auf Produktebene (id_product_attribute=0) enthält die Summe aller Kombinationen. Aktualisieren Sie den Lagerbestand auf Kombinationsebene, und PrestaShop berechnet die Gesamtsumme automatisch neu.

Bestellungen und Warenkorb

# Recent orders
curl -u "KEY:" "https://your-store.com/api/orders?display=[id,reference,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"

Bestellstatus aktualisieren

Erstellen Sie einen neuen order_history-Datensatz — dies löst die Statusänderung aus und sendet die Kunden-E-Mail:

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"

Standard-Status-IDs: 1=Warten auf Zahlung, 2=Zahlung akzeptiert, 3=In Bearbeitung, 4=Versendet, 5=Zugestellt, 6=Storniert, 7=Erstattet. Diese variieren je nach Installation — fragen Sie order_states für die tatsächliche Liste Ihres Shops ab.

Sendungsnummern: Holen Sie den order_carriers-Datensatz der Bestellung per GET, fügen Sie tracking_number hinzu und senden Sie ihn per PUT zurück.

Bestellungen über die API erstellen ist technisch möglich, wird aber nicht empfohlen. Die Bestellerstellung umfasst Warenkorbvalidierung, Steuerberechnung, Zahlungsabwicklung, Lagerabzug und Hook-Ausführung — die API umgeht das meiste davon. Für Marktplatz-Importe erstellen Sie einen Warenkorb über die API und verarbeiten ihn über einen benutzerdefinierten Front Controller.

PHP-Client-Bibliothek

composer require prestashop/prestashop-webservice-lib

Oder laden Sie die einzelne Datei von GitHub herunter.

$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,reference,total_paid,current_state,date_add]',
    'filter[date_add]' => '[2025-06-01,9999-12-31]',
    'sort' => '[date_add_DESC]', 'limit' => 500
]);

Integrationsmuster

ERP-Integration

Das häufigste Szenario. Produkte, Preise und Lagerbestand fließen vom ERP zu PrestaShop; Bestellungen und Kundendaten fließen zurück. Best Practices: Verwenden Sie Referenzcodes (SKU/EAN) als gemeinsame Identifikatoren, planen Sie die Lagersynchronisierung alle 15 Minuten und Produkte stündlich, verfolgen Sie den letzten Synchronisierungszeitpunkt mit filter[date_upd], legen Sie die Konfliktlösung im Voraus fest (das ERP gewinnt in der Regel) und protokollieren Sie alles.

Lager und POS

Ein WMS folgt einem Zyklus: Wareneingang → Lagerbestand über API aktualisieren; Bestellungen abrufen → versenden → Sendungsverfolgung über API aktualisieren. Die POS-Integration ist ähnlich — der Lagerbestand muss nahezu in Echtzeit synchronisiert werden, damit Einkäufe im Laden die Online-Verfügbarkeit sofort reduzieren.

Marktplatz-Synchronisierung

Allegro-, Amazon- und eBay-Integrationen erfordern Produktexport mit Bildern, Bestellimport (über Warenkorb und benutzerdefinierte Verarbeitung statt direktem Order-POST) sowie bidirektionale Lagersynchronisierung, um Überverkauf zu verhindern.

Buchhaltung

Nur Lesezugriff: Bestellungen, Rechnungen und Gutschriften täglich oder wöchentlich abrufen. Benötigt nur GET-Berechtigungen.

Änderungen der API in PrestaShop 9

Der bisherige Webservice funktioniert in PS 9 weiterhin — er ist nicht veraltet. Bestehende Integrationen funktionieren nach dem Upgrade.

AdminAPI — Neue Symfony-basierte API

PS 9 führt eine neue AdminAPI neben dem bisherigen Webservice ein. Die wichtigsten Unterschiede:

  • Authentifizierung: OAuth2 mit Client Credentials (statt API-Schlüssel mit Basic Auth)
  • Format: Nur JSON (statt XML als Standard)
  • Architektur: Symfony / API Platform mit OpenAPI/Swagger-Dokumentation unter /admin-api/docs
  • Abdeckung: Wachsend — deckt noch nicht alle Ressourcen des bisherigen Webservice ab
# 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

Tokens laufen ab (Standard: 1 Stunde) — implementieren Sie die Erneuerung in Ihrer Integration. Scopes (product_read, product_write, order_read) steuern den Zugriff granular. Erstellen Sie API-Clients unter Erweiterte Einstellungen > AdminAPI.

Verwenden Sie die AdminAPI für neue PS 9+-Integrationen. Verwenden Sie den bisherigen Webservice für breite Ressourcenabdeckung oder Rückwärtskompatibilität mit PS 1.6/1.7/8.x. Sie können beide in derselben Integration verwenden.

Häufige Probleme

401 Unauthorized: Falscher Schlüssel (prüfen Sie auf Leerzeichen), Schlüssel deaktiviert, Webservice ausgeschaltet oder Schlüssel als Query-Parameter statt im Basic-Auth-Header gesendet.

403 Forbidden: Der Schlüssel hat keine Berechtigung für die Ressource oder HTTP-Methode. Überprüfen Sie die Berechtigungsmatrix.

404 Not Found: Die Ressource existiert nicht oder das URL-Rewriting ist fehlerhaft. Test: curl -u "KEY:" "https://store.com/webservice/dispatcher.php?url=products" — wenn dies funktioniert, aber /api/products nicht, korrigieren Sie die Rewrite-Regeln.

XML-Parsing-Fehler: Verwenden Sie CDATA für Sonderzeichen (<![CDATA[HTML & more]]>), umschließen Sie alles immer mit dem <prestashop>-Wurzelelement und senden Sie UTF-8 mit korrektem Content-Type-Header.

Langsame Massenoperationen: Die API verarbeitet jeweils nur eine Anfrage. Bei 10.000+ Einträgen:

  • Fordern Sie mit display nur benötigte Felder an — vermeiden Sie display=full bei großen Katalogen
  • Filtern Sie nach date_upd, um nur geänderte Datensätze zu synchronisieren
  • Verwenden Sie curl-Handles für persistente Verbindungen wieder
  • Für Erstimporte von 50.000+ Artikeln erwägen Sie den direkten Datenbankzugriff mit anschließendem Cache-Leeren
// 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);

Best Practices für die Sicherheit

  • Ein Schlüssel pro Integration — einen widerrufen, ohne andere zu beeinträchtigen
  • Minimale Berechtigungen — Lagersynchronisierung benötigt kein DELETE für Produkte
  • Immer HTTPS — Schlüssel im Klartext-HTTP sind für Netzwerk-Sniffer sichtbar
  • IP-Whitelisting — die wirksamste einzelne Maßnahme für Server-zu-Server-Integrationen
  • Schlüsselrotation — alle 6–12 Monate
  • Umgebungsvariablen — Schlüssel niemals in die Versionskontrolle einchecken
  • Ratenbegrenzung — die API hat keine eingebaute; fügen Sie sie auf Webserver-Ebene hinzu
# 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;
}

Audit-Protokollierung: PrestaShop hat keine integrierte API-Protokollierung. Analysieren Sie die Zugriffsprotokolle des Webservers nach /api/-Anfragen, oder überschreiben Sie WebserviceReqüst, um Zeitstempel, IP, Ressource, Methode und Antwortcode zu protokollieren. Unverzichtbar für die DSGVO-/PCI-Konformität, wenn auf Kundendaten zugegriffen wird.

Alternativen zum Webservice

Direkter Datenbankzugriff

Um Größenordnungen schneller für Massenoperationen, umgeht jedoch Validierung, Hooks und Cache-Invalidierung. Geeignet für einmalige Importe, Nur-Lese-Berichte und Notfallkorrekturen. Nicht geeignet für laufende Synchronisierung oder alles, was Bestellungen oder Zahlungen betrifft. Leeren Sie nach direkten Datenbankänderungen immer den Cache.

Modul-Hooks für Echtzeit-Synchronisierung

Anstatt die API abzufragen, übermitteln Sie Daten per Hook, wenn Ereignisse eintreten:

public function hookActionProductUpdate($params) {
    $product = $params['product'];
    $payload = json_encode([
        'id' => $product->id, 'reference' => $product->reference,
        '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);
}

Benutzerdefinierte Modul-Endpunkte

Für Operationen, die der Webservice schlecht handhabt, erstellen Sie eine benutzerdefinierte API als Modul-Front-Controller. Volle Kontrolle über Format, Authentifizierung und Geschäftslogik — verarbeiten Sie Massenoperationen in einer einzigen Anfrage und nutzen Sie dabei die nativen PrestaShop-Klassen für die Validierung.

Den richtigen Ansatz wählen

SzenarioBester Ansatz
Standard-ERP-/WMS-IntegrationWebservice API
Neue PS 9+-IntegrationAdminAPI (OAuth2, JSON)
Massenimport von 50.000+ ProduktenDirekter Datenbankzugriff + Cache leeren
Echtzeit-Ereignis-SynchronisierungModul-Hooks (Webhook-Push)
Benutzerdefinierte GeschäftslogikBenutzerdefinierter Modul-Endpunkt
Nur-Lese-BerichteDirekte Datenbankabfragen

Der PrestaShop Webservice ist seit über einem Jahrzehnt stabil. Für PS 9+ bietet die AdminAPI eine moderne Alternative. Wählen Sie das richtige Werkzeug für jede Aufgabe, implementieren Sie es von Anfang an mit Sicherheit und Fehlerbehandlung und testen Sie immer gegen die spezifische PrestaShop-Version, die Sie einsetzen.

More guides available

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

Loading...
Back to top