API Webservice PrestaShop: Integracja REST, klient PHP i synchronizacja ERP
Kompletny przewodnik po PrestaShop Webservice API — operacje CRUD, biblioteka PHP, uwierzytelnianie, filtrowanie, integracja ERP/POS i AdminAPI w PS 9.
Czym jest PrestaShop Webservice
PrestaShop Webservice to wbudowane API typu REST, które umożliwia zewnętrznym aplikacjom odczytywanie i zapisywanie danych sklepu przez HTTP. Udostępnia zasoby — produkty, zamówienia, klientów, kategorie, stany magazynowe i dziesiątki innych — poprzez ustandaryzowany interfejs. Domyślnym formatem jest XML; JSON jest dostępny w PS 1.7+ za pomocą parametru &output_format=JSON.
Każdy PrestaShop od wersji 1.4 zawiera Webservice. To nie jest moduł — to część rdzenia systemu. PS 1.6, 1.7, 8.x i 9.x — wszystkie go obsługują.
Webservice to oficjalny sposób integracji PrestaShop z zewnętrznymi systemami. Bezpośrednie zapytania do bazy danych pomijają walidację, hooki i logikę biznesową. API tego nie robi.
Typowe zastosowania: synchronizacja produktów z ERP lub PIM, eksport zamówień do systemów realizacji, utrzymywanie spójności stanów magazynowych między kanałami, zarządzanie klientami z CRM oraz automatyzacja operacji masowych, takich jak aktualizacja cen.
Włączanie i konfiguracja API
Webservice jest domyślnie wyłączony. Włącz go w Zaawansowane > Webservice, a następnie kliknij „Dodaj nowy klucz webservice”. Dla każdego klucza ustawiasz opis, status włączony/wyłączony oraz macierz uprawnień — siatkę zasobów i dozwolonych metod HTTP (GET, POST, PUT, DELETE, HEAD).
Twórz oddzielne klucze API dla każdej integracji. Jeśli Twój ERP tylko odczytuje zamówienia i aktualizuje stany magazynowe, nie dawaj mu uprawnień do usuwania produktów. Zasada minimalnych uprawnień.
Webservice wymaga przepisywania URL-i. Apache obsługuje to przez .htaccess w /api/. W przypadku Nginx dodaj:
location /api/ {
try_files $uri $uri/ /webservice/dispatcher.php?$args;
}
Uwierzytelnianie
HTTP Basic Auth — klucz API wpisuje się w pole nazwy użytkownika, hasło pozostaje puste:
curl -u "YOUR_API_KEY:" https://your-store.com/api/products
HTTPS jest obowiązkowy — klucze są przesyłane w każdym nagłówku żądania. Biała lista IP to najskuteczniejszy pojedynczy środek bezpieczeństwa dla integracji ze stałym adresem IP:
# .htaccess in /api/
<IfModule mod_authz_core.c>
Require ip 10.0.0.5
Require ip 192.168.1.0/24
</IfModule>
Rotuj klucze co 6-12 miesięcy. Przechowuj je w zmiennych środowiskowych, nigdy w kodzie źródłowym.
Dostępne zasoby
Wywołaj główny endpoint, aby zobaczyć wszystko, do czego Twój klucz ma dostęp:
curl -u "KEY:" https://your-store.com/api/
Katalog: products, combinations, categories, manufacturers, suppliers, product_features, product_feature_values, product_options (grupy atrybutów), product_option_values, tags, images
Sprzedaż: orders, order_details (pozycje zamówienia), order_states, order_histories (zmiany statusów), order_carriers (śledzenie przesyłek), carts, cart_rules
Klienci: customers, addresses, groups
Magazyn: stock_availables (główny zasób magazynowy), warehouses, supply_orders
Konfiguracja: carriers, countries, currencies, languages, taxes, zones, shops
Operacje CRUD
GET — Odczyt danych
# 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 — Tworzenie
Pobierz pusty schemat XML, wypełnij wymagane pola i wyślij go z powrotem metodą 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 — Aktualizacja
Pobierz aktualny zasób metodą GET, zmodyfikuj pola i wyślij cały XML z powrotem metodą PUT. Częściowe aktualizacje nie są obsługiwane.
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
Zawsze wykonaj GET przed PUT. Jeśli skonstruujesz XML od zera i zapomnisz wymaganego pola, API może je wyczyścić lub odrzucić żądanie.
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 jest trwałe — bez kosza, bez cofania. W środowisku produkcyjnym lepiej ustawić active=0.
Filtrowanie, sortowanie i paginacja
# 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
Odkrywanie schematu — dwa tryby pozwalają zbadać strukturę zasobu bez dokumentacji:
?schema=blank # Empty XML template with all fields
?schema=synopsis # Field types, required flags, max lengths, read-only markers
Synopsis powie Ci dokładnie, które pola są wymagane i jakiego formatu oczekują. Zawsze sięgaj do niego przed pisaniem kodu integracji.
Praca z obrazami
Obrazy produktów są przesyłane za pomocą danych multipart do osobnego endpointu:
# 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"
Przesyłanie w 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);
Optymalizuj obrazy przed przesyłaniem. Zmniejsz do maksymalnie 2048px i skompresuj — zdjęcia 5MB z lustrzanki spowolnią Twój sklep.
Kombinacje i atrybuty
Kombinacje to najtrudniejsza część API. Model danych ma trzy warstwy:
- Product Option (grupa atrybutów) — Rozmiar, Kolor, Materiał
- Product Option Value — S, M, L, Czerwony, Niebieski
- Combination — zestaw wartości dla produktu (Rozmiar:M + Kolor:Czerwony)
Tworzenie w kolejności: grupa atrybutów → wartości → kombinacja:
# 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"
Pole price w kombinacji to wpływ na cenę dodawany do bazowej ceny produktu, a nie cena końcowa.
Stan magazynowy per kombinacja
Stan magazynowy jest zarządzany przez stock_availables, a nie przez samą kombinację:
# 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"
Rekord magazynowy na poziomie produktu (id_product_attribute=0) przechowuje sumę wszystkich kombinacji. Aktualizuj stan magazynowy na poziomie kombinacji, a PrestaShop automatycznie przeliczy sumę.
Zamówienia i koszyk
# 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"
Aktualizacja statusu zamówienia
Utwórz nowy rekord order_history — to uruchamia zmianę statusu i wysyła e-mail do klienta:
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"
Domyślne ID statusów: 1=Oczekiwanie na płatność, 2=Płatność zaakceptowana, 3=W realizacji, 4=Wysłane, 5=Dostarczone, 6=Anulowane, 7=Zwrócone. Mogą się różnić w zależności od instalacji — sprawdź order_states dla listy właściwej dla Twojego sklepu.
Numery śledzenia: Pobierz rekord order_carriers dla zamówienia metodą GET, dodaj tracking_number, wyślij z powrotem metodą PUT.
Tworzenie zamówień przez API jest technicznie możliwe, ale niezalecane. Tworzenie zamówienia obejmuje walidację koszyka, obliczanie podatków, przetwarzanie płatności, odejmowanie stanu magazynowego i wykonywanie hooków — API pomija większość z tego. Przy importach z marketplace utwórz koszyk przez API i przetwórz go przez dedykowany front controller.
Biblioteka klienta PHP
composer require prestashop/prestashop-webservice-lib
Lub pobierz pojedynczy plik z 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,reference,total_paid,current_state,date_add]',
'filter[date_add]' => '[2025-06-01,9999-12-31]',
'sort' => '[date_add_DESC]', 'limit' => 500
]);
Wzorce integracji
Integracja z ERP
Najczęstszy scenariusz. Produkty, ceny i stany magazynowe płyną z ERP do PrestaShop; zamówienia i dane klientów wracają w drugą stronę. Dobre praktyki: używaj kodów referencyjnych (SKU/EAN) jako wspólnych identyfikatorów, planuj synchronizację stanów co 15 minut, a produktów co godzinę, śledź znacznik czasu ostatniej synchronizacji za pomocą filter[date_upd], z góry ustal zasady rozwiązywania konfliktów (zwykle wygrywa ERP) i loguj wszystko.
Magazyn i POS
WMS działa w cyklu: przyjęcie towaru → aktualizacja stanu przez API; odpytywanie zamówień → wysyłka → aktualizacja śledzenia przesyłki przez API. Integracja POS jest podobna — stany muszą się synchronizować niemal w czasie rzeczywistym, aby zakupy w sklepie stacjonarnym natychmiast zmniejszały dostępność online.
Synchronizacja z marketplace
Integracje z Allegro, Amazon, eBay wymagają eksportu produktów z obrazami, importu zamówień (przez koszyk + niestandardowe przetwarzanie zamiast bezpośredniego POST zamówienia) oraz dwukierunkowej synchronizacji stanów magazynowych, aby zapobiec nadsprzedaży.
Księgowość
Tryb tylko do odczytu: pobieraj zamówienia, faktury i korekty według dziennego/tygodniowego harmonogramu. Wymaga jedynie uprawnień GET.
Zmiany API w PrestaShop 9
Starszy Webservice nadal działa w PS 9 — nie został oznaczony jako przestarzały. Istniejące integracje działają po aktualizacji.
AdminAPI — Nowe API oparte na Symfony
PS 9 wprowadza nowe AdminAPI obok starego Webservice. Kluczowe różnice:
- Uwierzytelnianie: OAuth2 z client credentials (zamiast Basic Auth z kluczem API)
- Format: Wyłącznie JSON (zamiast domyślnego XML)
- Architektura: Symfony / API Platform z dokumentacją OpenAPI/Swagger pod
/admin-api/docs - Pokrycie: Rosnące — nie obejmuje jeszcze wszystkich zasobów starego Webservice
# 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
Tokeny wygasą (domyślnie: 1 godzina) — obsłuż odświeżanie w swojej integracji. Zakresy (product_read, product_write, order_read) kontrolują dostęp w sposób granularny. Tworzenie klientów API: Zaawansowane > AdminAPI.
Używaj AdminAPI do nowych integracji z PS 9+. Używaj starego Webservice dla szerokiego pokrycia zasobów lub wstecznej kompatybilności z PS 1.6/1.7/8.x. Możesz używać obu w tej samej integracji.
Typowe problemy
401 Unauthorized: Zły klucz (sprawdź białe znaki), klucz wyłączony, Webservice wyłączony lub klucz wysłany jako parametr URL zamiast nagłówka Basic Auth.
403 Forbidden: Klucz nie ma uprawnień do zasobu lub metody HTTP. Sprawdź macierz uprawnień.
404 Not Found: Zasób nie istnieje lub przepisywanie URL jest uszkodzone. Test: curl -u "KEY:" "https://store.com/webservice/dispatcher.php?url=products" — jeśli to działa, ale /api/products nie, napraw reguły przepisywania.
Błędy parsowania XML: Używaj CDATA dla znaków specjalnych (<![CDATA[HTML & more]]>), zawsze opakowuj w element główny <prestashop>, wysyłaj UTF-8 z właściwym nagłówkiem Content-Type.
Wolne operacje masowe: API przetwarza jedno żądanie naraz. Przy 10 000+ elementów:
- Żądaj tylko potrzebnych pól za pomocą
display— unikajdisplay=fullna dużych katalogach - Filtruj po
date_upd, aby synchronizować tylko zmienione rekordy - Używaj ponownie uchwytów curl dla połączeń trwałych
- Przy początkowych importach 50K+ produktów rozważ bezpośredni dostęp do bazy z czyszczeniem 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);
Najlepsze praktyki bezpieczeństwa
- Jeden klucz na integrację — możesz odwołać jeden bez wpływu na pozostałe
- Minimalne uprawnienia — synchronizacja stanów nie potrzebuje DELETE na produktach
- Zawsze HTTPS — klucze w czystym HTTP są widoczne dla podsuchujących sieć
- Biała lista IP — najskuteczniejszy pojedynczy środek dla integracji serwer-serwer
- Rotacja kluczy — co 6-12 miesięcy
- Zmienne środowiskowe — nigdy nie commituj kluczy do repozytorium
- Limitowanie zapytań — API nie ma wbudowanego limitu; dodaj go na poziomie serwera WWW
# 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;
}
Logowanie audytowe: PrestaShop nie ma wbudowanego logowania API. Parsuj logi dostępu serwera WWW pod kątem zapytań do /api/ lub nadpisz WebserviceRequest, aby logować znacznik czasu, IP, zasób, metodę i kod odpowiedzi. Niezbędne dla zgodności z GDPR/PCI, gdy uzyskiwany jest dostęp do danych klientów.
Alternatywy dla Webservice
Bezpośredni dostęp do bazy danych
Rzędy wielkości szybszy przy operacjach masowych, ale pomija walidację, hooki i inwalidację cache. Odpowiedni do jednorazowych importów, raportów tylko do odczytu i napraw awaryjnych. Nieodpowiedni do bieżącej synchronizacji ani do operacji dotyczących zamówień czy płatności. Po zmianach bezpośrednio w bazie zawsze czyść cache.
Hooki modułowe do synchronizacji w czasie rzeczywistym
Zamiast odpytywać API, wysyłaj dane przez hooki w momencie wystąpienia zdarzeń:
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);
}
Niestandardowe endpointy modułowe
Dla operacji, z którymi Webservice radzi sobie słabo, zbuduj własne API jako front controller modułu. Pełna kontrola nad formatem, uwierzytelnianiem i logiką biznesową — przetwarzaj operacje masowe w jednym żądaniu, korzystając z natywnych klas PrestaShop do walidacji.
Wybór właściwego podejścia
| Scenariusz | Najlepsze podejście |
|---|---|
| Standardowa integracja ERP/WMS | Webservice API |
| Nowa integracja z PS 9+ | AdminAPI (OAuth2, JSON) |
| Import masowy 50K+ produktów | Bezpośrednia baza + czyszczenie cache |
| Synchronizacja zdarzeń w czasie rzeczywistym | Hooki modułowe (webhook push) |
| Niestandardowa logika biznesowa | Niestandardowy endpoint modułu |
| Raporty tylko do odczytu | Bezpośrednie zapytania do bazy |
PrestaShop Webservice jest stabilne od ponad dekady. Dla PS 9+ AdminAPI oferuje nowoczesną alternatywę. Wybierz odpowiednie narzędzie do każdego zadania, wdrażaj z uwzględnieniem bezpieczeństwa i obsługi błędów od pierwszego dnia i zawsze testuj na konkretnej wersji PrestaShop, na którą celujesz.
More guides available
Browse our knowledge base for more practical PrestaShop tutorials, or reach out if you need help.