Setting up product price tracking for a 1C-Bitrix user

Our company is engaged in the development, support and maintenance of Bitrix and Bitrix24 solutions of any complexity. From simple one-page sites to complex online stores, CRM systems with 1C and telephony integration. The experience of developers is confirmed by certificates from the vendor.
Our competencies:
Development stages
Latest works
  • image_website-b2b-advance_0.png
    B2B ADVANCE company website development
    1175
  • image_bitrix-bitrix-24-1c_fixper_448_0.png
    Website development for FIXPER company
    811
  • image_bitrix-bitrix-24-1c_development_of_an_online_appointment_booking_widget_for_a_medical_center_594_0.webp
    Development based on Bitrix, Bitrix24, 1C for the company Development of an Online Appointment Booking Widget for a Medical Center
    564
  • image_bitrix-bitrix-24-1c_mirsanbel_458_0.webp
    Development based on 1C Enterprise for MIRSANBEL
    747
  • image_crm_dolbimby_434_0.webp
    Website development on CRM Bitrix24 for DOLBIMBY
    655
  • image_crm_technotorgcomplex_453_0.webp
    Development based on Bitrix24 for the company TECHNOTORGKOMPLEKS
    976

Configuration of User Price Tracking in 1C-Bitrix

Price tracking is when user clicks "Notify on drop" and leaves. A week later price fell — they get email. The functionality is simple in logic but requires three elements: subscription storage, product page UI, and price comparison mechanism. Standard Bitrix lacks this — it's assembled from several modules.

Subscription table

Create bl_price_tracker table via \Bitrix\Main\ORM\Data\DataManager:

class PriceTrackerTable extends \Bitrix\Main\ORM\Data\DataManager
{
    public static function getTableName(): string { return 'bl_price_tracker'; }

    public static function getMap(): array {
        return [
            new \Bitrix\Main\ORM\Fields\IntegerField('ID', ['primary' => true, 'autocomplete' => true]),
            new \Bitrix\Main\ORM\Fields\IntegerField('USER_ID'),
            new \Bitrix\Main\ORM\Fields\StringField('EMAIL'),
            new \Bitrix\Main\ORM\Fields\IntegerField('PRODUCT_ID'),
            new \Bitrix\Main\ORM\Fields\FloatField('PRICE_AT_SUBSCRIBE'),
            new \Bitrix\Main\ORM\Fields\FloatField('TARGET_PRICE'),  // NULL = any drop
            new \Bitrix\Main\ORM\Fields\DatetimeField('CREATED_AT'),
            new \Bitrix\Main\ORM\Fields\DatetimeField('NOTIFIED_AT'),
            new \Bitrix\Main\ORM\Fields\StringField('STATUS'), // active, notified, cancelled
        ];
    }
}

Indexes: unique on (USER_ID, PRODUCT_ID) — one user can't subscribe to one product twice.

UI on product page

In bitrix:catalog.element component template (file template.php) add button:

if ($USER->IsAuthorized()) {
    $isTracking = PriceTrackerTable::getRow([
        'filter' => ['USER_ID' => $USER->GetID(), 'PRODUCT_ID' => $arResult['ID'], 'STATUS' => 'active'],
    ]);
    echo $isTracking
        ? '<button class="btn-untrack" data-id="'.$arResult['ID'].'">Tracking ✓</button>'
        : '<button class="btn-track" data-id="'.$arResult['ID'].'">Watch price</button>';
}

AJAX handler adds or removes row in bl_price_tracker. Record PRICE_AT_SUBSCRIBE — current price at subscription moment. Without this, can't determine if new price is lower.

Price drop checking

Agent runs once per hour. Logic:

  1. Get all active subscriptions from bl_price_tracker with STATUS = active
  2. For each PRODUCT_ID get current price via \Bitrix\Catalog\PriceTable::getRow(['filter' => ['PRODUCT_ID' => $id, 'CATALOG_GROUP_ID' => 1]])
  3. Compare with PRICE_AT_SUBSCRIBE: if new price < old — send notification
  4. Update STATUS = notified and NOTIFIED_AT = NOW()

If you want to reactivate subscription after notification — switch to active after N days: add reactivation logic to agent for records where NOTIFIED_AT < NOW() - INTERVAL '30 days'.

"My Tracking" page

In user cabinet add section with list of tracked products. Component reads bl_price_tracker by USER_ID and JOINs product data from b_iblock_element. Show: product name, price at subscription, current price, subscription date. "Cancel" button changes STATUS to cancelled.

What to configure

  • ORM-class PriceTrackerTable and DDL migration for bl_price_tracker table
  • AJAX-controller for subscribe/unsubscribe with auth check
  • Button in catalog.element template with dynamic state
  • Agent for price comparison and notification sending
  • "My Tracking" page in user cabinet