Налаштування єдиної програми лояльності онлайн та офлайн 1С-Бітрікс

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

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

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

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

  • 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С-Bitrix

Клієнт накопив 500 бонусів на сайті і прийшов у магазин їх витратити. Касир не бачить бонусів — вони в іншій системі. Або навпаки: покупка у магазині не нараховує бали на онлайн-акаунт. Розрив між онлайн та оффлайн програмою лояльності — це не тільки UX-проблема, але й прямі втрати на повторних покупках.

Як влаштована лояльність у Bitrix

Модуль sale реалізує дисконтну систему через b_sale_user_discount (персональні скидки) та бонусну систему через b_sale_discount (правила кошика). Для повнофункціональної програми лояльності (накопичувальні бали) використовується окремий модуль або інтеграція з зовнішньою системою.

У Bitrix24 є CRM-модуль з бонусами (b_crm_loyalty_bonus_transaction), але для інтернет-магазину без Bitrix24 частіше застосовується модуль marketingcrm або власна таблиця транзакцій.

Структура зберігання бонусів

Мінімальна структура для єдиної програми:

CREATE TABLE bl_loyalty_account (
    id          SERIAL PRIMARY KEY,
    user_id     INT UNIQUE,           -- b_user.ID (онлайн)
    card_number VARCHAR(20) UNIQUE,   -- номер карти для оффлайн
    balance     NUMERIC(10,2) DEFAULT 0,
    created_at  TIMESTAMP DEFAULT NOW()
);

CREATE TABLE bl_loyalty_transaction (
    id          SERIAL PRIMARY KEY,
    account_id  INT NOT NULL REFERENCES bl_loyalty_account(id),
    amount      NUMERIC(10,2) NOT NULL,  -- позитивне=нараховано, негативне=списано
    type        VARCHAR(20) NOT NULL,    -- 'earn_online', 'earn_offline', 'spend', 'expire'
    order_id    INT,                     -- b_sale_order.ID або зовнішній ID оффлайн-чека
    source      VARCHAR(20) NOT NULL,    -- 'web', 'pos', 'mobile'
    created_at  TIMESTAMP DEFAULT NOW()
);

Трансакційна модель із історією — єдиний надійний спосіб зберігання бонусів. Ніколи не оновлюйте balance напряму без запису транзакції. balance — це або денормалізований агрегат (оновлюється триггером БД), або розраховується як SUM(amount) з таблиці транзакцій.

Ідентифікація клієнта на оффлайн-касі

Ключева задача: касир має знайти акаунт клієнта. Способи ідентифікації:

  • Номер карти лояльності (фізична карта або штрихкод у мобільному додатку)
  • Номер телефону
  • QR-код з токеном (генерується в особистому кабінеті сайту)

При ідентифікації за телефоном касове ПО надсилає запит до API Bitrix:

// /local/ajax/loyalty/find-account.php
$phone     = normalizePhone($_POST['phone']);
$bitrixUser = \CUser::GetList([], ['PERSONAL_PHONE' => $phone])->Fetch();

if ($bitrixUser) {
    $account = getLoyaltyAccount($bitrixUser['ID']);
    echo json_encode(['balance' => $account['balance'], 'account_id' => $account['id']]);
}

Нарахування бонусів при онлайн-замовленні

Обробник зміни статусу замовлення — після доставки/завершення:

AddEventHandler('sale', 'OnSaleStatusOrderChange', function(\Bitrix\Main\Event $event) {
    $order  = $event->getParameter('ENTITY');
    $status = $order->getField('STATUS_ID');

    if ($status !== 'F') return; // Лише завершені замовлення

    $userId = $order->getUserId();
    $bonus  = round($order->getPrice() * BONUS_RATE); // BONUS_RATE = 0.05 (5%)

    addLoyaltyTransaction($userId, $bonus, 'earn_online', $order->getId(), 'web');
});

Списання бонусів при онлайн-покупці

Бонуси застосовуються через правило кошика або через кастомний платіжний метод. Правило кошика (b_sale_discount) може давати скидку фіксованої суми. Для більш гнучкої схеми — власний «платіжний метод» типу «Оплата бонусами», який при проведенні замовлення списує транзакцію з bl_loyalty_transaction.

Синхронізація через API для оффлайн-касл

Оффлайн-каса викликає три endpoint:

  1. GET /loyalty/balance?phone=... — перевірити баланс
  2. POST /loyalty/spend — списати бонуси при продажі (має бути трансакційним: початок продажу → резервування → підтвердження)
  3. POST /loyalty/earn — нарахувати бонуси після продажу

Резервування при списанні — критично важливий крок. Без нього два паралельні запити від різних касл можуть одночасно прочитати баланс 500 бонусів та двічі списати по 500, йдучи в мінус. Резервування через SELECT ... FOR UPDATE в PostgreSQL або через суворе UPDATE з перевіркою результату:

UPDATE bl_loyalty_account
SET balance = balance - :amount
WHERE id = :account_id AND balance >= :amount
RETURNING balance;
-- Якщо оновлено 0 рядків — недостатньо бонусів

Що налаштовуємо

  • Таблиці bl_loyalty_account та bl_loyalty_transaction
  • API-endpoints для касових систем (баланс, нарахування, списання)
  • Обробники подій OnSaleStatusOrderChange для онлайн-нарахувань
  • Механізм ідентифікації клієнта за телефоном/карткою
  • Трансакційне списання з захистом від race condition
  • Адміністративний інтерфейс для перегляду історії транзакцій