v3.32.0

Boss of Toys × WooCommerce

Kompleksowa dokumentacja systemu integracji WooCommerce z hurtownią BossOfToys oraz marketplace Allegro, Empik i InPost.

📅 2026-04-22
🔗 GitHub
🏗️ Python 3.11 + FastAPI + WordPress
🗄️ SQLite (WAL mode)
Rozdział 01

Czym jest ten system?

System Boss of Toys × WooCommerce to kompleksowa integracja łącząca trzy platformy handlowe w jeden zautomatyzowany potok — od produktu w hurtowni, przez sklep i marketplace, aż po dostawę do klienta.

PlatformaRola w systemie
BossOfToys (hurtownia)Źródło produktów, stanów magazynowych i cen. Przyjmuje zamówienia dropshippingowe z etykietami PDF.
WooCommerce (sklep)Sklep internetowy na WordPressie (OVH). Centralne miejsce zarządzania produktami i zamówieniami.
Allegro (marketplace)Wystawianie ofert, import zamówień, śledzenie przesyłek, fulfillment.
Empik (marketplace)Obsługa zamówień — OR23 (tracking) i OR24 (potwierdzenie wysyłki) przez Mirakl API.
InPost / ShipXGenerowanie etykiet, śledzenie paczek, Geowidget (wybór paczkomatu).
Fakturownia.plAutomatyczne wystawianie i pobieranie faktur PDF.
OpenAIGenerowanie opisów produktów AI.

System działa w trybie w pełni zautomatyzowanym: od pojawienia się zamówienia na Allegro/w sklepie, przez generowanie etykiety, forwarding do hurtowni, śledzenie przesyłki, aż po zamknięcie zamówienia i wystawienie faktury — wszystko bez interwencji ręcznej.

Rozdział 02

Architektura ogólna

KLIENCI
  │
  ├─ Sklep WooCommerce (OVH) ─── klient składa zamówienie
  ├─ Allegro (marketplace) ────── kupujący składa zamówienie
  └─ Empik (marketplace) ──────── kupujący składa zamówienie
         │
         ▼
┌──────────────────────────────────────────────────────┐
│           WordPress (OVH) — Plugin BossOfToys        │
│                                                      │
│  Dashboard    Ustawienia    Harmonogram              │
│  Etykiety     InPost Sizes  Geowidget                │
│  Fakturownia  Allegro Panel Logi                     │
└─────────────────┬────────────────────────────────────┘
                  │ HTTPS  (X-API-Key)
                  ▼
┌──────────────────────────────────────────────────────┐
│        VPS — Python FastAPI (port 8000)              │
│                                                      │
│  /api/jobs/*     /api/config/*    /api/labels/*      │
│  /api/allegro/*  /api/sse/*       /api/stats/*       │
│  /api/metrics    /api/logs/*                         │
│                                                      │
│  SQLite: data/api_bridge.db (WAL mode, 13 tabel)     │
└─────────────────┬────────────────────────────────────┘
                  │
                  ▼
┌──────────────────────────────────────────────────────┐
│         Moduły core/ (20+ modułów Python)            │
│                                                      │
│  6x WooCommerce    9x Allegro                        │
│  3x Etykiety       2x Empik      1x Fakturownia      │
└─────────────────┬────────────────────────────────────┘
                  │
     ┌────────────┼────────────┬──────────────┐
     ▼            ▼            ▼              ▼
BossOfToys     WC REST      Allegro        ShipX
(hurtownia)    API          OAuth 2.0      REST API

Komunikacja między komponentami

SkądDokądProtokół / Auth
WordPress pluginVPS FastAPIHTTPS + nagłówek X-API-Key
VPSWooCommerce RESTconsumer_key + consumer_secret
VPSWordPress REST (/wp/v2)HTTPS + Application Password + Chrome User-Agent
VPSBossOfToys APIemail + password + acronym
VPSAllegro APIOAuth 2.0 — tokeny w SQLite kv_store
VPSShipX (InPost)Bearer token + organization_id
VPSFakturowniaapi_token w URL
VPSEmpik (Mirakl)API Key w nagłówku
⚠️

OVH LiteSpeed WAF blokuje User-Agent python-requests → 403. Wszystkie requesty do /wp-json/wp/v2/* muszą używać USER_AGENT (Chrome string). Klucze WooCommerce NIE działają na WP REST API — potrzebne Application Password.

Rozdział 03

Stos technologiczny

Backend (VPS)

KomponentTechnologiaPlik
Framework APIFastAPI (Python 3.11+)run_api.py, api/server.py
Baza danychSQLite 3 (WAL mode)data/api_bridge.db
Repository patternWłasny ~40 metodapi/repository.py
Migracje DBWłasny system wersjonowaniaapi/migrations.py
Adapter danychDB/JSON fallbackcore/data_store.py
HarmonogramVPS Scheduler (asyncio)api/scheduler.py
Autoryzacja APIAPI Key (Bearer)api/auth.py
Logi real-timeServer-Sent Events (SSE)api/routes/sse.py
TelemetriaMetricsMiddleware + Chart.jsapi/metrics.py
GUI DesktopPyQt6 (Midnight Electric theme)main_woo.py, gui/

Frontend (WordPress Plugin)

KomponentTechnologia
Plugin PHPWordPress 6.x + WooCommerce 8.x
JavaScriptjQuery (vanilla)
WykresyChart.js
IkonyDashicons (WordPress)
Mapa InPostGeowidget InPost v5
Rozdział 04

Wdrożenie i uruchomienie

Uruchomienie VPS

# Instalacja zależności
pip install fastapi uvicorn woocommerce requests python-dotenv

# Uruchomienie API (produkcja)
python run_api.py

# Z opcjami
python run_api.py --port 8080 --reload

# Tryb Desktop (GUI lokalny)
python main_woo.py

Minimalna konfiguracja .env

# WooCommerce
WOOCOMMERCE_URL=https://twojsklep.pl
WOOCOMMERCE_KEY=ck_xxxxxxxxxxxxxxxxxxxx
WOOCOMMERCE_SECRET=cs_xxxxxxxxxxxxxxxxxxxx

# WordPress REST API (media, produkty - wymaga Application Password)
WP_USERNAME=admin
WP_APP_PASSWORD=xxxx xxxx xxxx xxxx xxxx xxxx

# BossOfToys
BOSSOFTOYS_EMAIL=email@firma.pl
BOSSOFTOYS_PASSWORD=haslo
BOSSOFTOYS_ACRONYM=ESKL1_XXXX

# API security
API_SECRET_KEY=bardzo_dlugi_losowy_klucz_min_32_znaki

# Allegro OAuth
ALLEGRO_CLIENT_ID=twoj_client_id
ALLEGRO_CLIENT_SECRET=twoj_client_secret

# ShipX (InPost)
SHIPX_TOKEN=twoj_token_shipx
SHIPX_ORGANIZATION_ID=12345

# Fakturownia
FAKTUROWNIA_API_TOKEN=twoj_token
FAKTUROWNIA_DOMAIN=twojafirma

# Empik Marketplace
EMPIK_API_KEY=twoj_klucz_empik
EMPIK_SHOP_ID=twoj_shop_id

# Opcjonalne (powiadomienia)
OPENAI_API_KEY=sk-xxxxxxxxxxxx
NTFY_TOPIC=twoj_temat_ntfy
SMTP_HOST=smtp.gmail.com
SMTP_USER=email@gmail.com
SMTP_PASSWORD=app_password
ALERT_EMAIL=odbiorca@gmail.com

Migracja na nowy serwer

Plugin WordPress

Skopiuj folder wordpress-plugin/bossoftoys-manager/ do wp-content/plugins/ i aktywuj w WordPress → Wtyczki.

Rozdział 05

Konfiguracja

Priorytet ładowania (pierwszy wygrywa)

  1. Zmienne systemowe (export WOOCOMMERCE_URL=...)
  2. Plik .env w katalogu głównym
  3. Plik config/settings.json (legacy)
  4. Plik config/settings.dat (zaszyfrowane — tryb Desktop)

Sekcje konfiguracji

SekcjaZawartość
woocommerceURL, klucze API, WP credentials
bossoftoysDane logowania, tryb danych (api/xml), marże per kategoria
allegroOAuth (client_id/secret), min_stock, price_margin, GPSR, dostawa, repricing
boss_apiauto_forward, forwarding credentials
shipxToken ShipX, organization_id
fakturowniaToken API, domena
empikAPI key, shop_id
ntfyTopic (powiadomienia push na telefon)
smtpKonfiguracja e-mail dla alertów
openaiKlucz API OpenAI (opisy AI)

Harmonogram VPS (config/scheduler.json)

{
  "label-generator":       { "enabled": true, "interval_minutes": 15 },
  "shipment-tracking":     { "enabled": true, "interval_minutes": 30 },
  "allegro-order-sync":    { "enabled": true, "interval_minutes": 15 },
  "allegro-offer-sync":    { "enabled": true, "interval_minutes": 30 },
  "order-forwarder":       { "enabled": true, "interval_minutes": 15 },
  "stock-sync":            { "enabled": true, "interval_minutes": 30 },
  "price-updater":         { "enabled": true, "interval_minutes": 1440 },
  "allegro-repricing":     { "enabled": true, "interval_minutes": 360 }
}
ℹ️

VPS Scheduler zastępuje WP-Cron. WP pseudo-cron działa tylko przy odwiedzinach strony. W WordPress → BossOfToys → Harmonogram należy wyłączyć WP-Cron — VPS przejmuje zadania.

Rozdział 06

Baza danych SQLite

Plik: data/api_bridge.db — WAL mode + PRAGMA foreign_keys=ON

Architektura dostępu do danych

core/*.py
   └─ from core.data_store import data_store  (lazy import w funkcji!)
         └─ core/data_store.py (adapter)
               ├─ VPS: api/repository.py → api/database.py → SQLite
               └─ Desktop: pliki JSON (fallback)
🚫

Zasada krytyczna: Moduły w core/ nigdy nie importują api.repository bezpośrednio — circular import przez Pydantic. Zawsze przez core.data_store, i tylko wewnątrz funkcji (lazy import).

13 tabel bazy danych

TabelaZawartośćRetencja
jobsHistoria uruchomień modułów7 dni
job_logsLogi z wykonań7 dni (CASCADE)
job_resultsWyniki zadań (JSON)7 dni (CASCADE)
schema_migrationsWersje migracji DBTrwałe
kv_storeKlucz-wartość (tokeny OAuth, checkpointy)Trwałe dla tokenów
allegro_synced_ordersHistoria sync zamówień Allegro → WCTrwałe (nigdy)
forwarded_ordersZamówienia przekazane do BossOfToysTrwałe (nigdy)
cache_entriesCache SKU, EAN, stany magazynoweTTL per wpis
allegro_eventsZdarzenia AllegroMax 500
allegro_fulfillment_stateStan fulfillmentTrwałe
ghost_trackerDaty nieobecności produktówAktywne
run_statsStatystyki uruchomieńAktywne
metrics_hourlyMetryki HTTP API (godzinowe)48h
💡

Migracje uruchamiają się automatycznie przy starcie serwera — plik api/migrations.py. Nie wymaga ręcznej obsługi.

Rozdział 07

Moduły — BossOfToys / WooCommerce

📊
Stock Sync
stock_synchronizer_woo.py
Synchronizacja stanów magazynowych z BossOfToys do WC. Tryb różnicowy — wysyła tylko zmiany. Ghost tracking — produkty nieobecne przez X dni są zerowane.
Product Adder
product_adder_woo.py
Dodaje nowe produkty do sklepu. Przelicza ceny z marżą per kategoria. Tworzy kartotekę w Fakturowni. Obsługa checkpoint (resume po przerwaniu).
🗑️
Product Deleter
product_deleter_woo.py
Usuwa produkty nieobecne u dostawcy przez X dni. Sanity check: max 70% katalogu jednorazowo. Domyślnie DRY-RUN!
💰
Price Updater
price_updater_woo.py
Aktualizuje ceny według cennika BossOfToys + marże per kategoria. Próg zmiany: 0.02 PLN. Zapisuje _cost_price.
✍️
Description Generator
description_generator_woo.py
Generuje opisy AI (OpenAI). Znacznik <!-- AI_DESC -->. Backup + resume. Modele: gpt-4o-mini, gpt-4o.
📤
Order Forwarder
order_forwarder_woo.py
Przekazuje zamówienia WC do BossOfToys z etykietą PDF. Nie generuje etykiet — wymaga, żeby już istniały. Deduplikacja przez forwarded_orders.

Szczegóły modułu Order Forwarder

⚠️

Order Forwarder sprawdza etykietę PDF PRZED tworzeniem zamówienia BossOfToys. Jeśli etykieta nie istnieje — zamówienie jest pomijane i moduł spróbuje ponownie w następnym CRON. Nigdy nie duplikuje zamówień dzięki tabeli forwarded_orders.

Tryb auto_forward: Jeśli boss_api.auto_forward=true, forwarding odbywa się inline po wygenerowaniu etykiety w label_auto_generator.py — bez potrzeby osobnego CRON Order Forwarder.

Rozdział 08

Moduły — Allegro Marketplace

#ModułPlikOpis
1Allegro Clientallegro_client.pyKlient API Allegro z OAuth 2.0. 40+ metod. Tokeny w SQLite kv_store.
2Allegro Scannerallegro_scanner.pySkanuje WC produkty → dopasowanie do katalogu Allegro po EAN/GTIN. Cache TTL 7 dni.
3Allegro Listerallegro_product_lister.pyWystawia oferty. dryRun walidacja, smart zdjęcia (deduplikacja URL), HTML→sekcje Allegro, GPSR, kategoria overrides.
4Allegro Order Syncallegro_order_sync.pyImportuje zamówienia Allegro → WC. Ustawia attribution "Allegro". Deduplikacja przez allegro_synced_orders.
5Allegro Offer Syncallegro_offer_sync.pySynchronizuje stany/ceny WC → oferty Allegro. Kończy oferty przy zerowym stanie, reaktywuje po powrocie.
6Allegro Fulfillmentallegro_fulfillment_sync.pyStatusy WC → Allegro (completed → SENT). Wysyła tracking number.
7Allegro Messagingallegro_messaging_sync.pyAutoresponder wiadomości od kupujących.
8Allegro Eventsallegro_events_poller.pyPoller zdarzeń Allegro. Max 500 w DB. Cursor w kv_store.
9Allegro Cost Backfillallegro_cost_backfill.pyUzupełnia _cost_price z BossOfToys — używane przez moduł rentowności.
10Allegro Repricingallegro_repricing.pyAnaliza cen konkurencji. Tryb manual (czeka na zatwierdzenie) lub auto_apply.

Ważne gotcha — Allegro API

ProblemPoprawne rozwiązanie
Pobieranie etykiety PDFAccept: application/octet-stream (NIE application/pdf!) → 406 bez tego
Status przy tworzeniu ofertyHTTP 202 (Accepted) to sukces — nie tylko 200/201
Opisy — niedozwolone tagi<br> niedozwolony, zamień na </p><p>. Dozwolone inline: <b>, <i>, <u>
Zdjęcia w ofercieTablica URL-i: ["https://..."], NIE obiektów [{"url": "..."}]
Sprawdzanie autoryzacji AllegroSprawdzaj client_id + client_secret — NIE access_token (tokeny są w SQLite)
Tracking statusstatuses[-1] (OSTATNI = najnowszy), odpowiedź jest chronologiczna
Endpoint etykiety/shipment-management/label/commands NIE ISTNIEJE (404). Używaj POST /shipment-management/label

Mapowanie statusów fulfillment

WooCommerceAllegro
processing / on-holdPROCESSING
completedSENT
cancelled / refunded / failedCANCELLED
ℹ️

Allegro nie ma statusu "DELIVERED" dla kurierów — SENT jest statusem końcowym pozytywnym.

Rozdział 09

Moduły — Etykiety i Wysyłka

Label Auto Generator (CRON)

Plik: core/label_auto_generator.py — centralny moduł automatyzacji wysyłki.

Zamówienie "processing" bez etykiety
  │
  ├─ _allegro_checkout_id JEST → Allegro Shipment Management API
  └─ _allegro_checkout_id BRAK → ShipX (InPost) API

Po wygenerowaniu etykiety:
  ├─ Zapis PDF: data/labels/label_{order_id}.pdf
  ├─ Meta WC: _*_shipment_id, _*_tracking_number, _shipping_label_source
  ├─ Pickup Scheduling (Allegro, inline, non-fatal)
  ├─ Auto-forward do BossOfToys (jeśli auto_forward=true)
  └─ NTFY/e-mail przy błędach

3-krokowy flow Allegro (allegro_label_generator.py)

Smart wymiary paczek InPost

RozmiarWymiaryMax wagaMeta produktu
A64 × 38 × 8 cm5 kg_inpost_parcel_size = a
B64 × 38 × 19 cm10 kg_inpost_parcel_size = b
C64 × 38 × 41 cm25 kg_inpost_parcel_size = c
Kurierwymusza kuriera_inpost_parcel_size = courier

System bierze największy gabaryt ze wszystkich produktów w zamówieniu. PHP hook kopiuje meta z produktu do line item przy składaniu zamówienia.

Pickup Scheduling (allegro_pickup_scheduler.py)

KurierZachowaniePowód
InPostskipBossOfToys ma umowę (codzienny odbiór)
GLSskipBossOfToys ma umowę
UPSskipBossOfToys ma umowę
DPDoptionalUstna umowa, konfigurowalne
DHLmust_scheduleBrak umowy — zawsze scheduluj

Shipment Tracking (shipment_tracking.py)

CRON co 30 min. Dwa źródła danych równolegle:

ŹródłoDotyczyKluczowy status → akcja
ShipX APIzamówienia z _shipx_shipment_idcollected_from_sender → WC auto-complete
Allegro Tracking APIzamówienia z _allegro_shipment_idIN_TRANSIT → WC shipped, DELIVERED → WC completed → Fakturownia → Allegro SENT
Rozdział 10

Moduły — Integracje zewnętrzne

Fakturownia.pl

Plik: core/fakturownia_client.py

Empik Marketplace — OR23 i OR24

Plik: core/empik_client.py (Mirakl API)

OperacjaCo robiKiedyMeta WC
OR23Wysyła numer tracking do EmpikaInline po wygenerowaniu etykiety_empik_carrier_tracking_number
OR24Potwierdza wysyłkę → Empik SHIPPEDCRON shipment_tracking gdy kurier odebrał_empik_or24_sent = "1"

Warunek automatycznego OR24: _empik_order_id JEST + _empik_carrier_tracking_number JEST + _empik_or24_sent BRAK + status WC = collected_from_sender LUB shipped/completed

💡

Jeśli CRON nie wyśle OR24 automatycznie, dostępny jest ręczny przycisk "Wyślij OR24" w meta boxie etykiety na zamówieniu WooCommerce.

Rozdział 11

Plugin WordPress

Struktura plików

wordpress-plugin/bossoftoys-manager/
├── bossoftoys-manager.php              ← Główny plik, aktywacja
├── includes/
│   ├── class-bot-api.php               ← Klient HTTP do VPS (X-API-Key)
│   ├── class-bot-admin.php             ← Dashboard, ustawienia, 53+ AJAX handlerów
│   ├── class-bot-cron.php              ← WP-Cron handlery
│   ├── class-bot-labels.php            ← Meta box etykiety na zamówieniu
│   ├── class-bot-inpost-sizes.php      ← Gabaryty InPost per produkt
│   ├── class-bot-geowidget.php         ← Mapa InPost na checkout
│   └── class-bot-allegro-orders.php    ← Dane Allegro na zamówieniu, fix VAT
└── admin/
    ├── views/
    │   ├── dashboard.php               ← Kokpit (statystyki, wykresy, logi)
    │   ├── settings.php                ← Ustawienia (BossOfToys, Allegro, itp.)
    │   ├── schedule.php                ← Harmonogram CRON
    │   ├── page-allegro.php            ← Panel Allegro (oferty, zamówienia, wysyłka)
    │   └── page-logs.php               ← Logi aplikacji
    ├── js/dashboard.js                 ← JavaScript (60+ funkcji)
    └── css/admin.css                   ← Style pluginu

Kluczowe PHP hooki (class-bot-admin.php)

Hook WooCommerceAkcja
woocommerce_order_status_processingPlanuje pobranie faktury z Fakturowni (60s opóźnienie)
woocommerce_order_status_completedPobiera fakturę + upload do Allegro (jeśli zamówienie Allegro)
woocommerce_order_status_changed → completedWysyła fulfillment do Allegro: completed → SENT
woocommerce_new_order_itemKopiuje _inpost_parcel_size z produktu do line item

Meta box etykiety (class-bot-labels.php)

Wyświetlany na stronie zamówienia WC. Zawiera:

Rozdział 12

API REST — mapa endpointów

🔑

Wszystkie endpointy wymagają nagłówka: X-API-Key: {API_SECRET_KEY}

Zadania (jobs)

MetodaEndpointOpis
POST/api/jobs/startUruchom moduł {"module": "stock-sync", "params": {}}
GET/api/jobs/{job_id}Status zadania
GET/api/jobs/{job_id}/logsLogi zadania
POST/api/jobs/{job_id}/stopZatrzymaj zadanie

Etykiety

MetodaEndpointOpis
POST/api/labels/generate/{order_id}Generuj etykietę dla zamówienia
GET/api/labels/download/{order_id}Pobierz PDF etykiety
POST/api/labels/empik/or23/{order_id}Wyślij OR23 do Empika (tracking)
POST/api/labels/empik/confirm-ship/{order_id}Wyślij OR24 do Empika (SHIPPED)

Allegro — główne endpointy

MetodaEndpointOpis
GET/api/allegro/auth-urlURL do autoryzacji OAuth
GET/api/allegro/statusStatus połączenia
GET/api/allegro/offersLista ofert (paginacja, filtry)
PATCH/api/allegro/offers/{id}/priceZmień cenę oferty
POST/api/allegro/offers/bulk-price-updateZbiorcza zmiana cen (%)
GET/api/allegro/ordersLista zamówień
POST/api/allegro/orders/{id}/fulfillmentWyślij fulfillment
GET/api/allegro/messages/threadsWątki wiadomości
POST/api/allegro/messages/threads/{id}/replyOdpowiedz w wątku
GET/api/allegro/issuesDyskusje i reklamacje (beta.v1)
GET/api/allegro/billingRozliczenia
GET/api/allegro/profitabilityRentowność ofert
GET/api/allegro/delivery-servicesUsługi dostawy (diagnostyka)
POST/api/allegro/shipping/pickupsZamów odbiór paczek
POST/api/allegro/shipping/shipments/cancelAnuluj przesyłki
POST/api/allegro/shipping/protocolProtokół nadania PDF
GET/api/allegro/repricing/analysisAnaliza cen vs konkurencja
GET/api/stats/schedulerStatus VPS Schedulera
GET/api/config/wp/testDiagnostyka WordPress AP
Rozdział 13

Przepływ zamówień

Jak system rozpoznaje typ zamówienia?

Meta zamówienia WC: _allegro_checkout_id
  ├─ JEST    → Zamówienie ALLEGRO
  │            Etykieta: Allegro Shipment Management
  │            Tracking: Allegro Tracking API
  │            Faktura: upload do Allegro
  │            Status: sync → Allegro SENT
  │
  ├─ BRAK + _empik_order_id JEST → Zamówienie EMPIK
  │            Etykieta: ShipX (InPost)
  │            OR23: numer trackingu do Empika
  │            OR24: potwierdzenie wysyłki
  │
  └─ BRAK    → Zamówienie SKLEPOWE
               Etykieta: ShipX (InPost)
               Tracking: ShipX API
               Faktura: tylko lokalna

Zamówienie sklepowe — pełny flow

KROK 1 — ZŁOŻENIE
  Klient → WooCommerce → status: processing (po płatności)
  PHP hook → planuje pobranie faktury (60s)
  Geowidget → _inpost_point_id
  PHP hook → _inpost_parcel_size z produktów do line items

KROK 2 — ETYKIETA (CRON: label-generator, co 15 min)
  Brak _allegro_checkout_id → ShipX API
  Odczytuje _inpost_parcel_size → największy gabaryt
  Tworzy przesyłkę ShipX → PDF → data/labels/label_{id}.pdf
  Meta: _shipx_shipment_id, _shipx_tracking_number

  [auto_forward=true] → BossOfToys + status completed

KROK 3 — ŚLEDZENIE (CRON: shipment-tracking, co 30 min)
  ShipX API → status paczki
  "collected_from_sender" → AUTO-COMPLETE WC
  PHP hook (completed) → Fakturownia PDF

GOTOWE ✅

Zamówienie Allegro — pełny flow

KROK 1 — IMPORT (CRON: allegro-order-sync, co 15 min)
  Allegro API → POST /wc/v3/orders
  Drugi PUT: _wc_order_attribution_utm_source="Allegro"
  Meta: _allegro_checkout_id, _allegro_buyer_*, _allegro_delivery_*
  PHP fix: zeruje VAT "zw" na wysyłce

KROK 2 — ETYKIETA (CRON: label-generator, co 15 min)
  Jest _allegro_checkout_id → Allegro Shipment Management
  3-krokowy flow: create → poll → label PDF
  Smart wymiary z _inpost_parcel_size
  Meta: _allegro_shipment_id, _allegro_tracking_number, _allegro_carrier
  Pickup scheduling: DHL → zamów, InPost/GLS/UPS → skip
  [auto_forward=true] → BossOfToys

KROK 3 — ŚLEDZENIE (CRON: shipment-tracking, co 30 min)
  Allegro Tracking API (/order/carriers/{id}/tracking)
  statuses[-1] = najnowszy status
  IN_TRANSIT  → WC: "shipped"
  DELIVERED   → WC: "completed" → Fakturownia → upload faktury
              → Fulfillment sync: Allegro SENT

GOTOWE ✅

Zamówienie Empik

KROK 1 — IMPORT
  Empik → WooCommerce (meta _empik_order_id)

KROK 2 — ETYKIETA + OR23 (label-generator)
  ShipX etykieta → _shipx_shipment_id, _shipx_tracking_number
  OR23 inline: empik_client.send_tracking()
  → _empik_carrier_tracking_number

KROK 3 — OR24 (shipment-tracking, co 30 min)
  "collected_from_sender" + _empik_order_id + tracking + brak or24_sent
  → OR24: empik_client.confirm_ship()
  → Empik: SHIPPED
  → _empik_or24_sent = "1"
  (ręczny fallback: przycisk "Wyślij OR24")

GOTOWE ✅
Rozdział 14

Harmonogram CRON

ModułInterwałParametryPriorytet
Label Generator15 minstatus=processing, limit=20⭐⭐⭐ Krytyczny
Shipment Tracking30 minstatus=processing,completed, limit=50⭐⭐⭐ Krytyczny
Allegro Order Sync15 minhours_back=1⭐⭐⭐ Krytyczny
Order Forwarder15 mindry_run=false⭐⭐ Ważny
Stock Sync30 min⭐⭐ Ważny
Allegro Offer Sync30 minsync_stock=true, sync_prices=true, end_zero_stock=true⭐⭐ Ważny
Price Updater1× dziennie⭐ Normalny
Product Adder1× dziennie⭐ Normalny
Product Deleter1× dzienniedry_run=true⚠️ Uwaga: DRY-RUN!
Allegro Repricingco 6h⭐ Normalny

Kolejność włączania (nowe wdrożenie)

Rozdział 15

Meta dane na zamówieniach WooCommerce

Kluczowe meta (routing systemu)

Klucz metaWartośćZnaczenie
_allegro_checkout_idUUIDZamówienie pochodzi z Allegro → Allegro flow
_empik_order_idstringZamówienie pochodzi z Empika → Empik flow
_shipping_label_source"allegro" / "shipx"Skąd pochodzi etykieta
_inpost_point_idstringID paczkomatu docelowego
_inpost_parcel_sizea/b/c/courierGabaryt paczki (na produkcie i line item)

Meta etykiet Allegro

KluczOpis
_allegro_shipment_idID przesyłki Allegro Shipment Management
_allegro_tracking_numberNumer śledzenia przesyłki
_allegro_carrierNazwa przewoźnika (DHL, InPost, DPD…)
_allegro_label_idID etykiety Allegro
_allegro_label_createdTimestamp wygenerowania
_allegro_pickup_scheduledCzy podjazd kuriera zamówiony
_allegro_shipment_statusAktualny status (IN_TRANSIT, DELIVERED…)

Meta etykiet ShipX

KluczOpis
_shipx_shipment_idID przesyłki ShipX
_shipx_tracking_numberNumer śledzenia
_shipx_statusAktualny status ShipX
_shipx_status_labelCzytelna etykieta PL
_shipx_status_updatedTimestamp ostatniej aktualizacji

Meta Empik

KluczOpis
_empik_order_idID zamówienia Empik Mirakl
_empik_carrier_tracking_numberNumer trackingu (po OR23)
_empik_or24_sent"1" po potwierdzeniu wysyłki

Meta Attribution (Pochodzenie w WC)

KluczWartośćEfekt
_wc_order_attribution_utm_source"Allegro" / "Import z Empik"Wartość w kolumnie "Pochodzenie"
_wc_order_attribution_source_type"utm"Wymagane — bez tego WC nie wyświetla źródła
Rozdział 16

Zależności między modułami

BossOfToys API / XML
        │
        ├──────────────────────────────────┐
        ▼                                 ▼
  Stock Sync ──────────► WooCommerce    Product Adder
  Price Updater ─────────► (REST API)   Product Deleter
  Cost Backfill                │
                               │
        ┌──────────────────────┤
        │                      │
        ▼                      ▼
  Allegro Scanner ──► WooCommerce produkty (EAN)
        │
        ▼
  Allegro Lister ──────────► Allegro API (OAuth 2.0)
                                     │
        ┌────────────────────────────┤
        │                            │
        ▼                            ▼
  Allegro Order Sync          Allegro Offer Sync
        │                            │
        ▼                            ▼
  WooCommerce               Allegro oferty
  (zamówienia)              (stany/ceny)
        │
        ├──────────────────────────────────────┐
        │                                      │
        ▼                                      ▼
  Label Auto Generator                   Order Forwarder
    │         │                                │
    │         │                                ▼
    ▼         ▼                         BossOfToys API
  ShipX   Allegro                       (zamówienie + PDF)
  Label   Label
    │         │
    └────┬────┘
         │
         ▼
  Shipment Tracking ──► ShipX API / Allegro Tracking API
         │
         ├──────────────► AUTO-COMPLETE WC
         ├──────────────► OR24 Empik (jeśli _empik_order_id)
         └──────────────► Fakturownia → upload faktury → Allegro SENT

Kolejność uruchamiania modułów

  1. Label Generator — etykiety muszą być pierwsze
  2. Shipment Tracking — śledzi i auto-complete
  3. Order Forwarder — wymaga etykiety
  4. Allegro Order Sync — import nowych zamówień
  5. Stock Sync — stany magazynowe
  6. Allegro Offer Sync — po sync stanów
  7. Price Updater — ceny
  8. Allegro Fulfillment Sync — na końcu (zależy od etykiet)
Rozdział 17

Historia wersji

WersjaDataKluczowe zmiany
3.32.02026-04-22Empik Marketplace (OR23/OR24), Allegro order attribution fix, strona logów
3.31.02026-03Webhook Circuit Breaker, Allegro Offer Sync rozszerzony, VPS Scheduler stabilność
3.30.02026-03-07Allegro Delivery (Shipment Management API), Dual Shipment Tracking, Smart wymiary InPost
3.29.02026-02-27Shipment Tracking (ShipX), Auto-Forward do BossOfToys, NTFY powiadomienia
3.27.02026-02-13Migracja JSON → SQLite (13 tabel, Repository pattern, data_store adapter)
3.26.02026-02-12Labels v2 (PDF na dysku VPS), deduplication przesyłek, carrier detection
3.20.02026-02VPS Scheduler (zastępuje WP-Cron)
3.8.12026-02Fakturownia.pl (faktury + produkty), upload faktur do Allegro
3.7.02026-02-04Issues API beta.v1, UI/UX refresh panelu Allegro, finanse
3.2.02026-01Allegro Integration v2.0 (GPSR, dryRun, obrazy, opisy, sync, fulfillment)
3.1.02026-01BossOfToys REST API (ceny z rabatami)
3.0.02026-01WordPress Bridge, Dashboard, telemetria, Chart.js
Rozdział 18

Rozwiązywanie problemów

Diagnoza ogólna — pierwsze kroki

  1. Sprawdź logi VPS: WordPress → BossOfToys → Logi
  2. Status API Allegro: GET /api/allegro/status
  3. Diagnostyka WP REST API: GET /api/config/wp/test
  4. Status Schedulera: GET /api/stats/scheduler
  5. Weryfikacja składni: python -m py_compile core/nazwa_modulu.py

Allegro

Brak tokenu / "Nie połączono z Allegro"

Sprawdź czy ALLEGRO_CLIENT_ID i ALLEGRO_CLIENT_SECRET są w .env. Tokeny OAuth są w SQLite (kv_store), nie w configu — autoryzuj przez WordPress → Ustawienia → Allegro.

Zamówienia Allegro — "Pochodzenie: Nieznane"

Wymaga obu meta: _wc_order_attribution_utm_source="Allegro" ORAZ _wc_order_attribution_source_type="utm". WooCommerce może nadpisać attribution w hooku — allegro_order_sync.py wykonuje drugi PUT po zapisie zamówienia.

Błąd 406 przy pobieraniu etykiety

Header Accept: application/octet-stream jest wymagany (NIE application/pdf!).

Endpoint etykiety 404

/shipment-management/label/commands NIE ISTNIEJE. Używaj POST /shipment-management/label.

ObjawRozwiązanie
Duplikaty przesyłek AllegroModuł sprawdza _allegro_shipment_id w meta. Duplikaty → anuluj przez panel WP → Allegro → Wysyłka → Anulowanie.
Pickup DHL się nie dziejeSprawdź allegro.pickup.carrier_overrides.DHL.auto_schedule=true. Błędy są non-fatal — sprawdź logi.
Oferta odrzucona — opisUsuń tagi <br>. Dozwolone: <b> <i> <u>.

WooCommerce / WordPress

ObjawRozwiązanie
403 przy requestach WP REST APIOVH LiteSpeed WAF blokuje python-requests. Wszystkie requesty do /wp-json/wp/v2/* muszą używać Chrome User-Agent.
Klucze WC nie działają na /wp/v2/Normalne — WP REST API wymaga Application Password (WordPress → Użytkownicy → profil).
Błąd generator has no len()get_orders_by_status() zwraca generator. Owijaj w list(): orders = list(woo_client.get_orders_by_status(...))
Gabaryt InPost zawsze ASprawdź _inpost_parcel_size na produktach. Sprawdź PHP hook kopiujący meta do line items.

Empik

ObjawRozwiązanie
OR24 nie poszło automatycznieSprawdź czy OR23 poszedł (_empik_carrier_tracking_number w meta). CRON retryuje co 30 min. Użyj ręcznego przycisku "Wyślij OR24" jako fallback.
OR24 race conditionFix w v3.32.0 — CRON retryuje gdy zamówienie ma status shipped/completed a _empik_or24_sent brak.

Baza danych

ObjawRozwiązanie
Circular import w core/Nigdy nie importuj api.repository w core/. Używaj from core.data_store import data_store — i tylko wewnątrz funkcji.
Stary schemat DB po aktualizacjiMigracje odpala się automatycznie przy python run_api.py. Sprawdź logi startowe.
Dane znikają po restarcieSQLite jest trwała. Sprawdź czy data/api_bridge.db nie jest nadpisywany przy deploy.

Komendy diagnostyczne

# Weryfikacja składni Pythona
python -m py_compile core/allegro_order_sync.py

# Test połączenia Allegro
curl -H "X-API-Key: TWOJ_KLUCZ" https://vps:8000/api/allegro/status

# Test połączenia WordPress
curl -H "X-API-Key: TWOJ_KLUCZ" https://vps:8000/api/config/wp/test

# Status Schedulera VPS
curl -H "X-API-Key: TWOJ_KLUCZ" https://vps:8000/api/stats/scheduler