# shopPRO REST API REST API do integracji z ordersPRO i innymi systemami zewnetrznymi. ## Autentykacja Kazde zapytanie wymaga headera `X-Api-Key` z kluczem API. ``` X-Api-Key: {klucz_api} ``` Klucz przechowywany jest w `pp_settings` jako parametr `api_key`. API jest stateless (bez sesji). ## Format odpowiedzi ### Sukces (HTTP 200) ```json { "status": "ok", "data": { ... } } ``` ### Blad ```json { "status": "error", "code": "UNAUTHORIZED", "message": "Invalid or missing API key" } ``` Kody bledow: | Kod | HTTP | Opis | |-----|------|------| | `UNAUTHORIZED` | 401 | Brak lub nieprawidlowy klucz API | | `BAD_REQUEST` | 400 | Brakujace lub niepoprawne parametry | | `NOT_FOUND` | 404 | Nie znaleziono zasobu/endpointu/akcji | | `METHOD_NOT_ALLOWED` | 405 | Nieprawidlowa metoda HTTP | | `INTERNAL_ERROR` | 500 | Blad wewnetrzny serwera | ## Endpointy ### Zamowienia #### Lista zamowien ``` GET api.php?endpoint=orders&action=list ``` Parametry filtrowania (opcjonalne): | Parametr | Typ | Opis | |----------|-----|------| | `status` | int | Filtruj po statusie zamowienia | | `paid` | int (0/1) | Filtruj po statusie platnosci | | `date_from` | date (YYYY-MM-DD) | Zamowienia od daty | | `date_to` | date (YYYY-MM-DD) | Zamowienia do daty | | `updated_since` | datetime (YYYY-MM-DD HH:MM:SS) | Zamowienia zmodyfikowane od podanej daty (klucz do pollingu) | | `number` | string | Szukaj po numerze zamowienia | | `client` | string | Szukaj po imieniu, nazwisku lub emailu klienta | | `page` | int | Numer strony (domyslnie 1) | | `per_page` | int | Wynikow na strone (domyslnie 50, max 100) | Odpowiedz: ```json { "status": "ok", "data": { "items": [ { "id": 42, "number": "2026/02/001", "date_order": "2026-02-19 10:30:00", "updated_at": "2026-02-19 12:00:00", "status": 4, "paid": 1, "client_name": "Jan", "client_surname": "Kowalski", "client_email": "jan@example.com", "client_phone": "111222333", "client_street": "Testowa 1", "client_postal_code": "00-000", "client_city": "Warszawa", "firm_name": null, "firm_nip": null, "transport": "Kurier DPD", "transport_cost": 15.00, "payment_method": "Przelew bankowy", "summary": 150.00 } ], "total": 1, "page": 1, "per_page": 50 } } ``` #### Szczegoly zamowienia ``` GET api.php?endpoint=orders&action=get&id={order_id} ``` Zwraca pelne dane zamowienia z produktami i historia statusow. #### Zmiana statusu zamowienia ``` PUT api.php?endpoint=orders&action=change_status&id={order_id} Content-Type: application/json { "status_id": 5, "send_email": true } ``` Odpowiedz: ```json { "status": "ok", "data": { "order_id": 42, "status_id": 5, "changed": true } } ``` #### Oznacz jako oplacone ``` PUT api.php?endpoint=orders&action=set_paid&id={order_id} ``` Opcjonalnie w body: `{"send_email": true}` #### Oznacz jako nieoplacone ``` PUT api.php?endpoint=orders&action=set_unpaid&id={order_id} ``` ### Produkty #### Lista produktow ``` GET api.php?endpoint=products&action=list ``` Parametry filtrowania (opcjonalne): | Parametr | Typ | Opis | |----------|-----|------| | `search` | string | Szukaj po nazwie, EAN lub SKU | | `status` | int (0/1) | Filtruj po statusie (1 = aktywny, 0 = nieaktywny) | | `promoted` | int (0/1) | Filtruj po promocji | | `attribute_{id}` | int | Filtruj po atrybucie — `attribute_1=3` oznacza atrybut 1 = wartosc 3 (wiele filtrow AND) | | `sort` | string | Sortuj po: id, name, price_brutto, status, promoted, quantity (domyslnie id) | | `sort_dir` | string | Kierunek: ASC lub DESC (domyslnie DESC) | | `page` | int | Numer strony (domyslnie 1) | | `per_page` | int | Wynikow na strone (domyslnie 50, max 100) | Odpowiedz: ```json { "status": "ok", "data": { "items": [ { "id": 1, "sku": "PROD-001", "ean": "5901234123457", "name": "Produkt testowy", "price_brutto": 99.99, "price_brutto_promo": null, "price_netto": 81.29, "price_netto_promo": null, "quantity": 10, "status": 1, "promoted": 0, "vat": 23, "weight": 0.5, "main_image": "product1.jpg", "date_add": "2026-01-15 10:00:00", "date_modify": "2026-02-19 12:00:00" } ], "total": 1, "page": 1, "per_page": 50 } } ``` #### Szczegoly produktu ``` GET api.php?endpoint=products&action=get&id={product_id} ``` Zwraca pelne dane produktu z jezykami, zdjeciami, kategoriami i atrybutami. Odpowiedz: ```json { "status": "ok", "data": { "id": 1, "sku": "PROD-001", "ean": "5901234123457", "price_brutto": 99.99, "price_brutto_promo": null, "price_netto": 81.29, "price_netto_promo": null, "quantity": 10, "status": 1, "promoted": 0, "vat": 23, "weight": 0.5, "stock_0_buy": 0, "custom_label_0": null, "set_id": null, "product_unit_id": 1, "producer_id": 3, "producer_name": "Nike", "date_add": "2026-01-15 10:00:00", "date_modify": "2026-02-19 12:00:00", "languages": { "pl": { "name": "Produkt testowy", "short_description": "Krotki opis", "description": "

Pelny opis produktu

", "meta_description": null, "meta_keywords": null, "meta_title": null, "seo_link": "produkt-testowy", "copy_from": null, "warehouse_message_zero": null, "warehouse_message_nonzero": null, "tab_name_1": null, "tab_description_1": null, "tab_name_2": null, "tab_description_2": null, "canonical": null, "security_information": null } }, "images": [ {"id": 1, "src": "product1.jpg", "alt": "Zdjecie produktu"} ], "categories": [1, 5], "attributes": [ { "attribute_id": 1, "attribute_type": 1, "attribute_names": {"pl": "Kolor", "en": "Color"}, "value_id": 3, "value_names": {"pl": "Czerwony", "en": "Red"} } ], "custom_fields": [ {"name": "Napis na koszulce", "type": "text", "is_required": 1} ], "variants": [ { "id": 101, "permutation_hash": "1-3|2-5", "sku": "PROD-001-RED-L", "ean": null, "price_brutto": 109.99, "price_brutto_promo": null, "price_netto": 89.42, "price_netto_promo": null, "quantity": 5, "stock_0_buy": 0, "weight": 0.5, "status": 1, "attributes": [ {"attribute_id": 1, "attribute_names": {"pl": "Kolor"}, "value_id": 3, "value_names": {"pl": "Czerwony"}}, {"attribute_id": 2, "attribute_names": {"pl": "Rozmiar"}, "value_id": 5, "value_names": {"pl": "L"}} ] } ] } } ``` #### Tworzenie produktu ``` POST api.php?endpoint=products&action=create Content-Type: application/json { "price_brutto": 99.99, "vat": 23, "quantity": 10, "status": 1, "sku": "PROD-001", "ean": "5901234123457", "weight": 0.5, "languages": { "pl": { "name": "Nowy produkt", "description": "

Opis produktu

" } }, "categories": [1, 5], "products_related": [10, 20] } ``` Wymagane: `languages` (min. 1 jezyk z `name`) oraz `price_brutto`. Odpowiedz (HTTP 201): ```json { "status": "ok", "data": { "id": 42 } } ``` #### Aktualizacja produktu ``` PUT api.php?endpoint=products&action=update&id={product_id} Content-Type: application/json { "price_brutto": 129.99, "status": 1, "languages": { "pl": { "name": "Zaktualizowana nazwa" } } } ``` Partial update — wystarczy przeslac tylko zmienione pola. Pola nieprzeslane zachowuja aktualna wartosc. Odpowiedz: pelne dane produktu (jak w `get`). ### Warianty produktow #### Lista wariantow produktu ``` GET api.php?endpoint=products&action=variants&id={product_id} ``` Zwraca warianty produktu nadrzednego wraz z dostepnymi atrybutami. Odpowiedz: ```json { "status": "ok", "data": { "product_id": 1, "available_attributes": [ { "id": 1, "type": 1, "status": 1, "names": {"pl": "Kolor", "en": "Color"}, "values": [ {"id": 3, "names": {"pl": "Czerwony", "en": "Red"}, "is_default": 0, "impact_on_the_price": null}, {"id": 4, "names": {"pl": "Niebieski", "en": "Blue"}, "is_default": 0, "impact_on_the_price": 10.0} ] } ], "variants": [ { "id": 101, "permutation_hash": "1-3", "sku": "PROD-001-RED", "ean": null, "price_brutto": 109.99, "price_brutto_promo": null, "price_netto": 89.42, "price_netto_promo": null, "quantity": 5, "stock_0_buy": 0, "weight": 0.5, "status": 1, "attributes": [ {"attribute_id": 1, "attribute_names": {"pl": "Kolor"}, "value_id": 3, "value_names": {"pl": "Czerwony"}} ] } ] } } ``` #### Tworzenie wariantu ``` POST api.php?endpoint=products&action=create_variant&id={product_id} Content-Type: application/json { "attributes": {"1": 3, "2": 5}, "sku": "PROD-001-RED-L", "ean": "5901234123458", "price_brutto": 109.99, "quantity": 5, "weight": 0.5 } ``` Wymagane: `attributes` (mapa attribute_id -> value_id, min. 1). Kombinacja atrybutow musi byc unikalna. Odpowiedz (HTTP 201): pelne dane wariantu. #### Aktualizacja wariantu ``` PUT api.php?endpoint=products&action=update_variant&id={variant_id} Content-Type: application/json { "sku": "PROD-001-RED-XL", "price_brutto": 119.99, "quantity": 3 } ``` Partial update — mozna zmienic: sku, ean, price_brutto, price_netto, price_brutto_promo, price_netto_promo, quantity, stock_0_buy, weight, status. Odpowiedz: pelne dane wariantu. #### Usuwanie wariantu ``` DELETE api.php?endpoint=products&action=delete_variant&id={variant_id} ``` Odpowiedz: ```json { "status": "ok", "data": {"id": 101, "deleted": true} } ``` ### Slowniki #### Lista statusow zamowien ``` GET api.php?endpoint=dictionaries&action=statuses ``` Odpowiedz: ```json { "status": "ok", "data": [ {"id": 0, "name": "Nowe"}, {"id": 1, "name": "Oplacone"}, {"id": 4, "name": "W realizacji"}, {"id": 6, "name": "Wyslane"} ] } ``` #### Lista metod transportu ``` GET api.php?endpoint=dictionaries&action=transports ``` #### Lista metod platnosci ``` GET api.php?endpoint=dictionaries&action=payment_methods ``` #### Lista atrybutow ``` GET api.php?endpoint=dictionaries&action=attributes ``` Zwraca aktywne atrybuty z wartosciami i wielojezycznymi nazwami. #### Znajdz lub utworz producenta ``` POST api.php?endpoint=dictionaries&action=ensure_producer Content-Type: application/json { "name": "Nike" } ``` Zwraca istniejacego producenta po nazwie lub tworzy nowego. Uzyc przed tworzeniem produktu, jesli producent moze nie istniec. Odpowiedz: ```json { "status": "ok", "data": { "id": 5, "created": false } } ``` `created: true` gdy producent zostal nowo dodany, `false` gdy juz istnial. Odpowiedz: ```json { "status": "ok", "data": [ { "id": 1, "type": 1, "status": 1, "names": {"pl": "Kolor", "en": "Color"}, "values": [ {"id": 3, "names": {"pl": "Czerwony"}, "is_default": 0, "impact_on_the_price": null}, {"id": 4, "names": {"pl": "Niebieski"}, "is_default": 1, "impact_on_the_price": 10.0} ] } ] } ``` ## Polling Aby pobierac tylko nowe/zmienione zamowienia, uzyj parametru `updated_since`: ``` GET api.php?endpoint=orders&action=list&updated_since=2026-02-19 12:00:00 ``` Kolumna `updated_at` w `pp_shop_orders` jest aktualizowana automatycznie przy kazdej modyfikacji zamowienia (zmiana statusu, platnosci, edycja danych, tworzenie zamowienia). ## Konfiguracja Klucz API ustawia sie w panelu admina w ustawieniach sklepu lub bezposrednio w bazie: ```sql INSERT INTO pp_settings (param, value) VALUES ('api_key', 'twoj-klucz-api'); -- lub UPDATE pp_settings SET value = 'twoj-klucz-api' WHERE param = 'api_key'; ``` ## Architektura - Entry point: `api.php` - Router: `\api\ApiRouter` (`autoload/api/ApiRouter.php`) - Kontrolery: `autoload/api/Controllers/` - `OrdersApiController` — zamowienia (5 akcji) - `ProductsApiController` — produkty (8 akcji: list, get, create, update, variants, create_variant, update_variant, delete_variant) - `DictionariesApiController` — slowniki (5 akcji: statuses, transports, payment_methods, attributes, ensure_producer)