Узнайте, как спроектировать и создать веб‑приложение для отслеживания кликов партнёров, конверсий и доходов. Рассмотрены модель данных, трекинг, отчётность, выплаты и приватность.

Атрибуция доходов партнёров — это система, которая отвечает на простой вопрос: какой партнёр должен получить кредит (и сколько) за событие дохода? В веб‑приложении это значит, что вы не просто считаете клики — вы связываете реферальный переход партнёра с последующей конверсией, переводите это в понятную сумму дохода и делаете процесс проверяемым.
Начните с одной фразы, в которой будут указаны (1) что атрибутируется, (2) кому, и (3) по каким правилам. Например:
Это определение станет опорой для требований, модели данных и споров, которые придётся решать позже.
«Партнёр» часто включает несколько групп с разными ожиданиями и рабочими процессами:
Не заставляйте все эти группы работать в одном процессе слишком рано. Можно использовать унифицированную модель (партнёры, программы, контракты) и одновременно поддерживать несколько методов рефералов (ссылки, коды, ручные сделки).
Практическое веб‑приложение для атрибуции партнёров должно надёжно обеспечивать четыре результата:
Если хоть одна из этих областей слабая, партнёры не будут доверять цифрам — даже при корректной математике.
Для практического руководства цель — помочь вам выпустить рабочую систему, а не спорить о философии атрибуции. Реалистичная первая версия должна:
Продвинутые функции (мультитач‑атрибуция, объединение кросс‑устройств, сложный скоринг фрода) можно добавить, когда базовые вещи станут надёжными и тестируемыми.
Прежде чем выбрать модель атрибуции или спроектировать базу, чётко пропишите, что приложение должно доказывать бизнесу. Атрибуция доходов партнёров — это в конце концов набор ответов, которым доверяют настолько, чтобы платить деньги.
Большинство команд сначала ориентируются на «партнёров», а потом обнаруживают, что финансы или поддержка не могут ничего проверить. Перечислите основных пользователей и решения, которые они принимают:
Запишите эти вопросы простым языком — ими должны оперировать UI и отчёты:
Минимально запланируйте: click, lead, trial start, purchase, renewal, и refund/chargeback. Решите, какие из них комиссионно‑пригодны, а какие служат вспомогательными доказательствами.
Начните с одного понятного набора правил — обычно last‑touch в конфигурируемом окне — и добавляйте multi‑touch только при росте потребностей в отчётности и чистых данных. Первая версия должна быть простой для объяснения и аудита.
До написания кода решите, что получает кредит и когда этот кредит истекает. Если правила не задать заранее, вы будете обсуждать крайние случаи (и получать жалобы партнёров) при каждой выплате.
Last click даёт 100% кредита последнему партнёрскому клику перед конверсией. Это просто и понятно, но может переоценивать трафик с купонами, появляющийся в самом конце воронки.
First click даёт 100% кредита партнёру, который первым привлёк клиента. Отдаёт предпочтение партнёрам, которые познакомили с продуктом, но может недооценивать тех, кто закрывает сделки.
Linear делит кредит поровну между всеми подходящими касаниями в окне. Может казаться «справедливым», но сложнее объясняется и может размывать стимулы.
Time‑decay даёт больше кредита касаниям, ближе к конверсии, сохраняя признание ранних касаний. Это компромисс, но требует больше математики и понятных отчётов.
Выберите одну модель по умолчанию для большинства конверсий (многие начинают с last click — потому что её проще всего объяснить и сверить). Затем явно задокументируйте исключения, чтобы поддержка и финансы могли применять их последовательно:
Установите одно или несколько окон, например 7 / 30 / 90 дней. Практический подход — стандартное окно (например, 30 дней) плюс более короткие окна для партнёров с купонами, если нужно.
Также определите правила повторного вовлечения: если клиент кликает по ссылке другого партнёра внутри окна, переключаете ли вы кредит сразу (last click), делите кредит или сохраняете исходного партнёра, если новый клик произошёл вне «close window» (например, 24 часа)?
Решите, что вы атрибутируете: только первоначальную покупку или чистый доход со временем.
Запишите эти правила в коротком «Attribution Policy» документе и ссылкой разместите в партнёрском портале, чтобы поведение системы соответствовало ожиданиям партнёров.
Чистая модель данных — это разница между «мы думаем, что партнёр привёл продажу» и «мы можем это доказать, сверить и корректно выплатить». Начните с небольшого набора сущностей и сделайте связи явными через неизменяемые идентификаторы.
partner_id, статус, условия выплат, валюту по умолчанию.campaign_id, даты начала/конца.link_id, принадлежит partner_id и опционально campaign_id.click_id, ссылается на link_id и partner_id.visitor_id (часто производный от cookie first‑party).conversion_id, ссылается на click_id (когда он есть) и visitor_id.order_id, ссылается на customer_id и связана с conversion_id.payout_id, ссылается на partner_id и агрегирует подходящие заказы.Ваш «золотой путь» —
partner_id → link_id → click_id → visitor_id → conversion_id → order_id → payout_id
Храните customer_id рядом с order_id, чтобы повторные покупки можно было обработать по вашим правилам (например, «только первая покупка» vs «на всю жизнь»). Храните внутренние и внешние идентификаторы, чтобы сверяться (например, shopify_order_id).
Заказы меняются. Модель должна это явным образом отражать:
gross_amount, tax_amount, shipping_amount, fee_amount, discount_amount.currency_code и fx_rate_to_payout_currency (и метку времени/источник этого курса).order_id (например, order_adjustment_id, type = partial_refund). Это сохраняет аудируемую историю и избегает перезаписи итогов.Добавьте поля аудита везде: created_at, updated_at, ingested_at, source (web, server‑to‑server, import) и неизменяемые идентификаторы.
Для анализа фрода без хранения персональных данных храните хешированные поля, как ip_hash и user_agent_hash. Наконец, ведите лёгкий журнал изменений (entity, entity_id, старое/новое значение, актор), чтобы решения по выплатам можно было объяснить позже.
Трекинг кликов — основа атрибуции: каждая партнёрская ссылка должна создавать долговременную «строку клика», которую потом можно соединить с конверсией.
Используйте один канонический формат ссылки, который партнёры могут копировать и вставлять. В большинстве систем ссылка для партнёра не должна содержать click_id — он генерируется сервером.
Хороший шаблон:
/r/{partner_id}?campaign_id=...&utm_source=...&utm_medium=partner&utm_campaign=...
Практические рекомендации по параметрам:
Пропускайте весь партнёрский трафик через редирект‑эндпойнт (например, /r/{partner_id}):
click_id (UUID/ULID) и сохраняйте строку клика на сервере (partner_id, campaign_id, user agent, ip_hash, timestamp, landing URL).click_id.Это делает создание клика последовательным, предотвращает подделку click_id партнёрами и централизует применение правил.
Большинство команд используют cookie как основной метод, localStorage как fallback, а серверные сессии — только для коротких потоков.
Для мобильного веба cookies могут быть менее надёжны — поэтому используйте редирект‑эндпойнт и храните click_id и в cookie, и в localStorage.
Для app→web поддерживайте:
click_id.Задокументируйте точные правила ссылок в партнёрском портале (см. /blog/partner-links), чтобы партнёры не «творили» с параметрами.
Трекинг конверсий — место, где системы атрибуции либо завоёвывают доверие, либо тихо его теряют. Цель — записать одну каноничную «конверсию» на реальную покупку (или регистрацию) с достаточным контекстом, чтобы связать её с партнёрским кликом.
Большинство продуктов может наблюдать конверсии из нескольких мест:
Рекомендация: рассматривайте бэкенд сервис заказов как каноничный регистратор конверсий и опционно используйте вебхуки платёжных провайдеров как сигналы подтверждения/обновления (например, перевод заказа из pending в paid). Клиент‑сайд события пригодны для дебага или вороночной аналитики, но не для выплатного уровня атрибуции.
Чтобы атрибуция была возможна позже, событие конверсии должно иметь стабильный идентификатор и способ связаться с кликом.
Типичный подход:
click_id.click_id к заказу (например, из состояния сессии, записи клиента или подписанного токена с клиента).Основное соединение должно быть conversion.click_id → click.id. Если click_id отсутствует, определите явные fallback‑правила, например:
Сделайте эти fallback‑правила видимыми в админ‑инструментах, чтобы поддержка могла объяснить результаты без догадок.
Вебхуки и клиентские вызовы будут ретраиться. Система должна уметь принимать одну и ту же конверсию несколько раз без двойного учёта.
Внедрите idempotency keys, используя стабильное уникальное значение, например:
order_id (лучше всего, если глобально уникален)payment_provider_charge_idХраните ключ на записи конверсии с уникальным ограничением. При повторном поступлении возвращайте успех и не создавайте вторую конверсию. Это предотвращает типичные баги с «фантомными» выплатами.
Здесь трекинг превращается в деньги. Приложение должно иметь ясный, аудируемый путь от зафиксированного события до суммы, которую можно выплатить — и при этом согласовываться с тем, как финансы учитывают доход.
Практический жизненный цикл может выглядеть так:
click_id и контекст кампании.Храните временные метки для каждого перехода состояния, чтобы можно было объяснить когда и почему конверсия стала выплачиваемой.
Определите, что в вашей системе значит «доход», и храните это явно:
Типичные варианты, которые стоит поддержать без жёсткой привязки к политике:
Финансы нужны данные для сверки:
Партнёрская программа живёт или умирает доверие. Портал — место, где партнёры убеждаются, что клики превратились в конверсии, а конверсии в деньги. Админ‑дашборд — место, где команда поддерживает программу чистой, быстрой и справедливой.
Начните с небольшого набора экранов, которые отвечают на ежедневные вопросы партнёров:
Для списка конверсий включите колонки, которые снижают обращения в поддержку: время конверсии, ID заказа (или замаскированный), атрибутируемая сумма, ставка комиссии, статус (pending/approved/rejected/paid) и короткое поле «причина», если есть отказ.
Партнёры и админы нуждаются в быстрых срезах без экспорта в таблицы. Приоритизируйте:
Если вы отслеживаете несколько продуктов или планов, добавьте фильтр по продукту — но только после стабилизации базовых функций.
Админ‑инструменты должны фокусироваться на скорости и ответственности:
click_id при наличии доказательств).Ограничивайте ручные правки: админы должны корректировать исключения, а не переписывать историю по прихоти.
Внедрите RBAC с первого дня:
Реализуйте проверки прав на уровне API, а не только UI, и логируйте доступ к чувствительным выгрузкам, например к экспортам выплат.
Приложение для атрибуции партнёров обычно «write‑heavy»: много кликов, много событий конверсий и периодические интенсивные чтения для отчётов. Проектируйте сначала для высоких объёмов записи, затем ускоряйте отчётность через агрегации.
Один рабочий базовый набор:
Делайте трекинг‑эндпойнты статлесс, чтобы их можно было горизонтально масштабировать за балансировщиком.
Если хотите быстро перейти от спецификации к рабочему прототипу, можно использовать инструменты прототипирования, которые генерируют админ‑дашборд, партнёрский портал и API — затем экспортировать код для продакшена.
Не выполняйте дорогую работу в синхронном цикле запрос‑ответ. Используйте очередь (SQS/RabbitMQ/Redis queues) и воркеры для:
Воркеры должны быть идемпотентными: повторный запуск не ломает результаты.
Таблицы кликов растут быстро. Планируйте хранение заранее:
В Postgres рассмотрите партиционирование по времени (например, месячные партиции) и индексацию по (occurred_at, partner_id) и click_id. Партиционирование упрощает обслуживание индексов и удаление старых данных.
Сбоивый трекинг часто тихий, если вы его не измеряете. Добавьте метрики:
Логируйте с согласованным correlation ID (например, click_id/conversion_id), чтобы поддержка могла трассировать первое обращение партнёра сквозь систему.
Контрмеры против злоупотреблений защищают не только бизнес, но и честных партнёров от недоплат из‑за шумных данных. Лучший подход совмещает автоматические защиты (быстрые и последовательные) и ручную проверку (гибкую, контекстную).
Саморефералы, когда партнёры пытаются заработать на своих же покупках/регистрациях (детектируются по повторяющимся платёжным отпечаткам, email, устройствам).
Cookie stuffing и клик‑спам пытаются «заявить» пользователей без реального намерения — невидимые iframe, принудительные редиректы или очень большой объём кликов с нулевой вовлечённостью.
Фейковые лиды — низкокачественные формы, созданные для получения CPA‑выплат. Утечки купонов случаются, когда приватный код делится публично и смещает атрибуцию.
Начните с лимитов по частоте кликов и конверсий на партнёра, IP‑диапазон и сессию. Сочетайте это с сигналами ботов: аномальный user‑agent, отсутствие выполнения JavaScript, подозрительное постоянство таймингов, дата‑центровые IP, повторяющиеся отпечатки устройств.
Добавляйте тревоги по аномалиям. Не нужна сложная ML‑система, чтобы получить эффект: простые пороги вроде «рост CR в 5× за неделю» или «много конверсий с идентичными метаданными» ловят большинство проблем. Тревоги должны вести в детализированный режим в админке (например, /admin/partners/:id/attribution).
Для качества данных валидируйте входящие данные при приёме. Требуйте click_id или подписанные партнёрские токены там, где нужно; отвергайте некорректные UTM; нормализуйте страну/валюту. Многие расследования тормозят из‑за неполных логов или неоднозначных джойнов.
Дайте операторам понятную очередь: флаги (причина + серьёзность), заметки и временную шкалу связанных кликов и конверсий.
Поддерживайте удержания конверсий (pending), чтобы подозрительные события не поступали сразу в выплаты. Вводите предупреждения партнёрам и эскалации (временные задержки выплат, ограничения трафика или исключение из программы) с единообразными шаблонами действий.
Храните неизменяемый журнал для:
Это необходимо для споров с партнёрами, сверки финансов и внутренней отчётности — особенно когда несколько людей могут менять правила и выплаты.
Атрибуция партнёрских доходов затрагивает трекинг, идентичность и платежи — три зоны, где мелкие ошибки приводят к большим рискам. Цель — измерять рефералы и рассчитывать выплаты, собирая минимум персональных данных и надёжно защищая то, что хранится.
Отталкивайтесь от минимального набора, нужного для атрибуции и сверки:
partner_id, campaign_id, сгенерированный click_id.click_time и conversion_time.order_id (или внутренний transaction_id), валюта, net‑revenue, статус возврата.Избегайте лишнего:
click_id, internal_customer_id) вместо персональных идентификаторов.Если вы используете cookies или похожие идентификаторы, может потребоваться согласие в зависимости от юрисдикции:
Практически полезно поддерживать сервер‑сайд трекинг (postbacks) для партнёров, которые могут это сделать, и использовать клиент‑сайд cookie только там, где это разрешено и нужно.
Обращайтесь с данными атрибуции и выплат как с конфиденциальной бизнес‑информацией:
Также продумайте ретеншн: храните сырые события только столько, сколько нужно для сверки и споров, затем агрегируйте или удаляйте.
Логи часто становятся случайной утечкой данных. Установите правила логирования:
order_id, click_id) и хранить чувствительные полезные нагрузки в защищённом хранилище с ограниченным доступом.Опубликуйте прозрачную политику приватности и документируйте потоки данных. Когда партнёры спрашивают, как работает трекинг, вы сможете объяснить это ясно и безопасно.
Система атрибуции партнёров полезна только если партнёры доверяют ей, а финансы могут сверить результаты. Рассматривайте тестирование и запуск как часть продукта: вы проверяете бизнес‑правила, целостность данных и операционные процессы, а не только код.
Начните с набора «золотых» сценариев, которые можно прогонять целиком:
click_id или множественных кликов.conversion_id), отсутствие отрицательных выплат, согласованность между «атрибутируемым доходом» и «базой выплат».Изменение правил атрибуции изменит исторические числа — планируйте это заранее. Храните сырые события (клики, конверсии, возвраты) неизменяемыми, затем пересчитывайте атрибуцию в версионируемых таблицах (например, attribution_results_v1, v2). Для больших объёмов делайте бэкфилл по партиям (по дню/неделе) с dry‑run режимом, который даёт diff‑отчёт для проверки финансами.
Проведите пилот с небольшой группой партнёров (5–10). В пилоте:
Внедряйте изменения за фичер‑флагами, документируйте версии правил в портале и заранее уведомляйте о любых изменениях, которые могут повлиять на доходы.
Операционно полезно иметь быструю возможность отката для логики отчётности и выплат. Если вы быстро прототипируете, сохраняйте известную рабочую версию, чтобы при необходимости быстро вернуться к проверенному поведению.
Если вы хотите позже изучить упаковку и онбординг, смотрите /pricing или другие руководства в /blog.
Атрибуция доходов партнёров — это набор правил и данных, которые определяют, какой партнёр получает кредит за событие дохода (и в каком размере), на основе доказательств вроде click_id, промокодов и временных окон.
Полезное определение включает:
Начните с прописанной в одно предложение политики, затем задокументируйте исключения.
Хорошая политика для V1 часто выглядит так:
click_id, созданный через редирект и присоединённый сервер‑сайд к заказуДалее зафиксируйте исключения — приоритет купонов, правила для пролонгаций и поведение при прямом трафике.
Минимально необходимо отслеживать:
Эти три события позволяют связать трафик → доход → возвраты и безопасно формировать выплаты.
Используйте редирект‑эндпойнт (например, /r/{partner_id}), который:
click_idЭто предотвращает спуфинг и делает трекинг однородным независимо от размещений.
Отдавайте приоритет серверной записи заказа как каноничному источнику конверсий.
Практически это выглядит так:
click_id (или атрибуционный токен)pending → paid), но не в качестве единственного источника правдыИспользуйте idempotency keys, чтобы повторные вебхуки не создавали дубликаты конверсий.
Типичные ключи:
order_id (лучше всего, если глобально уникален)payment_provider_charge_idНакладывайте уникальное ограничение в базе. При повторе возвращайте успех и не создавайте новую конверсию или комиссионную строку.
Стремитесь к цепочке, которую можно доказать end‑to‑end:
partner_id → link_id → click_id → visitor_id → conversion_id → order_id → payout_idХраните внутренние и внешние идентификаторы (например, shopify_order_id) и временные метки (created_at, ingested_at), чтобы можно было трассировать спорные случаи и сверять с биллингом.
Проектируйте учёт сумм с возможностью аудита и корректировок:
currency_codeНачните с минимального набора экранов, который сокращает число тикетов поддержки:
Сделайте каждую конверсию объяснимой: время клика, номер заказа (замаскированный), применённое правило.
Используйте лёгкие, но эффективные меры:
Для приватности храните минимум: псевдонимные идентификаторы, хешируйте IP при возможности и не логируйте персональные/платежные данные.
click_idЭто уменьшает количество двойных срабатываний и облегчает сверку с финучётом.
Так сохраняется история и вы сможете создавать отрицательные строки в следующих выплатах при необходимости.