Разработка реферальной системы

Наша компания занимается разработкой, поддержкой и обслуживанием сайтов любой сложности. От простых одностраничных сайтов до масштабных кластерных систем построенных на микро сервисах. Опыт разработчиков подтвержден сертификатами от вендоров.
Разработка и обслуживание любых видов сайтов:
Информационные сайты или веб-приложения
Сайты визитки, landing page, корпоративные сайты, онлайн каталоги, квиз, промо-сайты, блоги, новостные ресурсы, информационные порталы, форумы, агрегаторы
Сайты или веб-приложения электронной коммерции
Интернет-магазины, B2B-порталы, маркетплейсы, онлайн-обменники, кэшбэк-сайты, биржи, дропшиппинг-платформы, парсеры товаров
Веб-приложения для управления бизнес-процессами
CRM-системы, ERP-системы, корпоративные порталы, системы управления производством, парсеры информации
Сайты или веб-приложения электронных услуг
Доски объявлений, онлайн-школы, онлайн-кинотеатры, конструкторы сайтов, порталы предоставления электронных услуг, видеохостинги, тематические порталы

Это лишь некоторые из технических типов сайтов, с которыми мы работаем, и каждый из них может иметь свои специфические особенности и функциональность, а также быть адаптированным под конкретные потребности и цели клиента

Предлагаемые услуги
Показано 1 из 1 услугВсе 2065 услуг
Разработка реферальной системы
Средняя
~1-2 недели
Часто задаваемые вопросы
Наши компетенции:
Этапы разработки
Последние работы
  • image_website-b2b-advance_0.png
    Разработка сайта компании B2B ADVANCE
    1214
  • image_web-applications_feedme_466_0.webp
    Разработка веб-приложения для компании FEEDME
    1161
  • image_websites_belfingroup_462_0.webp
    Разработка веб-сайта для компании БЕЛФИНГРУПП
    852
  • image_ecommerce_furnoro_435_0.webp
    Разработка интернет магазина для компании FURNORO
    1041
  • image_crm_enviok_479_0.webp
    Разработка веб-приложения для компании Enviok
    823
  • image_bitrix-bitrix-24-1c_fixper_448_0.png
    Разработка веб-сайта для компании ФИКСПЕР
    815

Разработка реферальной системы

Реферальная программа — это механизм, при котором существующий пользователь получает вознаграждение за привлечение нового. На практике это набор технических задач: генерация уникальных ссылок, атрибуция переходов, учёт выполненных условий, начисление и выплата вознаграждений.

Модель данных

CREATE TABLE referral_codes (
    id          BIGSERIAL PRIMARY KEY,
    user_id     BIGINT REFERENCES users(id),
    code        VARCHAR(32) UNIQUE NOT NULL,
    type        VARCHAR(32) DEFAULT 'personal', -- personal/promo/partner
    created_at  TIMESTAMPTZ DEFAULT NOW()
);

CREATE TABLE referral_clicks (
    id          BIGSERIAL PRIMARY KEY,
    code_id     BIGINT REFERENCES referral_codes(id),
    ip          INET,
    user_agent  TEXT,
    landed_at   TIMESTAMPTZ DEFAULT NOW(),
    converted   BOOLEAN DEFAULT FALSE
);

CREATE TABLE referrals (
    id              BIGSERIAL PRIMARY KEY,
    referrer_id     BIGINT REFERENCES users(id),   -- кто привёл
    referred_id     BIGINT REFERENCES users(id),   -- кого привели
    code_id         BIGINT REFERENCES referral_codes(id),
    status          VARCHAR(32) DEFAULT 'pending', -- pending/qualified/rewarded/cancelled
    qualified_at    TIMESTAMPTZ,                   -- выполнено условие начисления
    created_at      TIMESTAMPTZ DEFAULT NOW()
);

CREATE TABLE referral_rewards (
    id              BIGSERIAL PRIMARY KEY,
    referral_id     BIGINT REFERENCES referrals(id),
    recipient_id    BIGINT REFERENCES users(id),   -- реферер или реферал (двусторонние программы)
    type            VARCHAR(32),                   -- 'cashback', 'bonus_points', 'discount'
    amount          DECIMAL(14,2),
    currency        CHAR(3) DEFAULT 'RUB',
    status          VARCHAR(32) DEFAULT 'pending', -- pending/paid/cancelled
    paid_at         TIMESTAMPTZ
);

Генерация уникального кода

class ReferralCodeService {
    public function generateForUser(User $user): ReferralCode {
        // Проверяем, нет ли уже кода
        if ($existing = ReferralCode::where('user_id', $user->id)->first()) {
            return $existing;
        }

        do {
            // Читаемый код на основе имени пользователя + случайный суффикс
            $base = strtoupper(substr(preg_replace('/[^a-z]/i', '', $user->name), 0, 4));
            $code = $base . strtoupper(Str::random(4));
        } while (ReferralCode::where('code', $code)->exists());

        return ReferralCode::create([
            'user_id' => $user->id,
            'code'    => $code,
        ]);
    }
}

Реферальная ссылка и cookie

Реферальный параметр передаётся через URL: https://example.com/register?ref=IVAN4X2K. Нужно сохранить атрибуцию даже если пользователь не зарегистрируется сразу:

// Middleware: ReferralTracker
class ReferralTrackerMiddleware {
    public function handle(Request $request, Closure $next): Response {
        $code = $request->query('ref');

        if ($code && !session()->has('referral_code')) {
            $referralCode = ReferralCode::where('code', $code)->first();
            if ($referralCode) {
                session(['referral_code' => $code]);
                // Логируем клик
                ReferralClick::create([
                    'code_id'    => $referralCode->id,
                    'ip'         => $request->ip(),
                    'user_agent' => $request->userAgent(),
                ]);
            }
        }

        return $next($request);
    }
}

Атрибуция при регистрации

// В UserRegistrationService
public function register(array $data): User {
    $user = User::create($data);

    $referralCode = session()->pull('referral_code');
    if ($referralCode) {
        $code = ReferralCode::where('code', $referralCode)->first();
        if ($code && $code->user_id !== $user->id) {
            Referral::create([
                'referrer_id' => $code->user_id,
                'referred_id' => $user->id,
                'code_id'     => $code->id,
                'status'      => 'pending',
            ]);
            // Обновляем клик как сконвертированный
            ReferralClick::where('code_id', $code->id)
                ->where('converted', false)
                ->latest('landed_at')
                ->first()
                ?->update(['converted' => true]);
        }
    }

    return $user;
}

Условия начисления вознаграждения

Реферал считается «квалифицированным» только при выполнении определённого условия: первая оплата, достижение порога покупок, истечение trial-периода. Это реализуется через Events:

// Событие: первая оплата нового пользователя
class FirstPurchaseMade {
    public function __construct(public Order $order) {}
}

// Listener
class QualifyReferralOnFirstPurchase {
    public function handle(FirstPurchaseMade $event): void {
        $referral = Referral::where('referred_id', $event->order->user_id)
            ->where('status', 'pending')
            ->first();

        if (!$referral) return;

        DB::transaction(function() use ($referral, $event) {
            $referral->update([
                'status'       => 'qualified',
                'qualified_at' => now(),
            ]);

            $program = ReferralProgram::active()->first();

            // Вознаграждение рефереру
            ReferralReward::create([
                'referral_id'  => $referral->id,
                'recipient_id' => $referral->referrer_id,
                'type'         => $program->reward_type,
                'amount'       => $this->calculateReward($program, $event->order),
                'status'       => 'pending',
            ]);

            // Двусторонняя программа: бонус и новому пользователю
            if ($program->reward_referred) {
                ReferralReward::create([
                    'referral_id'  => $referral->id,
                    'recipient_id' => $referral->referred_id,
                    'type'         => $program->referred_reward_type,
                    'amount'       => $program->referred_reward_amount,
                    'status'       => 'pending',
                ]);
            }
        });
    }

    private function calculateReward(ReferralProgram $program, Order $order): float {
        return match($program->reward_type) {
            'fixed'      => $program->reward_amount,
            'percentage' => round($order->total * $program->reward_percent / 100, 2),
            default      => 0,
        };
    }
}

Выплата вознаграждений

Накопленные вознаграждения выплачиваются пакетно (раз в неделю) или сразу — зависит от типа:

// Бонусные баллы — мгновенно
class CreditBonusPoints implements ShouldQueue {
    public function handle(ReferralRewardCreated $event): void {
        $reward = $event->reward;
        if ($reward->type !== 'bonus_points') return;

        BonusAccount::firstOrCreate(['user_id' => $reward->recipient_id])
            ->increment('balance', $reward->amount);

        $reward->update(['status' => 'paid', 'paid_at' => now()]);
    }
}

// Cashback — через очередь выплат
// Накапливаем и выплачиваем batch-ем через платёжный сервис

Личный кабинет реферера

Страница статистики реферальной программы:

interface ReferralStats {
    code: string;
    link: string;
    clicks_total: number;
    registered: number;
    qualified: number;
    earned_total: number;
    pending_amount: number;
    referrals: Array<{
        id: number;
        name: string;        // только имя, не полные данные
        status: string;
        joined_at: string;
        reward_amount: number | null;
    }>;
}

Защита от фрода

Базовые проверки:

// В QualifyReferralOnFirstPurchase::handle()
// 1. Самореферал (пользователь ввёл собственный код)
if ($referral->referrer_id === $event->order->user_id) {
    $referral->update(['status' => 'cancelled']);
    return;
}

// 2. Один IP зарегистрировал несколько аккаунтов
$sameIpUsers = DB::table('user_registrations')
    ->where('ip', $event->order->user->registration_ip)
    ->where('created_at', '>', now()->subDays(7))
    ->count();

if ($sameIpUsers > 3) {
    $referral->update(['status' => 'fraud_suspect']);
    // Флаг для ручной проверки
    return;
}

Сроки реализации

Базовая реферальная система с кодами, атрибуцией и начислением фиксированного вознаграждения: 1–1,5 недели. Двусторонняя программа с процентными бонусами, личным кабинетом и защитой от фрода: 2–2,5 недели. Многоуровневая (MLM-подобная) реферальная система с деревом рефералов: плюс 1–2 недели.