Appearance
Vendors and their lifecycle
A Vendor is a seller on your marketplace: the party that owns products, fulfils its own slice of each order, and gets paid its share. Almost every other concept in this plugin hangs off a vendor — vendor orders, the ledger, product moderation — so it is worth understanding when a vendor is merely registered and when it is actually selling.
Two independent things decide that: the vendor's status (has the operator accepted them?) and their onboarding (have they finished setting themselves up?).
Status
Every vendor carries a status, driven by a state machine (graph odiseo_marketplace_vendor, initial place pending):
| Status | Meaning |
|---|---|
pending | Registered, awaiting the operator's decision. |
approved | Accepted by the operator. |
rejected | Turned down. |
suspended | Previously approved, then withdrawn by the operator. |
Transitions: approve (pending, suspended → approved), reject (pending → rejected), suspend (approved → suspended).
A suspended vendor can be re-approved; a rejected one cannot. Approving, rejecting and suspending all accept a statusReason, shown to the vendor and included in the notification email.
By default a vendor registering from the storefront lands in pending and waits for an administrator. Set vendor.approval_mode to auto to approve them the moment they register instead.
Live
Status alone is not enough to sell. A vendor is live — its products purchasable, its storefront reachable — only when all of these hold:
- status is
approved, - the vendor is
enabled, - the vendor belongs to at least one channel,
- every required onboarding step is complete.
The first three are the vendor's own state (VendorInterface::isLive()). The fourth is delegated to the onboarding step registry, because a subplugin can add steps the core knows nothing about — so the full check lives in VendorLivenessCheckerInterface:
php
<?php
/** @var \Odiseo\SyliusMarketplacePlugin\Onboarding\VendorLivenessCheckerInterface $checker */
$checker = $this->container->get('odiseo_marketplace.onboarding.vendor_liveness_checker');
$checker->isLive($vendor); // approved + enabled + has channels + onboarding completeWARNING
Use VendorLivenessCheckerInterface::isLive(), not the entity's own isLive(), whenever you mean "can this vendor sell". The entity method deliberately skips onboarding — it has no way to know which steps a subplugin registered.
This distinction is also why the shop catalogue queries and the single-product check behave differently: SQL filters can express conditions 1–3 but not 4. See Product authoring and moderation.
Onboarding
After being approved, a vendor is walked through an onboarding wizard in the seller panel (/seller/onboarding). The core ships three required steps:
| Position | Step | Complete when |
|---|---|---|
| 10 | Store profile | The vendor has filled in a description. |
| 20 | Payout method | The vendor has at least one payout method. |
| 30 | Billing address | The vendor has billing data with an address. |
The seller login success handler redirects a vendor into the wizard until every required step reports complete, at which point onboardingCompletedAt is stamped. Steps are an extension point — add KYC, tax details or anything else by tagging a service, see Onboarding steps.
Trusted vendors
trusted is a separate flag, orthogonal to status. It only affects product moderation: a trusted vendor's products are approved automatically the moment they are submitted, instead of queueing for review. It grants no other privilege.
Vendor plans
A vendor may be assigned a VendorPlan, which carries the commission percentage applied to that vendor's sales. With no plan, the marketplace's default fee applies. How the fee turns into an operator commission is covered in Settlement and the ledger, and the whole calculation is replaceable — see Commission calculator.