Development of Multi-Vendor Marketplace in 1C-Bitrix
Out of box 1C-Bitrix — tool for single seller. Turn it into marketplace where hundreds of independent sellers manage their goods, orders, payouts — task requiring serious architectural overlay. No "click button get Wildberries" solutions exist. Several third-party modules exist that take on part of work, plus custom development on top.
What needs to be built
Multi-vendor marketplace differs from regular online store in several fundamental ways:
Seller data isolation. Seller A shouldn't see goods, orders, analytics of seller B. In base Bitrix infoblocks and catalog — common. Need to add segregation layer: either separate infoblock per seller (scales poorly), or common infoblock with VENDOR_ID field and filtering on all levels.
Independent management. Each seller — personal cabinet to manage own goods, orders, prices. Not standard /personal/ Bitrix, but custom section with custom components.
Order division. Buyer puts goods from three sellers in cart. In Bitrix this one order in b_sale_order. Need to split into sub-orders, each seller sees only theirs.
Commissions and payouts. Platform takes commission per sale. Need commission calculation per rules and payout mechanism to sellers (manual or automatic via payment APIs).
Architecture for seller data storage
Most practical approach — add seller identifier at catalog infoblock level. Seller registers as Bitrix user in "Sellers" group, his USER_ID used as VENDOR_ID.
Product storage structure:
Main catalog infoblock extended with UF field UF_VENDOR_ID (link to b_user.ID). All catalog components when fetching add filter by UF_VENDOR_ID. In seller cabinet — only elements with his UF_VENDOR_ID.
Alternative for large marketplaces: HighLoad infoblock as intermediate layer storing PRODUCT_ID → VENDOR_ID mapping for quick permission checks.
Sellers table (additional, via HL-infoblock or custom):
| Field | Description |
|---|---|
| UF_USER_ID | User ID in b_user |
| UF_COMPANY_NAME | Legal entity name |
| UF_INN | Tax number |
| UF_STATUS | pending / active / blocked |
| UF_COMMISSION_RATE | % commission (if individual) |
| UF_PAYMENT_DETAILS | Payment details (JSON) |
| UF_RATING | Rating (float) |
| UF_RATING_COUNT | Rating count |
Order division
Most technically complex part. In b_sale_order order is single. Implementation options:
Option 1: Sub-orders as child records. Additional mp_sub_orders table with ORDER_ID, VENDOR_ID, STATUS, TOTAL, COMMISSION. On order creation, trigger (or OnAfterOrderAdd handler) auto creates sub-orders, grouping basket items by product UF_VENDOR_ID. Seller sees only own sub-orders.
Option 2: Separate baskets. Basket on site divided by sellers visually, on checkout separate b_sale_order created per seller. Technically simpler, but complicates UX for buyer (multiple payments or one aggregated).
Option 3: Order item attributes. VENDOR_ID stored in b_sale_basket as custom property via b_sale_basket_props_value. On order view seller sees only own items. Sub-order not created, status managed at item level.
For most projects optimal option 1 or 3 — option 2 inconvenient for buyer with mixed basket.
Seller cabinet
Minimal cabinet content:
-
Product management: add/edit/deactivate. Standard infoblock API with forced
UF_VENDOR_ID = $USER->GetID()on add and filtering on fetch - Order management (sub-orders): list, status change, invoice printing
- Stock and price management: bulk update via CSV upload or AJAX editing
- Analytics: sales per period, top goods, returns. Data from sub-orders with aggregation
- Profile and details: documents, payment data, verification status
- Finance: accrued commissions, payout history, balance
Cabinet implemented as separate site section with template, components and AJAX handlers. Permissions: user in "Sellers" group + UF_VENDOR_ID check on each request.
Commission system
Commissions calculated on sub-order creation or on final status (paid). Logic:
// Simplified pseudocode
$commissionRate = $vendor['UF_COMMISSION_RATE']
?? $categoryRate[$product['IBLOCK_SECTION_ID']]
?? $defaultRate;
$commission = $subOrder['TOTAL'] * $commissionRate / 100;
// Save to finance operations table
MpFinanceTable::add([
'VENDOR_ID' => $vendor['ID'],
'ORDER_ID' => $orderId,
'TYPE' => 'commission',
'AMOUNT' => -$commission,
'STATUS' => 'pending',
]);
Commission can vary: unified for all, by product category, individual per seller, progressive (depends on turnover).
Product moderation
Seller products before publication undergo moderation. Technically status of infoblock element: on add by seller set ACTIVE = N and special status UF_MODERATION_STATUS = 'pending'. Moderator (user in "Moderators" group) sees moderation queue, checks, sets ACTIVE = Y or rejects with comment.
Seller notification on moderation result — via CEvent::Send() or built-in Bitrix notifications.
Technical stack and ready components
Marketplace has several ready multi-vendor solutions: Marketplace Builder (from various studios), Multi-Vendor modules. They handle seller registration, basic cabinet, order division. Custom development needed for specific commission logic, non-standard cabinet, complex integrations.
Recommended approach: take ready module as basis, customize via events and templates. Faster than from scratch, but more expensive than "just configure".
Development timeline
| Component | Timeline |
|---|---|
| Architecture + seller registration + profiles | 3–4 weeks |
| Order division and sub-orders | 3–5 weeks |
| Seller cabinet (basic) | 4–6 weeks |
| Commission system and finance module | 3–5 weeks |
| Product moderation | 1–2 weeks |
| Seller analytics | 2–3 weeks |
| Payout system (manual + API) | 2–4 weeks |
| Total full-featured MVP | 18–29 weeks |
Timelines for ground-up development. Using ready multi-vendor module as basis cuts to 10–16 weeks customization.







