Розробка модуля підписки на товари 1С-Бітрікс

Наша компанія займається розробкою, підтримкою та обслуговуванням рішень на Бітрікс та Бітрікс24 будь-якої складності. Від простих односторінкових сайтів до складних інтернет-магазинів, CRM систем з інтеграцією 1С та телефонії. Досвід розробників підтверджено сертифікатами від вендора.
Пропоновані послуги
Показано 1 з 1 послугУсі 1626 послуг
Розробка модуля підписки на товари 1С-Бітрікс
Середня
~1-2 тижні
Часті питання

Наші компетенції:

Етапи розробки

Останні роботи

  • image_website-b2b-advance_0.png
    Розробка сайту компанії B2B ADVANCE
    1262
  • image_bitrix-bitrix-24-1c_fixper_448_0.png
    Розробка веб-сайту для компанії ФІКСПЕР
    851
  • image_bitrix-bitrix-24-1c_development_of_an_online_appointment_booking_widget_for_a_medical_center_594_0.webp
    Розробка на базі Бітрікс, Бітрікс24, 1С для компанії Development of an Online
    585
  • image_bitrix-bitrix-24-1c_mirsanbel_458_0.webp
    Розробка на базі 1С Підприємство для компанії МИРСАНБЕЛ
    751
  • image_crm_dolbimby_434_0.webp
    Розробка сайту на CRM Бітрікс24 для компанії DOLBIMBY
    657
  • image_crm_technotorgcomplex_453_0.webp
    Розробка на базі Бітрікс24 для компанії ТЕХНОТОРГКОМПЛЕКС
    989

Розробка модуля підписки на товари 1С-Бітрікс

«Сповістити, коли з'явиться в наявності» — базова потреба для інтернет-магазину з товарами, які не завжди є в наявності. Стандартний Бітрікс не має такого механізму. Завдання часто закривають формою зворотного зв'язку з ручною обробкою, що погано масштабується. Модуль підписки вирішує завдання системно: автоматична постановка в чергу, відправлення сповіщень при появі залишку, статистика по затребуваності позицій.

Модель даних

Модуль vendor.waitlist:

  • b_vendor_waitlist_subscription — підписки: id, user_id, email (для незареєстрованих), product_id, sku_id (торгова пропозиція), created_at, notified_at, status (active/notified/cancelled)
  • b_vendor_waitlist_notify_log — журнал сповіщень: id, subscription_id, sent_at, result (sent/failed), error

Підписка на конкретний SKU

При натисканні «Сповістити про надходження» клієнт вводить email або підписується через обліковий запис:

class WaitlistService
{
    public function subscribe(int $productId, ?int $skuId, int $userId, string $email): SubscribeResult
    {
        // Перевіряємо, чи немає вже активної підписки від цього користувача/email на цей товар
        $existing = SubscriptionTable::getList([
            'filter' => [
                'PRODUCT_ID' => $productId,
                'SKU_ID'     => $skuId,
                'STATUS'     => 'active',
                '=EMAIL'     => $email,
            ],
        ])->fetch();

        if ($existing) {
            return SubscribeResult::alreadySubscribed();
        }

        SubscriptionTable::add([
            'USER_ID'    => $userId ?: null,
            'EMAIL'      => $email,
            'PRODUCT_ID' => $productId,
            'SKU_ID'     => $skuId,
            'STATUS'     => 'active',
        ]);

        return SubscribeResult::success();
    }
}

Тригер при надходженні товару

При зміні залишків через API або 1С-синхронізацію спрацьовує подія OnProductStockChanged (кастомна подія модуля, викликається з обробника OnAfterIBlockElementUpdate):

AddEventHandler('iblock', 'OnAfterIBlockElementUpdate', ['\Vendor\Waitlist\StockWatcher', 'onElementUpdate']);

public static function onElementUpdate(array &$fields): void
{
    // Перевіряємо: це торгова пропозиція? Чи змінився QUANTITY?
    if (!isset($fields['PROPERTY_VALUES']['QUANTITY'])) return;

    $newQty = (int)$fields['PROPERTY_VALUES']['QUANTITY'];
    if ($newQty <= 0) return;

    // Шукаємо активні підписки на цей SKU
    $subscriptions = SubscriptionTable::getList([
        'filter' => ['SKU_ID' => $fields['ID'], 'STATUS' => 'active'],
    ])->fetchAll();

    foreach ($subscriptions as $sub) {
        NotifyQueueTable::add(['SUBSCRIPTION_ID' => $sub['ID']]);
    }
}

Сповіщення відправляються з черги агентом — не блокуючи процес збереження елемента.

Агент відправлення сповіщень

public static function run(): string
{
    $queue = NotifyQueueTable::getList(['limit' => 100, 'filter' => ['STATUS' => 'pending']])->fetchAll();

    foreach ($queue as $item) {
        $sub = SubscriptionTable::getById($item['SUBSCRIPTION_ID'])->fetch();

        // Повторно перевіряємо залишок: раптом розкупили поки агент спав
        $qty = \CIBlockElement::GetProperty($sub['SKU_ID'], false, 'QUANTITY', true);
        if ($qty <= 0) {
            NotifyQueueTable::delete($item['ID']);
            continue;
        }

        $result = \Bitrix\Main\Mail\Event::send([
            'EVENT_NAME' => 'WAITLIST_PRODUCT_AVAILABLE',
            'LID'        => SITE_ID,
            'C_FIELDS'   => [
                'EMAIL'       => $sub['EMAIL'],
                'PRODUCT_ID'  => $sub['PRODUCT_ID'],
                'PRODUCT_URL' => \CIBlockElement::GetDetailPageUrl($sub['PRODUCT_ID']),
            ],
        ]);

        SubscriptionTable::update($sub['ID'], ['STATUS' => 'notified', 'NOTIFIED_AT' => new DateTime()]);
    }

    return '\Vendor\Waitlist\NotifyAgent::run();';
}

Віджет на картці товару

Компонент vendor:waitlist.button підключається до картки товару. Визначає:

  • Чи є у поточного користувача активна підписка на даний SKU
  • Відображає кнопку «Сповістити про надходження» або «Ви підписані»
  • Для незалогінених — форма введення email без реєстрації

Статистика та аналітика

В адміністративному інтерфейсі:

  • Топ товарів за кількістю підписок — розуміння реального попиту
  • Конверсія: скільки користувачів купили після отримання сповіщення
  • Середній час від підписки до сповіщення
  • Список «вічних» очікувачів — підписки старше N днів без сповіщення

Статистика попиту безпосередньо корисна для закупівельної служби.

Терміни розробки

Етап Термін
ORM-таблиці, сервіс підписки 1 день
Тригер зміни залишків 1 день
Черга та агент сповіщень 1 день
Віджет картки товару 1 день
Email-шаблон сповіщення 0.5 дня
Статистика та аналітика 1 день
Адміністративний інтерфейс 1 день
Тестування 0.5 дня

Разом: 7 робочих днів. Підтримка push-сповіщень як додаткового каналу — +1 день.