darksidepro/sylius-baselinker-plugin

BaseLinker API integration plugin for Sylius 2.1 e-commerce platform with DDD architecture

Maintainers

Package info

github.com/DarkSidePro/sylius-baselinker

Type:sylius-plugin

pkg:composer/darksidepro/sylius-baselinker-plugin

Statistics

Installs: 0

Dependents: 0

Suggesters: 0

Stars: 0

Open Issues: 0

dev-master 2026-03-23 10:40 UTC

This package is auto-updated.

Last update: 2026-03-23 10:46:58 UTC


README

Wtyczka integrująca BaseLinker z platformą e-commerce Sylius ^2.1. Zbudowana w warstwowej architekturze inspirowanej DDD z wydzieleniem warstw Application / Domain / Infrastructure / UI oraz asynchronicznym przetwarzaniem komend przez Symfony Messenger.

Wymagania

Zależność Wersja
PHP ^8.1
Sylius ^2.1
Symfony ^7.0
MySQL/MariaDB dowolna wspierająca utf8mb4

Instalacja

1. Composer

composer require darksidepro/sylius-baselinker-plugin

2. Rejestracja bundle

W config/bundles.php:

return [
    // ...
    DarkSidePro\SyliusBaselinkerPlugin\DarkSideProSyliusBaselinkerPlugin::class => ['all' => true],
];

3. Import konfiguracji

W config/packages/acme_sylius_baselinker.yaml (utwórz plik jeśli nie istnieje):

# config/packages/acme_sylius_baselinker.yaml
DarkSidePro_sylius_baselinker:
    api:
        token: '%env(BASELINKER_API_TOKEN)%'
        endpoint: 'https://api.baselinker.com/connector.php'
        timeout: 30
        max_retries: 3
        rate_limit: 5

    synchronization:
        enabled: true
        interval: 300
        batch_size: 100

    features:
        orders:
            enabled: '%env(bool:BASELINKER_ORDERS_ENABLED)%'
            auto_export: '%env(bool:default:true:BASELINKER_ORDERS_AUTO_EXPORT)%'
            auto_sync_status: '%env(bool:default:true:BASELINKER_ORDERS_AUTO_SYNC_STATUS)%'
            confirmed_only: true
        products:
            enabled: '%env(bool:BASELINKER_PRODUCTS_ENABLED)%'
            auto_sync: '%env(bool:default:true:BASELINKER_PRODUCTS_AUTO_SYNC)%'
            default_inventory_id: '%env(int:default::BASELINKER_DEFAULT_INVENTORY_ID)%'
        inventory:
            enabled: '%env(bool:BASELINKER_INVENTORY_ENABLED)%'
            sync_stock: '%env(bool:default:true:BASELINKER_INVENTORY_SYNC_STOCK)%'
            default_warehouse_id: '%env(default:bl_1:BASELINKER_DEFAULT_WAREHOUSE_ID)%'
        shipping:
            enabled: '%env(bool:default:false:BASELINKER_SHIPPING_ENABLED)%'

4. Import routingu

W config/routes.yaml:

DarkSidePro_baselinker_webhook:
    resource: '../../vendor/darksidepro/sylius-baselinker-plugin/config/routes/webhook.yaml'

DarkSidePro_baselinker_operations:
    resource: '../../vendor/darksidepro/sylius-baselinker-plugin/config/routes/operations.yaml'

5. Konfiguracja Messenger

W config/packages/messenger.yaml dodaj routing komend (lub zaimportuj plik z pluginu):

framework:
    messenger:
        default_bus: command.bus
        buses:
            command.bus:
                middleware: [validation, doctrine_transaction]
            query.bus:
                middleware: [validation]
            event.bus:
                default_middleware: allow_no_handlers
        transports:
            async:
                dsn: '%env(MESSENGER_TRANSPORT_DSN)%'
                retry_strategy:
                    max_retries: 3
                    delay: 1000
                    multiplier: 2
            sync:
                dsn: 'sync://'
        routing:
            'DarkSidePro\SyliusBaselinkerPlugin\Application\Command\Order\ImportOrderFromBaselinkerCommand': async
            'DarkSidePro\SyliusBaselinkerPlugin\Application\Command\Order\ExportOrderToBaselinkerCommand': async
            'DarkSidePro\SyliusBaselinkerPlugin\Application\Command\Order\SynchronizeOrderStatusCommand': async
            'DarkSidePro\SyliusBaselinkerPlugin\Application\Command\Product\SyncProductToBaselinkerCommand': async
            'DarkSidePro\SyliusBaselinkerPlugin\Application\Command\Inventory\UpdateProductStockCommand': async
            'DarkSidePro\SyliusBaselinkerPlugin\Application\Command\Inventory\SyncStockFromBaselinkerCommand': async

6. Migracja bazy danych

Plugin tworzy trzy własne tabele. Wykonaj migrację ręcznie lub przez narzędzie migracji:

Uwaga: Przy rozbudowie obsługi wariantów schemat może zostać uzupełniony o dodatkową tabelę mapowania wariantów — sprawdź katalog migrations/ po aktualizacji pluginu.

# Ręcznie przez migrację SQL:
mysql -u user -p dbname < vendor/darksidepro/sylius-baselinker-plugin/migrations/001_initial_schema.sql

Tabele:

Tabela Opis
DarkSidePro_baselinker_order_mapping Mapowanie ID zamówień Sylius ↔ BaseLinker
DarkSidePro_baselinker_product_mapping Mapowanie ID produktów Sylius ↔ BaseLinker
DarkSidePro_baselinker_sync_log Log operacji synchronizacji

7. Zmienne środowiskowe

Skopiuj .env.example i uzupełnij wartości:

# API
BASELINKER_API_TOKEN=your_api_token_here
BASELINKER_WEBHOOK_SECRET=your_webhook_secret_here
BASELINKER_BASE_URL=https://twojsklep.pl

# Magazyn i inwentarz
BASELINKER_DEFAULT_INVENTORY_ID=307
BASELINKER_DEFAULT_WAREHOUSE_ID=bl_1
BASELINKER_DEFAULT_PRICE_GROUP_ID=

# Mapowanie statusów (Sylius state => BaseLinker status ID)
BASELINKER_STATUS_NEW=6624
BASELINKER_STATUS_FULFILLED=6625
BASELINKER_STATUS_CANCELLED=6626
BASELINKER_IMPORT_LOCALE=pl_PL

# Opcjonalne mapowania statusów płatności/wysyłki (0 = wyłączone)
BASELINKER_STATUS_PAYMENT_PAID=0
BASELINKER_STATUS_PAYMENT_PARTIALLY_PAID=0
BASELINKER_STATUS_PAYMENT_REFUNDED=0
BASELINKER_STATUS_SHIPPING_SHIPPED=0
BASELINKER_STATUS_SHIPPING_PARTIALLY_SHIPPED=0

# Feature flags
BASELINKER_ORDERS_ENABLED=true
BASELINKER_ORDERS_AUTO_EXPORT=true
BASELINKER_ORDERS_AUTO_SYNC_STATUS=true
BASELINKER_PRODUCTS_ENABLED=true
BASELINKER_PRODUCTS_AUTO_SYNC=true
BASELINKER_INVENTORY_ENABLED=true
BASELINKER_INVENTORY_SYNC_STOCK=true
BASELINKER_SHIPPING_ENABLED=false

# Messenger
MESSENGER_TRANSPORT_DSN=doctrine://default

Funkcjonalności

Zamówienia

  • Eksport zamówień z Sylius do BaseLinker (automatyczny po złożeniu lub ręczny)
  • Import zamówień z BaseLinker do Sylius
  • Synchronizacja statusów — zdarzenia Sylius (zmiana stanu zamówienia, płatności, wysyłki) są mapowane na statusy BaseLinker
  • Mapowanie statusów odbywa się przez zmienne środowiskowe (BASELINKER_STATUS_*)

Produkty

  • Eksport produktów do katalogu BaseLinker (batch lub per-produkt)
  • Podstawowe wsparcie wariantów produktów; pełne mapowanie wielowariantowe zależy od konfiguracji i modelu danych integracji
  • Opcja synchronizacji wyłącznie produktów bez istniejącego mapowania (--unmapped-only)

Inwentarz / Stan magazynowy

  • Synchronizacja stanów magazynowych z BaseLinker do Sylius
  • Stan pobierany z jednego magazynu określonego przez BASELINKER_DEFAULT_WAREHOUSE_ID (domyślnie bl_1) — sumowanie wielu magazynów nie jest aktualnie obsługiwane
  • Obsługa webhooków aktualizacji stanu (/baselinker/webhook/stock)
  • Weryfikacja podpisu webhooków przez nagłówek X-BLToken

Znane ograniczenia

Obszar Ograniczenie
Warianty produktów Przy braku jawnego mapowania wariant→BaseLinker produkt może być wysłany z danymi rodzica; pełne wsparcie wielowariantowe wymaga weryfikacji konfiguracji
Stan magazynowy Synchronizacja z jednego magazynu; obsługa wielu magazynów wymaga własnej implementacji StockSyncServiceInterface
Import zamówień Przy braku mapowania statusu BaseLinker → Sylius zamówienie importowane jest ze statusem new; nieznane statusy nie blokują importu

Komendy CLI

# Import zamówień z ostatnich 7 dni (domyślnie)
php bin/console baselinker:orders:import

# Import zamówień z ostatnich 30 dni, limit 200
php bin/console baselinker:orders:import --days=30 --limit=200 --confirmed-only

# Eksport wszystkich zamówień do BaseLinker
php bin/console baselinker:orders:export

# Synchronizacja produktów do BaseLinker
php bin/console baselinker:products:sync --inventory-id=307

# Tylko produkty bez istniejącego mapowania, batch po 50
php bin/console baselinker:products:sync --inventory-id=307 --unmapped-only --batch-size=50

# Test połączenia z API BaseLinker
php bin/console baselinker:test-connection

Endpointy REST (panel admina)

Wszystkie endpointy wymagają uprawnień administracyjnych Sylius.

Metoda Ścieżka Opis
GET /admin/baselinker/orders/list Lista zamówień z BaseLinker
POST /admin/baselinker/order/import Importuj zamówienie po order_id
POST /admin/baselinker/order/export Eksportuj zamówienie po order_id
POST /admin/baselinker/orders/export-batch Batch eksport zamówień
POST /admin/baselinker/stock/sync Synchronizacja stanów magazynowych

Webhooki (publiczne)

Metoda Ścieżka Opis
POST /baselinker/webhook/order Powiadomienie o zmianie zamówienia
POST /baselinker/webhook/stock Powiadomienie o zmianie stanu

Webhooki weryfikują sygnaturę przez nagłówek X-BLToken (BASELINKER_WEBHOOK_SECRET).

Architektura

Plugin stosuje warstwową architekturę inspirowaną DDD z podziałem na cztery warstwy:

src/
├── Application/        # Komendy, zapytania (CQRS), interfejsy serwisów
│   ├── Command/        # Commands + Handlers (Order, Product, Inventory)
│   ├── Query/          # Queries + Handlers
│   ├── EventHandler/   # Obsługa domain events
│   └── Service/        # Interfejsy: OrderMapper, ProductMapper, StockSync...
│
├── Domain/             # Czysta logika biznesowa (bez zależności infrastruktury)
│   ├── Order/          # Value objects, repo interfaces, domain events
│   ├── Product/        # Value objects, repo interfaces, domain events
│   └── Inventory/      # Value objects, repo interfaces, domain events
│
├── Infrastructure/     # Implementacje: HTTP client, mappery, repozytoria Doctrine
│   ├── Baselinker/     # BaselinkerHttpClient + wyjątki API
│   ├── EventListener/  # Subskrybenci zdarzeń Sylius (order state, product)
│   ├── Mapper/         # OrderMapper, ProductMapper
│   ├── Persistence/    # Repozytoria Doctrine + BaseLinker API
│   └── Service/        # StockSyncService, WebhookSignatureVerifier
│
└── UI/                 # Interfejs użytkownika
    ├── Command/         # Komendy konsolowe (bin/console)
    └── Controller/      # WebhookController, OperationsController

Przepływ asynchroniczny

Wszystkie ciężkie operacje (import/eksport zamówień, sync produktów, aktualizacja stanu) są wysyłane przez Symfony Messenger na transport async. Zapytania (Query) i domain events działają synchronicznie.

Wymagane jest uruchomienie workera:

php bin/console messenger:consume async --time-limit=3600

Operacje integracyjne są projektowane jako idempotentne — ponowne przetworzenie tej samej komendy (np. przy retry po błędzie API) nie zduplikuje danych. Asynchroniczny transport oddziela czas odpowiedzi sklepu od opóźnień API BaseLinker, co zapewnia skalowalność przy dużym wolumenie zamówień.

Rozszerzanie

Plugin udostępnia interfejsy, które możesz podmienić przez własne implementacje:

Interfejs Domyślna implementacja Opis
BaselinkerClientInterface BaselinkerHttpClient Klient HTTP API BaseLinker
OrderMapperInterface OrderMapper Mapowanie Sylius Order ↔ BaseLinker
ProductMapperInterface ProductMapper Mapowanie Sylius Product ↔ BaseLinker
StockSyncServiceInterface StockSyncService Synchronizacja stanów magazynowych
WebhookSignatureVerifierInterface WebhookSignatureVerifier Weryfikacja podpisów webhooków
StockWebhookHandlerInterface StockWebhookHandler Obsługa webhooków stanu

Nadpisanie przez alias w services.yaml:

services:
    DarkSidePro\SyliusBaselinkerPlugin\Application\Service\Order\OrderMapperInterface:
        alias: App\Integration\Baselinker\CustomOrderMapper

Testy

# Unit testy
php vendor/bin/phpunit

# Analiza statyczna (PHPStan)
php vendor/bin/phpstan analyse src --level=max

# Code style
php vendor/bin/ecs check src

Licencja

MIT — szczegóły w pliku LICENSE.