Appearance
Installation
Seems you'd like to create an online marketplace. Great! Let's start with the first step — make sure you meet the requirements before you begin.
0. Configure access to the private package repository
This plugin is distributed through Odiseo's own package repository, not the public Packagist. Register it and store your credentials — issued per license, so they're different for every client — using Composer's own credential store rather than pasting them into composer.json:
bash
composer config repositories.odiseo composer https://distribution.odiseo.io
composer config http-basic.distribution.odiseo.io <your-username> <your-password>The first command adds a repositories entry to composer.json (safe to commit, no secret in it). The second writes your credentials to auth.json in the project root — add /auth.json to your .gitignore and never commit it. If you don't have credentials yet, contact Odiseo: they're handed over at purchase time and tied to your license.
1. Require the package
bash
composer require odiseoteam/sylius-marketplace-plugin --no-scripts2. Check the bundles are enabled
Composer/Flex registers both bundles for you as part of step 1 — the vendor plugin through its recipe, the marketplace plugin through an ad hoc one Flex derives on the fly. So they are normally already there by the time you get here:
php
// config/bundles.php
return [
// ...
Odiseo\SyliusVendorPlugin\OdiseoSyliusVendorPlugin::class => ['all' => true],
Odiseo\SyliusMarketplacePlugin\OdiseoSyliusMarketplacePlugin::class => ['all' => true],
];If either line is missing (Flex disabled, or the recipe was rejected/skipped), add it yourself — it's safe to add even if it's already there.
3. Import the plugin configuration
yml
# config/packages/_sylius.yaml
imports:
# ...
- { resource: "@OdiseoSyliusMarketplacePlugin/config/config.yaml" }4. Add the API, shop, admin and seller routes
yml
# config/routes.yaml
odiseo_sylius_marketplace_api:
resource: "@OdiseoSyliusMarketplacePlugin/config/routing/api.yaml"
odiseo_sylius_marketplace_seller:
resource: "@OdiseoSyliusMarketplacePlugin/config/routing/seller.yaml"
prefix: /seller
odiseo_sylius_marketplace_admin:
resource: "@OdiseoSyliusMarketplacePlugin/config/routing/admin.yaml"
prefix: /admin
odiseo_sylius_marketplace_shop:
resource: "@OdiseoSyliusMarketplacePlugin/config/routing/shop.yaml"
prefix: /{_locale}
requirements:
_locale: ^[A-Za-z]{2,4}(_([A-Za-z]{4}|[0-9]{3}))?(_([A-Za-z]{2}|[0-9]{3}))?$5. Add the traits to your entities and repositories
This is the longest step, and the one where a mistake fails silently. It has its own page:
→ Entity and repository wiring
Come back here when you're done.
6. Add the security configuration for the seller user
The seller panel is a separate firewall/route namespace. Its path prefix is configurable (see Seller route prefix); the snippet below uses the default /seller.
Declare seller before shop
The seller firewall must come before the shop firewall in the firewalls list. Symfony resolves firewalls in declaration order, first match wins, and sylius.security.shop_regex does not exclude /seller — so if shop comes first, every seller request silently gets authenticated through the shop firewall instead: wrong user provider, wrong success handler, no error of any kind. You'll just see shop_auth_profile_token instead of seller_auth_profile_token in the session cookie.
yml
# config/packages/security.yaml
security:
providers:
# ...
odiseo_marketplace_seller_user_provider:
id: odiseo_marketplace.security.seller_user_provider
firewalls:
# ...
# This must come before the "shop" firewall entry — see the note above.
seller:
context: seller
pattern: "%odiseo_marketplace.security.seller_regex%"
provider: odiseo_marketplace_seller_user_provider
form_login:
provider: odiseo_marketplace_seller_user_provider
login_path: odiseo_marketplace_seller_login
check_path: odiseo_marketplace_seller_login_check
failure_path: odiseo_marketplace_seller_login
default_target_path: odiseo_marketplace_seller_dashboard
success_handler: odiseo_marketplace.security.seller_authentication_success_handler
use_forward: false
use_referer: true
logout:
path: odiseo_marketplace_seller_logout
target: odiseo_marketplace_seller_login
access_control:
# ...
- { path: "%odiseo_marketplace.security.seller_regex%/login", role: PUBLIC_ACCESS }
- { path: "%odiseo_marketplace.security.seller_regex%/forgotten-password", role: PUBLIC_ACCESS }
- { path: "%odiseo_marketplace.security.seller_regex%", role: ROLE_ADMINISTRATION_ACCESS }Keep the success_handler
It redirects a seller straight into the onboarding wizard until their setup is complete. Drop it and new vendors land on the dashboard without ever finishing onboarding — which keeps them from going live.
If you also expose the Seller API, it needs its own firewall.
7. Create the vendor logo upload folder
bash
mkdir -p public/media/vendor-logo8. Update the database schema
Both this plugin and the vendor plugin ship their own migrations, covering every odiseo_* table plus the columns they add to Sylius' own tables (sylius_product.vendor_id, sylius_product.moderation_state, sylius_shipping_method.vendor_id, sylius_adjustment.vendor_id). Applying them is all a standard installation needs:
bash
php bin/console doctrine:migrations:migrate
php bin/console cache:clearThat's it — the admin product form's vendor selector, the seller panel and the shop vendor pages are wired automatically by the plugin, no further template overrides needed.
Next: configure your marketplace in the admin panel.