Связаться
  • OpenCart
  • Импорт и экспорт
  • v1.0.1

Shared Stock для OpenCart — один остаток для нескольких товаров и значений опций без перепродаж

Модуль для OpenCart 4, 3 и 2.3, который продаёт одну физическую вещь из одного остатка, где бы она ни стояла: отдельным товаром, значением опции в нескольких списках подарочного набора («Вкус 1…5: Ваниль») или в другом наборе. Корзина проверяется по пулу целиком, «Купить» отказывает с оставшимся количеством, а два покупателя, которые в одну и ту же секунду подтверждают последние единицы, не получат их оба. Базовая версия бесплатна; Pro — упаковки, история с CSV, письма «мало» и «закончился». Лицензия навсегда.

Скачать Free
Pro · лицензия навсегда Чем больше сайтов, тем дешевле каждый
Совместимость
OpenCart 4.0.2 – 4.1.x (проверено на 4.1.0.3 с драйвером pdo и 4.0.2.3), 3.0.x (проверено на 3.0.5.0) и 2.3.0.2 (PHP 7.0) · штатный чекаут и наш One Page Checkout · MySQL / MariaDB · языки модуля: украинский, английский, русский
Версия
v1.0.1 (OpenCart 4)
v1.0.1 (OpenCart 3.x)
v1.0.1 (OpenCart 2.3)
Лицензия
один сайт, навсегда
Триал
7 дней, без карты, один на сайт
Или все 173 Pro-модулей в All Access — 4 990 ₴ / год

Что есть во Free,
а что даёт Pro

Бесплатная версия работает без ограничения по времени. Pro добавляет остальные функции из таблицы.

Функция Free Pro
Пулы общего остатка без ограничения количества: участник — товар целиком или отдельное значение опции (Вкус 3: Ваниль) ✔ ✔
Один и тот же пул — в нескольких товарах и нескольких списках опций одного товара: набор с 5 списками «Вкус» и отдельный батончик продаются из одного остатка ✔ ✔
Корзина проверяется по пулу целиком: 2 набора по 5 «Ваниль» = 10 единиц пула ✔ ✔
«Купить» отказывает с оставшимся количеством — в блоке у кнопки, а не как «обязательная опция» ✔ ✔
Корзина помечает строки *** и не пускает дальше, если пул уже не покрывает корзину ✔ ✔
Шаг подтверждения удерживает единицы заказа под блокировкой базы: одновременные покупатели не получат последнюю единицу оба ✔ ✔
Списание при переходе заказа в статус обработки или выполнения (как в OpenCart), возврат при отмене — ровно один раз ✔ ✔
Правка заказа в админке: убранные строки возвращаются в пул, новые списываются ✔ ✔
Количество участника в OpenCart — зеркало пула: значения без остатка исчезают из списка опций, как обычное «нет в наличии» ✔ ✔
Форма товара: новая цифра в поле «Количество» устанавливает пул; старая открытая форма пул не перезаписывает ✔ ✔
«Синхронизировать количества» после импорта: зеркала снова = пул, участники удалённых товаров убираются ✔ ✔
Языки модуля: украинский, английский, русский ✔ ✔
Единиц пула за одну продажу всегда 1 любое число: упаковка из 6 снимает 6
История каждого изменения пула с источником и заказом, экспорт CSV — ✔
Письмо «мало на складе» с порогом на пул и письмо «закончился» — ✔
Массовое добавление: найти значение опции по названию во всех товарах и добавить одним кликом — ✔

Как это выглядит

Отказ «Купить» у кнопки на странице товара OpenCart 4.1
Подарочный набор с 5 списками «Flavour», в каждом выбрано Vanilla, а в пуле «Vanilla» осталось 4: «Купить» отказывает, и покупатель видит причину в блоке над кнопкой.
Отказ «Купить» на телефоне
Тот же блок на телефоне: во всю ширину экрана, над кнопкой корзины; проверено на ширинах 375 и 320 px.
Корзина OpenCart с пометкой *** для пула
Пул уменьшился, пока товар лежал в корзине: строка помечена ***, и OpenCart не пускает к оформлению, пока покупатель не изменит количество.

Главное о модуле

Как это выглядит для покупателя

Покупатель выбирает вкусы в наборе и нажимает «Купить».

Что проверено, а что нет

Проверено локально на четырёх версиях OpenCart: 79 проверок на OpenCart 4.1.0.3 и 4.0.2.3 и по 77 на 3.0.5.0 и 2.3.0.2 по основному сценарию, плюс отдельные прогоны в браузере, с One Page Checkout, правки заказов, импорта и писем Pro.

Триал стартует, когда вы попросите

Свежая установка — бесплатная версия, ничего не включается само. Кнопка «Попробовать Pro 7 дней» → e-mail → ключ сразу в окне и письмом.

Один ключ — один сайт

Переносите магазин — отвяжите лицензию на старом домене и активируйте на новом сами. Для студий — ключи на 5, 25 сайтов или без ограничений.

Технические требования

  • OpenCart 4.0.2.0+ и 4.1.x (проверено на 4.1.0.3 и 4.0.2.3), 3.x (проверено на 3.0.5.0) или 2.3.0.2.
  • PHP 7.0+ — тот, который нужен вашей версии OpenCart (проверено на 7.0, 8.1, 8.2 и 8.3).
  • База MySQL или MariaDB: блокировка между чекаутами — именованная блокировка MySQL (GET_LOCK). Проверено на MariaDB 10.11. На кластере Galera такая блокировка не действует между узлами.
  • «Оформление без наличия» в настройках OpenCart должно быть выключено — иначе OpenCart не проверяет остаток на чекауте, и модуль тоже не отказывает.
  • Почта магазина настроена (System → Settings → Mail) — для писем Pro.
  • Языки модуля: украинский, английский, русский.

Вместе с Shared Stock для OpenCart покупают

4 модуля одним заказом — на 40% дешевле, чем по отдельности

Набор «Старт магазина» Shared Stock Nova Poshta Premium LiqPay Telegram-уведомления и Viber/SMS покупателям Нужно больше — все 173 модулей в All Access за 4 990 ₴.
3 790 ₴ навсегда вместо 6 260 ₴ поштучно
Купить набор →

Полное описание модуля

Shared Stock для OpenCart — модуль от студии CatCode для магазина, который продаёт одну физическую вещь в нескольких местах каталога. Батончик «Ваниль» отдельно — и тот же вкус в подарочном наборе, где покупатель выбирает вкус в пяти списках «Вкус 1…5». Тот же товар в другом наборе. OpenCart считает остаток каждого товара и каждого значения опции отдельно, поэтому владелец магазина переписывает цифры вручную — и всё равно продаёт последнюю единицу дважды.

Shared Stock объединяет такие места в пул — одну цифру остатка, из которой продают все они. Участником пула может быть товар целиком или отдельное значение опции. Корзина проверяется по пулу целиком: набор с пятью «Ваниль» в количестве 2 берёт из пула 10. Продажа любого участника снимает с пула, а каждый участник показывает, сколько пул ещё может покрыть. Два покупателя, которые в одну и ту же секунду подтверждают последние единицы, не получат их оба.

Это не дубль Option Combinations. Option Combinations ведёт остаток комбинаций опций внутри одного товара (размер × цвет). Shared Stock решает другой сценарий: один остаток для разных товаров и значений опций — тот же вкус отдельным товаром, в пяти списках набора и в другом наборе. Первый модуль не делит остаток между товарами, второй не ведёт комбинаций внутри товара.

Как это выглядит для покупателя

Покупатель выбирает вкусы в наборе и нажимает «Купить». Если вместе с тем, что уже лежит в корзине, пула не хватает, OpenCart не добавляет товар, а над кнопкой появляется понятное предложение: сколько ещё осталось или что всё уже в корзине. Значение, которое пул уже не может покрыть, исчезает из списка опций, как обычное «нет в наличии».

Если пул уменьшился, пока товар лежал в корзине (другой покупатель успел купить), корзина помечает строку *** и не пускает к оформлению — это штатное поведение OpenCart для остатка, только считается оно по пулу.

Что получает админ

  • Каталог → Общий остаток: пулы с остатком, удержанным неподтверждёнными заказами, и доступным; создание пула. Пустой новый пул берёт остаток первого добавленного участника.
  • Страница пула: «Добавить / списать (±N)» относительно текущего — поставка, оформленная во время заказов, не потеряется; «Установить» для инвентаризации; порог письма (Pro); участники с их количеством в OpenCart; поиск товара и добавление целого товара или одного значения опции; список удержаний неподтверждённых заказов.
  • Форма товара: строка под полем «Количество» с названием пула. Новая цифра в этом поле или в количестве значения опции устанавливает пул, а старая цифра из давно открытой формы — нет.
  • «Синхронизировать количества» — после CSV-импорта или другого модуля, который пишет количества напрямую: зеркала снова показывают пул, участники удалённых товаров убираются.

Как это работает — шаг за шагом

  1. Вы создаёте пул (например, «Ваниль»), задаёте остаток и добавляете участников: батончик целиком и значение «Ваниль» из каждого списка набора. Количество каждого участника в OpenCart становится зеркалом пула.
  2. Покупатель добавляет товар в корзину. Модуль считает, сколько единиц каждого пула просит вся корзина, с учётом того, что удерживают неподтверждённые заказы других покупателей, и отказывает с объяснением, если не хватает.
  3. На шаге подтверждения — отдельным запросом или внутри страницы оформления OpenCart 4 и One Page — модуль берёт блокировку базы, ещё раз проверяет корзину по пулу и удерживает единицы заказа. Другой покупатель, который подтверждает в ту же секунду, ждёт своей очереди и видит уже меньшую цифру. Очередь дольше 10 секунд (настраивается) — покупатель получает отказ, а не риск продать дважды.
  4. Когда заказ переходит в статус обработки или выполнения, модуль снимает единицы с пула — ровно один раз на строку заказа — и обновляет количество всех участников. Отмена возвращает единицы.
  5. Удержание неподтверждённого заказа живёт 60 минут (настраивается), потом единицы снова доступны другим покупателям.

Что проверено, а что нет

Проверено локально на четырёх версиях OpenCart: 79 проверок на OpenCart 4.1.0.3 и 4.0.2.3 и по 77 на 3.0.5.0 и 2.3.0.2 по основному сценарию, плюс отдельные прогоны в браузере, с One Page Checkout, правки заказов, импорта и писем Pro. Версию 1.0.1 — тем же набором, плюс пять прогонов подряд одновременных загрузок страницы оформления (штатной и One Page) на OpenCart 4.1 и 4.0.2.3 — каждый раз ровно 2 заказа из 8, пул не ниже нуля — и 24 комбинации языка магазина и языка покупателя для сообщения «в корзину». Лицензионный сервер и почту подменяли тестовые серверы.

Границы, о которых стоит знать. Защита от одновременных покупателей стоит на шаге подтверждения заказа — и тогда, когда он идёт отдельным запросом, и когда OpenCart 4 или наш One Page открывает его внутри страницы оформления. Сторонний one-page чекаут, который записывает заказ в обход этого шага, проверяет корзину без блокировки; удержание модуль и тогда пишет, только если пул его покрывает. Заказ, оплаченный уже после того, как его удержание истекло (60 минут по умолчанию), списывает пул даже в минус — так же, как OpenCart без модуля; это видно в истории пула. Не проверяли: платёжные шлюзы с обратным вызовом банка, сторонние one-page чекауты (кроме нашего), совместную работу с Option Combinations, варианты товаров OpenCart 4 (master / variant), MySQL 8 и кластеры Galera.

Что под капотом

  • Пул — в собственной таблице. Количества участников в OpenCart лишь показывают, сколько пул ещё может покрыть; чекаут считает по пулу.
  • Одно списание на строку. Строка заказа снимает с пула один раз (условное обновление в базе), так что повторная смена статуса или повторная отмена ничего не удваивает.
  • Удержание на подтверждении. Заказ, дошедший до шага подтверждения, удерживает свои единицы; повторное открытие шага тем же покупателем заменяет удержание, а не добавляет второе.
  • Без правок ядра и без OCMOD-патчей — только события OpenCart; одна библиотека на три сборки, код совместим с PHP 7.0, работает и с драйвером базы pdo в OpenCart 4.1.
  • Лицензия — отдельной группой настроек, так что сохранение настроек её не затрагивает.
  • Удаление снимает события и таблицы модуля (можно оставить данные для повторной установки).

Как установить

  1. OpenCart 4: Расширения → Установщик → загрузите cc_sharedstock.ocmod.zip (имя архива не меняйте) и нажмите «Установить». OpenCart 3: Расширения → Установщик → cc_sharedstock-oc3.ocmod.zip → «Установить». OpenCart 2.3: Расширения → Установщик → cc_sharedstock-oc2.ocmod.zip, если в настройках магазина включён FTP; иначе залейте содержимое папки upload/ из архива в корень магазина.
  2. Расширения → Расширения → Модули → Shared Stock → «Установить».
  3. Каталог → Общий остаток: создайте пул и добавьте участников — товар целиком или значение опции.
  4. Задайте остаток пула или оставьте поле пустым — тогда пул возьмёт остаток первого добавленного участника.
  5. Для Pro: вставьте лицензионный ключ из письма после оплаты или включите триал на вкладке «Лицензия» настроек модуля.

Вопросы
о модуле

Не нашли ответ? Напишите в Telegram — ответим в течение рабочего дня.

@catcode_support Настройка, совместимость, активация
Чем это отличается от Option Combinations?

Option Combinations ведёт остаток комбинаций опций внутри одного товара. Shared Stock нужен, когда одна и та же вещь продаётся в нескольких товарах или в нескольких списках опций: отдельный батончик «Ваниль», «Ваниль» в каждом из списков «Вкус 1…5» подарочного набора, тот же вкус в другом наборе. То есть это не дубль, а другой сценарий: один остаток для разных товаров и опций. Совместную работу обоих модулей в одном магазине мы ещё не проверяли.

Это действительно защищает от перепродажи, когда двое платят одновременно?

Да, на шаге подтверждения: заказ удерживает свои единицы под блокировкой базы, второй покупатель ждёт и видит, что пула уже не хватает. В тесте 8 покупателей одновременно подтверждали по 4 единицы из пула на 10 — прошло ровно 2 заказа, пул ни разу не ушёл в минус; без модуля тот же тест пропускал все 4 из 4 первых. С версии 1.0.1 так же защищён случай, когда OpenCart 4 или One Page записывает заказ уже при загрузке страницы оформления: 8 одновременных загрузок — ровно 2 заказа, в 5 прогонах подряд.

Когда единицы снимаются с пула?

Когда заказ переходит в статус обработки или выполнения — как OpenCart списывает остаток товара. Отмена возвращает единицы, повторная отмена ничего не возвращает второй раз. Неподтверждённый заказ лишь удерживает единицы на время из настроек (60 минут по умолчанию).

Что станет с количеством товара, когда он войдёт в пул?

Количество участника в OpenCart становится зеркалом пула и считается модулем. Пустой новый пул берёт остаток первого добавленного участника, так что цифра не обнуляется. Новая цифра, введённая в поле «Количество» товара или значения опции, устанавливает пул.

Импорт из CSV перезаписал количества — что делать?

Витрина по-прежнему считает по пулу, так что лишнего не продаст. Нажмите «Синхронизировать количества» на странице пулов — зеркала снова покажут цифру пула. Если импорт несёт новую фактическую цифру остатка, введите её в пул.

Работает с нашим One Page Checkout?

Да, мы проверили их вместе на OpenCart 4.1, 4.0.2.3, 3.0 и 2.3: заказ через One Page, отказ, когда пул стал меньше корзины, и одновременные подтверждения, в том числе когда One Page записывает заказ при загрузке страницы.

Интерфейс на русском?

Да: админка модуля — на русском, украинском и английском, а сообщения покупателю — на языке, который он выбрал на витрине (с версии 1.0.1 и на OpenCart 3 и 2.3).

Лицензия на год?

Нет. Для OpenCart это одна оплата, лицензия навсегда, и она одна на все три сборки: 4.x, 3.x и 2.3. Пулы, проверка корзины и защита на подтверждении — в бесплатной версии без ограничения по времени.

Не тот вариант, что искали?

Делаем кастомные модули под WordPress, WooCommerce, OpenCart и Shopify. Расскажите о задаче — подготовим оценку.

Заказать кастомный модуль