Розробка модуля реферальної програми 1С-Бітрікс
Завдання реферальної програми — відстежити ланцюжок «хто кого привів» і коректно нарахувати винагороду рефереру при кожній оплаті реферала. Звучить просто, але на практиці виникають питання: як зберігати реферальне посилання при переході через браузер з іншого пристрою? як не нарахувати двічі при поверненні замовлення? як зробити багаторівневу систему без рекурсивних запитів? Штатних інструментів для цього в Бітрікс немає.
Модель даних
Модуль vendor.referral:
-
b_vendor_ref_link— реферальні посилання: id, user_id, code (унікальний 8-символьний код), clicks, registrations, orders_count, earned_total, created_at, is_active -
b_vendor_ref_relation— зв'язки реферер-реферал: id, referrer_id, referral_id, link_id, created_at -
b_vendor_ref_transaction— нарахування: id, referrer_id, referral_id, order_id, level (1/2/3 для багаторівневих), amount, status (pending/approved/paid/cancelled), created_at -
b_vendor_ref_withdrawal— запити на виведення: id, user_id, amount, method (bank/card/wallet), details (JSON), status, processed_at
Відстеження переходу та реєстрації
При кліку на реферальне посилання ?ref=ABCD1234:
// В init.php — перехоплюємо параметр
if ($refCode = $_GET['ref'] ?? null) {
setcookie('ref_code', $refCode, time() + 30 * 86400, '/', '', true, true);
// 30 днів cookie, httponly, secure
RefLinkTable::incrementClicks($refCode);
}
При реєстрації нового користувача:
AddEventHandler('main', 'OnAfterUserAdd', ['\Vendor\Referral\EventHandler', 'onUserRegistered']);
public static function onUserRegistered(array &$fields): void
{
$refCode = $_COOKIE['ref_code'] ?? null;
if (!$refCode) return;
$link = RefLinkTable::getByCode($refCode);
if (!$link || $link['USER_ID'] === $fields['ID']) return; // не реферимо самих себе
RefRelationTable::add([
'REFERRER_ID' => $link['USER_ID'],
'REFERRAL_ID' => $fields['ID'],
'LINK_ID' => $link['ID'],
]);
RefLinkTable::incrementRegistrations($link['ID']);
}
Нарахування винагороди
Винагорода нараховується при оплаті замовлення реферала:
AddEventHandler('sale', 'OnSaleOrderPaid', ['\Vendor\Referral\EventHandler', 'onOrderPaid']);
public static function onOrderPaid(\Bitrix\Main\Event $event): void
{
$orderId = $event->getParameter('id');
$order = \Bitrix\Sale\Order::load($orderId);
$referral = $order->getUserId();
// Шукаємо ланцюжок рефереров (до 3 рівнів)
$chain = RefRelationTable::getChain($referral, 3);
$rules = Option::get('vendor.referral', 'reward_rules'); // JSON з % по рівнях
foreach ($chain as $level => $referrerId) {
$percent = $rules["level_{$level}"] ?? 0;
if (!$percent) continue;
$amount = $order->getPrice() * $percent / 100;
RefTransactionTable::add([
'REFERRER_ID' => $referrerId,
'REFERRAL_ID' => $referral,
'ORDER_ID' => $orderId,
'LEVEL' => $level,
'AMOUNT' => $amount,
'STATUS' => 'pending', // очікує підтвердження
]);
}
}
Статуси нарахувань та захист від фроду
Нарахування створюється зі статусом pending. Переводиться в approved тільки після того, як:
- Минуло N днів з моменту оплати (період повернення)
- Замовлення не було скасовано або повернуто
При скасуванні замовлення транзакція переводиться в cancelled. Агент щодня перевіряє прострочений період повернення і схвалює pending-транзакції.
Додаткові захисти:
- Один реферер не може бути рефералом самого себе
- Реєстрація з тієї самої IP, що і реферер, — прапор для ручної перевірки
- Ліміт нарахувань на добу з одного реферала (захист від масових фіктивних замовлень)
Особистий кабінет реферера
- Унікальне реферальне посилання з QR-кодом
- Статистика: переходи, реєстрації, замовлення рефералів, зароблено
- Історія нарахувань з розбивкою по рефералах і замовленнях
- Баланс до виведення та історія виплат
- Форма запиту виведення коштів
Багаторівнева структура
Рівень 1: реферер отримує 5% від кожного замовлення прямого реферала
Рівень 2: 2% від замовлень рефералів рефералів
Рівень 3: 1% від третього рівня
Ланцюжок будується рекурсивним запитом по b_vendor_ref_relation з обмеженням глибини.
Терміни розробки
| Етап | Термін |
|---|---|
| ORM-таблиці, генерація посилань | 1 день |
| Відстеження переходів (cookie) | 1 день |
| Прив'язка реферала при реєстрації | 1 день |
| Нарахування винагород, багаторівневість | 2 дні |
| Захист від фроду, агент схвалення | 2 дні |
| Запити на виведення, адміністративний інтерфейс | 2 дні |
| Особистий кабінет реферера | 2 дні |
| Тестування | 1 день |
Разом: 12 робочих днів. Інтеграція з платіжними системами для автоматичної виплати винагород — окрема оцінка.







