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:
- Get all active subscriptions from
bl_price_trackerwithSTATUS = active - For each
PRODUCT_IDget current price via\Bitrix\Catalog\PriceTable::getRow(['filter' => ['PRODUCT_ID' => $id, 'CATALOG_GROUP_ID' => 1]]) - Compare with
PRICE_AT_SUBSCRIBE: if new price < old — send notification - Update
STATUS = notifiedandNOTIFIED_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
PriceTrackerTableand DDL migration forbl_price_trackertable - AJAX-controller for subscribe/unsubscribe with auth check
- Button in
catalog.elementtemplate with dynamic state - Agent for price comparison and notification sending
- "My Tracking" page in user cabinet







