Розробка системи аукціону на 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С-Бітрикс

Аукціон на сайті — це механізм продажу, де ціна товара визначається конкуренцією покупців: переможцем стає той, хто в відведений час запропонував найбільшу суму. 1С-Бітрикс не містить аукціонної логіки — її потрібно розробляти поверх стандартних модулів catalog та sale.

Типи аукціонів

Перед розробкою важливо зафіксувати бізнес-вимоги за типом аукціону:

Тип Опис Особливості
Англійський (відкритий) Ставки зростають, переважає максимальна Найпоширеніший
Нідерландський (зворотний) Ціна знижується, переважає перший, хто згоджується Потрібен таймер зниження ціни
Авто-ставка Вказується максимум, система торгується автоматично Складна логіка
«Купити зараз» Аукціон + фіксована ціна для миттєвої покупки Паралельний канал продажу

Структура даних

Аукціонний лот — розширення товарної картки. Зберігання через властивості інфоблока або окремі таблиці.

Таблиця b_local_auction:

Поле Тип Опис
ID int Первинний ключ
PRODUCT_ID int Посилання на елемент інфоблока
START_PRICE decimal Стартова ціна
MIN_STEP decimal Мінімальний крок ставки
CURRENT_PRICE decimal Поточна максимальна ставка
CURRENT_WINNER_ID int ID користувача з ведучою ставкою
RESERVE_PRICE decimal Резервна ціна (приховна)
BUY_NOW_PRICE decimal Ціна «Купити зараз» (опціонально)
START_TIME datetime Початок аукціону
END_TIME datetime Кінець аукціону
STATUS enum PENDING, ACTIVE, ENDED, CANCELLED
BIDS_COUNT int Кількість ставок

Таблиця b_local_auction_bid — історія ставок:

Поле Опис
AUCTION_ID Посилання на аукціон
USER_ID Учасник
AMOUNT Сума ставки
AUTO_MAX Максимум для авто-ставки
CREATED_AT Час ставки
IP IP-адреса (для антифраду)

Логіка прийняття ставки

Прийняття нової ставки — критична секція: кілька користувачів можуть робити ставки одночасно. Без блокувань виникають race conditions.

function placeBid(int $auctionId, int $userId, float $amount): BidResult
{
    // Початок транзакції з блокуванням рядка аукціону
    $connection = \Bitrix\Main\Application::getConnection();
    $connection->startTransaction();

    try {
        // SELECT FOR UPDATE — блокуємо рядок
        $auction = $connection->query(
            "SELECT * FROM b_local_auction WHERE ID = {$auctionId} FOR UPDATE"
        )->fetch();

        // Валідації
        if ($auction['STATUS'] !== 'ACTIVE') {
            throw new \Exception('Аукціон не активний');
        }
        if (new DateTime() > new DateTime($auction['END_TIME'])) {
            throw new \Exception('Аукціон завершений');
        }
        if ($amount < $auction['CURRENT_PRICE'] + $auction['MIN_STEP']) {
            throw new \Exception('Ставка нижче мінімальної: ' . ($auction['CURRENT_PRICE'] + $auction['MIN_STEP']));
        }
        if ($auction['CURRENT_WINNER_ID'] === $userId) {
            throw new \Exception('Ви вже лідируєте');
        }

        // Записати ставку
        AuctionBidTable::add([
            'AUCTION_ID' => $auctionId,
            'USER_ID' => $userId,
            'AMOUNT' => $amount,
            'CREATED_AT' => new DateTime(),
        ]);

        // Оновити поточну ставку
        AuctionTable::update($auctionId, [
            'CURRENT_PRICE' => $amount,
            'CURRENT_WINNER_ID' => $userId,
            'BIDS_COUNT' => $auction['BIDS_COUNT'] + 1,
        ]);

        // Продовження часу при ставці в останні хвилини
        if ((new DateTime($auction['END_TIME']))->getTimestamp() - time() < 300) {
            AuctionTable::update($auctionId, [
                'END_TIME' => (new DateTime())->modify('+5 minutes'),
            ]);
        }

        $connection->commitTransaction();

        // Сповістити попереднього лідера
        notifyOutbid($auction['CURRENT_WINNER_ID'], $auctionId, $amount);

    } catch (\Exception $e) {
        $connection->rollbackTransaction();
        throw $e;
    }
}

Real-time оновлення

Аукціон вимагає відображення поточної ставки без перезавантаження сторінки. Варіанти:

Polling — найпростіший: JavaScript робить AJAX-запит кожні 5-10 секунд.

setInterval(() => {
    fetch('/local/ajax/auction_state.php?id=' + auctionId)
        .then(r => r.json())
        .then(data => updateUI(data));
}, 5000);

Server-Sent Events (SSE) — сервер сам відправляє події при змінені. Менше навантаження, ніж polling.

WebSocket — максимально real-time, але вимагає окремого сервера (Node.js, Ratchet). На хостингу Бітрикс може бути недоступно.

Для більшості аукціонів polling з інтервалом 5-10 секунд — достатнє рішення.

Завершення аукціону та створення замовлення

Агент перевіряє аукціони, у яких сплив END_TIME:

$ended = AuctionTable::getList([
    'filter' => ['STATUS' => 'ACTIVE', '<END_TIME' => new DateTime()]
])->fetchAll();

foreach ($ended as $auction) {
    AuctionTable::update($auction['ID'], ['STATUS' => 'ENDED']);

    if ($auction['CURRENT_WINNER_ID'] && $auction['CURRENT_PRICE'] >= $auction['RESERVE_PRICE']) {
        // Сповістити переможця
        notifyWinner($auction['CURRENT_WINNER_ID'], $auction);
        // Створити замовлення або відправити посилання на оплату
        createAuctionOrder($auction);
    } else {
        // Резервна ціна не досягнута
        notifyReserveNotMet($auction);
    }
}

Антифрод та правила

  • Один користувач не може робити ставки від кількох аккаунтів — перевірка за IP + cookies + історія аккаунту.
  • Ставки тільки від авторизованих користувачів.
  • Опціонально: верифікація телефону або передоплата (блокування суми) для доступу до аукціону.
  • Мінімальний аккаунт: зареєстрований N днів тому, зробив хоча б одне замовлення.

Строки розробки

Варіант Состав Строк
Базовий аукціон Англійський, ставки, таймер, polling 8-10 днів
Розширений Авто-ставка, «купити зараз», сповіщення 12-16 днів
Повна платформа Кілька типів, WebSocket, аналітика, антифрод 20-30 днів