Почему сайт показывает неверные остатки?
Мы сталкивались с ситуацией, когда интернет-магазин на 1С-Битрикс показывает 10 единиц товара, а на физическом складе уже давно пусто. Клиент делает заказ, мы передаём его в 1С, а там — отказ. Overselling съедает до 20% выручки, а убытки могут превышать $1.8k–2.6k ежемесячно. Стандартная синхронизация через <cite>CommerceML</cite> запускается раз в 15–60 минут. Этого недостаточно при интенсивных продажах: расхождение накапливается. Наши инженеры решают эту задачу с помощью вебхуков и документооборота в реальном времени.
Какие подходы к синхронизации существуют?
Сравним два основных метода:
| Метод | Частота обновления | Задержка | Подходит для |
|---|---|---|---|
| CommerceML | По расписанию (15-60 мин) | Высокая | Небольшие интернет-магазины |
| Вебхуки | В реальном времени | Секунды | Магазины с высокими продажами |
CommerceML — стандартный протокол обмена с 1С, описанный в CommerceML. Он надежен, но не подходит для сценариев, где остатки меняются быстро. Вебхуки обновляют данные за 1-2 секунды — это в 30 раз быстрее, чем CommerceML. Наш опыт — более 50 проектов с вебхуками — показывает, что окупаемость такого решения наступает за полгода.
Как мы реализуем обновление в реальном времени?
Для минимизации расхождения — интеграция кассы с Битрикс в реальном времени. При каждой продаже на офлайн-кассе немедленный webhook в Битрикс. Шаги реализации:
- Создать endpoint на PHP, принимающий JSON от кассы.
- Проверить данные и найти товар по SKU.
- Создать складской документ типа «S» (продажа) через
DocumentTable. - Провести документ вызовом
conduct()— это автоматически обновит остатки вb_catalog_store_product. - Инвалидировать кеш товара.
Пример реализации вебхука
// /local/ajax/pos-sale-callback.php $data = json_decode(file_get_contents('php://input'), true); foreach ($data['items'] as $item) { $product = \CCatalogProduct::GetByID($item['sku']); if (!$product) continue; // Уменьшаем остаток на конкретном складе \Bitrix\Catalog\StoreProductTable::update( ['PRODUCT_ID' => $item['product_id'], 'STORE_ID' => $data['store_id']], ['AMOUNT' => new \Bitrix\Main\DB\SqlExpression('AMOUNT - ?', $item['quantity'])] ); // Пересчитываем суммарный остаток в b_catalog_product \CCatalogProduct::RecalcQuantity($item['product_id']); } RecalcQuantity() пересчитывает b_catalog_product.QUANTITY как сумму по всем складам в b_catalog_store_product. После этого кеш товара должен быть инвалидирован — через BXClearCache(false, '/catalog/') или тегированный кеш. Мы гарантируем, что время обновления не превышает 2 секунд.
Как резервировать остатки для онлайн-продаж?
Частая практика для магазинов с несколькими каналами продаж: выделить отдельный «онлайн-склад» в b_catalog_store, остатки которого предназначены только для интернет-магазина. Физически товар может быть на одном складе, но логически разделён.
При этом офлайн-продажи уменьшают «физический склад», а онлайн-заказы резервируются из «онлайн-склада». Ночью 1С пополняет онлайн-склад из физического по заданной пропорции.
Физический склад: 100 единиц Онлайн-квота: 30% = 30 единиц → хранится в b_catalog_store_product (STORE_ID = online_store) Офлайн-квота: 70% = 70 единиц → не попадает в Битрикс Это исключает ситуацию overselling, но снижает доступный остаток для онлайн-продаж. Мы подбираем пропорцию индивидуально, опираясь на статистику продаж.
Как работает документооборот?
В Битрикс модуль catalog поддерживает складские документы: \Bitrix\Catalog\Document\DocumentTable. Типы документов: A — приход, S — продажа, M — перемещение, R — возврат.
При проведении документа через \Bitrix\Catalog\Document\DocumentController::conduct() автоматически пересчитываются остатки в b_catalog_store_product. Это правильный способ двигать остатки — через документы, а не прямым UPDATE.
Для офлайн-продаж: при получении webhook от кассы создаём документ типа S с позициями продажи и проводим его. Это обеспечивает полную историю движения товара и корректный складской учёт.
Инвентаризация и сверка
Расхождения между 1С и Битрикс неизбежны. Важно уметь их находить. Раз в сутки запускаем агент-сверщик:
// Получаем остатки из 1С через REST API $bx1cItems = get1cQuantities(); // Сравниваем с b_catalog_store_product foreach ($bx1cItems as $sku => $qty) { $bitrixQty = StoreProductTable::getList([ 'filter' => ['PRODUCT.XML_ID' => $sku], 'select' => ['AMOUNT'], ])->fetch()['AMOUNT'] ?? 0; if (abs($bitrixQty - $qty) > 0) { logDiscrepancy($sku, $bitrixQty, $qty); } } Лог расхождений позволяет принять решение: корректировать Битрикс по 1С (1С — мастер) или сигнализировать о проблеме в интеграции. После внедрения экономия для клиента составляет до $4.5k–6.5k в год за счёт устранения overselling и ручной сверки.
Что входит в настройку под ключ
В каждом проекте мы предоставляем:
- Аудит текущей схемы складского учета и точек интеграции
- Выбор оптимального протокола синхронизации (CommerceML или вебхуки)
- Разработку endpoint под вебхуки от касс и POS-терминалов
- Настройку документооборота: приход, продажа, перемещение, возврат
- Внедрение агента сверки остатков с логированием расхождений
- Обучение персонала работе с обновленной системой
- Подробную документацию по интеграции и настройкам
- Техническую поддержку в течение месяца после запуска
Этапы и сроки работ
| Этап | Длительность | Результат |
|---|---|---|
| Аналитика | 2-3 дня | Схема интеграции, выбор метода синхронизации |
| Проектирование | 3-5 дней | Техническое задание, прототип |
| Разработка | 5-10 дней | Вебхуки, документы, агент сверки |
| Тестирование | 3-5 дней | Проверка на реальных данных, устранение ошибок |
| Запуск | 1-2 дня | Деплой, обучение персонала |
Сроки — от 2 до 4 недель. Инвестиции рассчитываются индивидуально в зависимости от сложности. Окупаемость — 4–6 месяцев. Мы сертифицированные специалисты 1С-Битрикс с опытом более 10 лет. Гарантируем, что после настройки расхождения остатков не превысят 0.1% при условии стабильной работы каналов связи.
Если вы заметили расхождения остатков в своем магазине, закажите аудит и получите план синхронизации. Свяжитесь с нами для консультации.







