A typical problem: a buyer chooses in-store pickup, arrives at the store, but the item is not on the shelf. The reason — no strict warehouse binding and no real stock check before reservation. We eliminate such situations through proper Click & Collect configuration. Our expertise: over 50 Bitrix projects, certified engineers with guaranteed results.
Click & Collect (online order with in-store pickup) is one of the most popular retail scenarios, especially after the pandemic. But without correct stock and reservation handling, it brings more trouble than benefits. The buyer selects a point where the item is not available, or two people order the last unit simultaneously — and someone leaves disappointed. A proper implementation on 1C-Bitrix solves these problems at the architectural level: strict binding of points to warehouses, stock check in the cart before reservation, and reservation at order placement. Below is how this works in practice with code examples.
Why is it important to bind pickup points to warehouses?
Each pickup point must be strictly bound to a specific warehouse via XML_ID. Only then the system knows which stock to show. Without this binding, pickup becomes a lottery. We use standard Bitrix tables: b_catalog_store and b_catalog_store_product. Example query to check stock:
SELECT s.ID, s.TITLE, s.ADDRESS, sp.AMOUNT FROM b_catalog_store s JOIN b_catalog_store_product sp ON sp.STORE_ID = s.ID WHERE sp.PRODUCT_ID = ? AND s.ACTIVE = 'Y' AND sp.AMOUNT > 0 ORDER BY s.SORT ASC; 1C-Bitrix documentation: warehouse management
How to add the delivery service "Pickup"
In the admin panel: Store → Delivery → Add delivery service → Type: Pickup. Specify the name, activate it, configure the cost (usually zero). Programmatic creation via API gives more flexibility — you can add conditional rules and 1C integration:
\Bitrix\Main\Loader::includeModule('sale'); $deliveryService = \Bitrix\Sale\Delivery\Services\Manager::getList([ 'filter' => ['CODE' => 'self_pickup'], ])->fetch(); if (!$deliveryService) { \Bitrix\Sale\Delivery\Services\Manager::add([ 'NAME' => 'Pickup from store', 'CODE' => 'self_pickup', 'ACTIVE' => 'Y', 'CLASS_NAME' => '\Bitrix\Sale\Delivery\Services\Base', 'CURRENCY' => 'RUB', 'PRICE' => 0, ]); } How to select a pickup point in the cart?
In the sale.order.ajax component template, we display a list of points with stock check. Example:
// Get active warehouses with availability for all cart items $basketItems = $order->getBasket(); $productIds = []; foreach ($basketItems as $item) { $productIds[] = $item->getProductId(); } $storesResult = \Bitrix\Catalog\StoreTable::getList([ 'filter' => ['ACTIVE' => 'Y'], 'select' => ['ID', 'TITLE', 'ADDRESS', 'GPS_N', 'GPS_S'], 'order' => ['SORT' => 'ASC'], ]); $availableStores = []; while ($store = $storesResult->fetch()) { $allAvailable = true; foreach ($productIds as $productId) { $stockResult = \Bitrix\Catalog\StoreProductTable::getList([ 'filter' => ['PRODUCT_ID' => $productId, 'STORE_ID' => $store['ID']], 'select' => ['AMOUNT'], ])->fetch(); if (!$stockResult || $stockResult['AMOUNT'] < $basketItems->getQuantityByProductId($productId)) { $allAvailable = false; break; } } if ($allAvailable) { $availableStores[] = $store; } } How to set up reservation: step-by-step instructions
Reservation is a critical step that determines the reliability of Click & Collect. Incorrect implementation leads to lost items and conflicts with buyers.
-
Create a custom order property
PICKUP_STORE_IDviaStore → Settings → Order properties. Type — list or string with a link to the warehouse table. -
Add an event handler for
OnSaleOrderBeforeSaved. In it, get the selected warehouse ID from the order property and check stock again before reservation. -
Call reservation for each cart item via
\Bitrix\Catalog\StoreProductTable::reserveProduct. Ensure the function returns success before saving the order.
Example handler:
\Bitrix\Main\EventManager::getInstance()->addEventHandler( 'sale', 'OnSaleOrderBeforeSaved', function (\Bitrix\Main\Event $event) { $order = $event->getParameter('ENTITY'); $pickupStoreId = $order->getPropertyCollection() ->getItemByOrderPropertyCode('PICKUP_STORE_ID') ?->getValue(); if (!$pickupStoreId) return; foreach ($order->getBasket() as $basketItem) { \Bitrix\Catalog\StoreProductTable::reserveProduct( $basketItem->getProductId(), (int)$pickupStoreId, $basketItem->getQuantity(), $order->getId() ); } } ); Details of the handler operation
The handler fires before the order is saved — reservation happens atomically. If reservation fails (e.g., the item is not in stock), the order is not saved and the user sees an error. This prevents double sales.Notifications and order statuses for pickup
After the point is selected and the item is reserved, we need to set up notifications for the buyer. When the order moves to the "Ready for pickup" status (usually after processing in 1C), the system sends an email and SMS to the number from the profile: store address, working hours, what to bring. For regular customers, we recommend a personal account with real-time status tracking. Implementation via the OnSaleOrderStatusChange event and email templates. Our experience shows that proper notifications reduce no-shows by 20–30%.
What is included in the work?
| Phase | Duration | Result |
|---|---|---|
| Analytics | 0.5 day | Warehouse scheme, point list |
| Delivery service setup | 1 day | Ready pickup service |
| Point selection development | 1–2 days | Display points with stock in cart |
| Reservation | 1 day | OnSaleOrderBeforeSaved handler |
| Notifications and statuses | 1 day | Email and SMS when ready for pickup |
| 1C integration (optional) | 2–3 days | Stock exchange via CommerceML |
| Testing and documentation | 1 day | Instructions for managers |
Turnkey: from 7 business days. 6-month guarantee on revisions. 1C-Bitrix certificate.
Comparison: built-in mechanism vs custom solution
| Parameter | Built-in pickup | Custom solution with HL-blocks |
|---|---|---|
| Flexibility | Fixed logic | Full freedom |
| Implementation speed | 1–2 days | 3–5 days |
| 1C synchronization | Via warehouses | Any ERP |
A custom solution outperforms the built-in by 2–3 times in flexibility, but requires more time and resources.
To get a cost and timeline estimate for your project, contact us. Request a consultation on Click & Collect setup.
Additional information: delivery services documentation

