Supplier Portal for Dropshipping on 1C-Bitrix
On one project with 60 suppliers, a manager spent 3 hours daily synchronizing stock via Excel. After implementing a supplier portal, that time dropped to 10 minutes. Many dropshipping stores face the same pain: suppliers can't see their orders, update prices via email, and manual entry errors reach 12%. Building a separate personal cabinet for each supplier on 1C-Bitrix solves these issues: isolated permissions, their own products and orders, bulk CSV upload. We automate the routine so a supplier spends 15 minutes instead of 4 hours—and errors approach zero.
Our experience: over 10 years of Bitrix development, 50+ e-commerce projects. We guarantee stable operation of the cabinet under load up to 100 simultaneously active suppliers. We will assess your project within 2 days: contact us for a consultation.
How to Organize Permission Differentiation for Suppliers
In Bitrix, permission differentiation is implemented via user groups. We create a "Suppliers" group through the API:
$groupId = CGroup::Add([ 'ACTIVE' => 'Y', 'NAME' => 'Suppliers', 'STRING_ID' => 'SUPPLIERS', ]); Linking a specific supplier to their products is done via an HL-block SupplierProduct or an infoblock property SUPPLIER_ID of type "Link to user" (E). The supplier cabinet section is protected by checking the group:
if (!$USER->IsAuthorized() || !$USER->IsInGroup($supplierGroupId)) { LocalRedirect('/auth/?backurl=' . urlencode($_SERVER['REQUEST_URI'])); } More about user groups in the documentation.
Cabinet Components: Products, Orders, Prices
What's Included in the "My Products" Block?
A list of the supplier's products with current stock and price. Query via CIBlockElement::GetList filtered by SUPPLIER_ID:
$userId = $USER->GetID(); $res = CIBlockElement::GetList( ['NAME' => 'ASC'], [ 'IBLOCK_ID' => CATALOG_IBLOCK_ID, 'ACTIVE' => 'Y', 'PROPERTY_SUPPLIER_ID' => $userId, ], false, false, ['ID', 'NAME', 'DETAIL_PAGE_URL', 'PREVIEW_PICTURE', 'PROPERTY_SUPPLIER_ID'] ); For each product, we show current stock from b_catalog_store_product and price from b_catalog_price. Each supplier has their own warehouse (b_catalog_store)—this allows independent stock tracking.
How Does a Supplier Update Prices and Stock?
The supplier sends an AJAX request from a form. The handler checks product ownership and performs the update:
// /local/ajax/supplier-update.php $productId = (int)$_POST['product_id']; $newPrice = (float)$_POST['price']; $newQty = (int)$_POST['quantity']; $ownerCheck = CIBlockElement::GetProperty( CATALOG_IBLOCK_ID, $productId, 'sort', 'asc', ['CODE' => 'SUPPLIER_ID', 'VALUE' => $USER->GetID()] ); if (!$ownerCheck->Fetch()) { echo json_encode(['error' => 'Access denied']); die(); } $priceRow = CCatalogPrice::GetList( [], ['PRODUCT_ID' => $productId, 'CATALOG_GROUP_ID' => BASE_PRICE_GROUP_ID] )->Fetch(); if ($priceRow) { CCatalogPrice::Update($priceRow['ID'], ['PRICE' => $newPrice, 'CURRENCY' => 'RUB']); } else { CCatalogPrice::Add([ 'PRODUCT_ID' => $productId, 'CATALOG_GROUP_ID' => BASE_PRICE_GROUP_ID, 'PRICE' => $newPrice, 'CURRENCY' => 'RUB', ]); } $storeProductRow = CCatalogStoreProduct::GetList( [], ['PRODUCT_ID' => $productId, 'STORE_ID' => getSupplierStoreId($userId)] )->Fetch(); if ($storeProductRow) { CCatalogStoreProduct::Update($storeProductRow['ID'], ['AMOUNT' => $newQty]); } else { CCatalogStoreProduct::Add([ 'PRODUCT_ID' => $productId, 'STORE_ID' => getSupplierStoreId($userId), 'AMOUNT' => $newQty, ]); } echo json_encode(['success' => true]); How Does a Supplier See Their Orders?
The supplier sees only orders containing their products. A direct query to b_sale_order is not suitable—we need a link through the basket:
$supplierId = $USER->GetID(); $connection = \Bitrix\Main\Application::getConnection(); $orders = $connection->query(" SELECT DISTINCT o.ID, o.DATE_INSERT, o.PRICE, o.STATUS_ID, o.USER_ID, u.NAME, u.LAST_NAME, u.EMAIL FROM b_sale_order o JOIN b_sale_basket b ON b.ORDER_ID = o.ID JOIN b_iblock_element_property ep ON ep.IBLOCK_ELEMENT_ID = b.PRODUCT_ID AND ep.IBLOCK_PROPERTY_ID = " . SUPPLIER_PROP_ID . " AND ep.VALUE_NUM = {$supplierId} LEFT JOIN b_user u ON u.ID = o.USER_ID WHERE o.DATE_INSERT >= DATE_SUB(NOW(), INTERVAL 90 DAY) ORDER BY o.DATE_INSERT DESC LIMIT 100 "); On the order details page, the supplier sees only their basket items.
Shipment Confirmation and Statuses
The supplier confirms shipment of their part of the order through the interface. Statuses are stored in the HL-block SupplierShipment with fields: UF_ORDER_ID, UF_SUPPLIER_ID, UF_STATUS (pending/confirmed/shipped/delivered), UF_TRACKING, UF_DATE_SHIPPED. When all suppliers for an order have set status shipped, an agent automatically changes the order status in Bitrix to "Shipped".
Bulk Upload via CSV
For suppliers with a large assortment (5000+ items), we provide a CSV upload form with columns: SKU, price, stock. The PHP handler finds the product by CML2_ARTICLE, checks supplier ownership, and updates price and stock if correct. A row limit (up to 5000) prevents PHP timeout. For larger batches, we use background agents.
Comparison of Supplier Management Approaches
| Approach | Manual Management | Our Supplier Portal |
|---|---|---|
| Time to update 100 products | 2 hours | 5 minutes |
| Error risk | 12% | <1% |
| Data access | Full admin access | Only own products and orders |
| Scalability | Up to 10 suppliers | 100+ suppliers |
Development Stages
| Stage | Duration | Outcome |
|---|---|---|
| Analytics | 1–2 days | Requirements, prototypes, role model |
| Design | 2–3 days | DB architecture, component structure |
| Implementation | 5–10 days | Ready functionality: components, AJAX, integrations |
| Testing | 2–3 days | Rights verification, load testing up to 100 sessions |
| Deployment & documentation | 1–2 days | Installation, caching, manager training |
Total timeline: from 1 to 4 weeks depending on complexity (basic cabinet—1–1.5 weeks, full with warehouse and CSV—2–3 weeks, multilingual with analytics—3–4 weeks).
Why Standard Personal Account Doesn't Fit?
The built-in my module in Bitrix is aimed at buyers: shopping cart, order history, personal data. A supplier needs different entities—stock management, bulk upload, shipment tracking. Moreover, without additional configuration, a supplier cannot be restricted to only their products. Hence, a separate component solution with its own permission system is required.
Typical Mistakes We Prevent
- Lack of permission checks on AJAX requests—an attacker could update others' prices. All handlers verify SUPPLIER_ID.
- No tagged caching—with 100 suppliers, page load exceeds 10 seconds. We use caching with user tags.
- Supplier warehouse not created automatically—all suppliers' stock get mixed. We create a warehouse upon supplier registration via the OnBeforeUserRegister event.
Benefits of Automation
Automated data exchange with suppliers is 5 times faster than manual entry. Errors in manual updates occur in 12% of transactions—with our portal, this rate approaches zero. Each supplier saves at least 3 hours per day on stock reconciliation.
Get a consultation on cabinet architecture—describe your situation, and we will offer the optimal solution. Order a turnkey supplier portal and start accepting orders in 1–2 weeks.

