Всем привет! Я Роман, тимлид e-commerce агентства KISLOROD

Любой бизнес в сети зависит от привлечения трафика и один из важнейших каналов — это CPA-сети. Однако при работе с любыми каналами важно правильно оценивать качество посетителей, поскольку иначе весь бюджет просто будет слит впустую.

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

Admitad — это платформа, которая работает по модели Cost Per Action — оплата за действие. 

Это одна из крупнейших CPA-сетей в России, которая запустилась в 2010 году. Она связывает рекламодателей и владельцев сайтов, предоставляет им техническое обеспечение, а зарабатывает на комиссии. 

Экосистема Адмитад

В сеть входит множество сайтов, на которых демонстрируется реклама. Адмитад фиксирует все клики по баннерам и партнерским ссылкам, а также целевые действия пользователей. К ним относятся: регистрация на сайте, заявка с сайта, покупка товара, установка приложения и другие.

Цель внедрения — зачем нужен акт сверки

Задача бизнеса — контролировать и корректировать расходы на рекламу.

Собственникам и маркетологам необходимо:

  1. Видеть стоимость привлеченных покупателей через рекламный канал.

  2. Отслеживать процент качественных клиентов.

  3. Выполнять сверки привлеченных клиентов с актами за прошедший месяц.

  4. Оценивать стоимость услуг рекламного агентства.

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

То есть бизнесу важно получать информацию о том, с каких сайтов приходят посетители и какое количество из них совершают целевое действие — конвертируются в клиентов. Причем важно отслеживать как моментальные, так и отложенные конверсии, например, когда клиент оплачивает не онлайн, а при получении.

Для этого используется сверка по статусу заказа:

  • выполнен; 

  • отменен;

  • или просто сформирован. 

Каждый выполненный заказ для рекламной площадки оплачивается больше, чем отмененные или брошенные заказы, а сверка производится один раз в месяц и уже затем предоставляются акты.

При этом в аналитике необходимо учитывать сегменты пользователей:

  • новые клиенты  — те, кто купил впервые;

  • текущие клиенты — те, кто уже совершал покупки.

Наше решение позволяет получать независимую статистику, чтобы разделять трафик и проверять эффективность разных каналов.

Как определить эффективность рекламных каналов

Если формировать отчеты можно только по лидам, то разделить рекламный трафик может быть довольно сложно, но все же возможно.

Чтобы различать источники трафика можно использовать:

  1. UTM-метки.

  2. Промокоды или специальные предложения

  3. Анализ данных о лидах.

  4. Временные метки и активность кампаний.

  5. Интеграция с CRM.

  6. Анализ поведения лидов.

Хотя эти методы не дают 100% точности, но помогут приблизительно разделить трафик и понять, какие каналы приносят больше лидов.

Возможные сложности

Скрытый текст

Разделение каналов трафика и использование меток требует тщательной настройки и учета возможных конфликтов, таких как перезапись UTM-меток другими рекламными инструментами. 

  1. Для начала важно определить, какие каналы и кампании будут участвовать в стратегии, и назначить для каждого из них уникальные метки. 

  2. Чтобы избежать перезаписи UTM-меток, необходимо провести аудит всех рекламных инструментов и скриптов, которые могут влиять на URL.

  3. После настройки UTM-меток и устранения конфликтов важно интегрировать данные с аналитическими инструментами, такими как Google Analytics или Яндекс Метрика. 

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

Если UTM-метки все же перезаписываются, можно использовать дополнительные отчеты в CRM-системе, где данные о лидах будут сопоставляться с информацией о рекламных каналах.

Если вы внедряете контекстную рекламу с отдельным трафиком и используете отслеживание меток, то необходимо регулярно проверять, как собираются данные, и при необходимости корректировать настройки. Это позволит минимизировать потери данных и принимать более обоснованные решения при распределении рекламного бюджета.

Проектирование и архитектура решения

Архитектура хранения и структура данных заказа определялись тем, какие возможности нужны в отчете.

Совместно с клиентом мы согласовали и выбрали формат отчета и собрали требования к функциональности, одним из которых было выполнение запроса в одно касание. Также определили механизмы взаимодействия с сервисом и сайтами.

Отчет по сверке позволяет рассчитывать конверсию по каждому рекламному каналу. 

  • в отчете указывается количество выполненных и отмененных заказов;

  • затем с помощью формулы подсчета конверсии определяется эффективность конкретного канала.

У Адмитад есть встроенная система для трекинга пользователей, а также возможность подключать собственные системы аналитики через Postback URL. Именно его мы использовали при внедрении нашей системы для клиента.

Этот тип интеграции позволяет избежать потерь пользователей из-за блокировки рекламных трекеров. А кука принимается из get-параметра и является внешним ресурсом, поэтому потери данных исключены.

Как обеспечить прозрачность работы решения

Для синхронизации данных между сайтом и рекламной площадкой было важно тщательно сопоставить статусы и триггеры, которые связаны с заказами. 

Это нужно для того, чтобы обе системы — и сайт, и Адмитад — могли корректно взаимодействовать и обмениваться информацией. Основная задача заключается в том, чтобы согласовать маппинги статусов на стороне Адмитад и на стороне сайта. 

Когда заказ только формируется, его дальнейшая судьба еще неизвестна: он может быть отменен, возвращен или успешно выполнен. 

Однако данные в Admitad должны быть переданы сразу после создания заказа, чтобы рекламная площадка могла начать отслеживание. Это особенно важно, так как заказы могут быть двух типов: с онлайн-оплатой и с оплатой при получении. 

В случае безналичной оплаты можно передать триггер, который подтверждает оплату, но если товар оплачивается при получении, то такой триггер отсутствует. В этом случае ключевым показателем становится конечный статус заказа — выполнен, отменен или возвращен. Именно этот статус будет использоваться для формирования отчетности.

Как распределить зоны ответственности

Сотрудничество между сторонами требует четкого взаимодействия. 

  • Рекламный агент должен согласовать с разработчиками ключи типов оплат и статусов заказа, чтобы обе системы могли корректно интерпретировать данные. 

  • Со стороны разработчиков сайта необходимо подготовить техническое задание, в котором будет описан событийный ряд (последовательность действий, которые связаны с заказом), а также структура таблицы с данными для отчета.

Отчет формируется по итогам завершившегося месяца, обычно к 10-м числам следующего месяца или в другой согласованный интервал. 

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

Скрытый текст

Чтобы синхронизировать данные между сайтом и рекламной площадкой, нужна не только техническая настройка, но и четкое взаимодействие между всеми участниками процесса. Чтобы система работала корректно, а отчеты были достоверными, необходима согласованность действий и точная передача данных.

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

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

Его задачи:

  • убедиться, что маппинги статусов и типов оплат корректно настроены;

  • что и сайт, и Адмитад готовы к обмену данными в нужном формате.

Заказчик также берет на себя ответственность за определение, от кого ожидаются дальнейшие действия. 

Например, если возникает расхождение в данных или требуется уточнение по статусам заказов, именно Заказчик инициирует процесс согласования и указывает, какая из сторон должна внести изменения. Это позволяет избежать путаницы и ускорить процесс настройки. 

Таким образом, участие Заказчика не только упрощает взаимодействие, но и обеспечивает прозрачность процесса, что особенно важно для своевременного формирования отчетности и корректного учета данных.

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

Схема интеграции: как это реализовано

На сайте используется система отслеживания рекламных меток с использованием куки-файлов, которая позволяет идентифицировать источник перехода пользователя и корректно учитывать эффективность рекламных каналов, включая трафик от партнерской сети Адмитад.

Рекламная кампания отслеживается по параметру "utm_source", где значение Admitad соответствует значению "adm". Если значение "utm_source" отличается от "adm", то кука удаляется.

Как это работает

Скрытый текст

Сохранение рекламной метки

  • Когда пользователь переходит на сайт по рекламной ссылке, в том числе через партнерскую сеть Admitad, система проверяет параметр "utm_source". Если значение utm_source равно adm, то в браузере пользователя создается кука, которая сохраняет эту рекламную метку из другого параметра "tagtag_uid" или "admitad_uid". 

  • Кука действует в течение одного месяца с момента первого перехода. Это позволяет отслеживать пользователя в течение длительного периода, даже если он возвращается на сайт позже.

Идентификация пользователя

  • Если пользователь возвращается на сайт в течение срока действия куки, система автоматически определяет, что он пришел с рекламного канала Admitad (по значению "utm_source=adm"), и учитывает это при формировании заказов.

Учет рекламного канала при заказе

  • При оформлении заказа система проверяет наличие куки с рекламной меткой. Если кука присутствует и содержит значение "tagtag_uid" или "admitad_uid, заказ связывается с рекламным каналом Admitad.

  • После успешного формирования заказа куки автоматически удаляются, чтобы избежать повторного учета этого же пользователя в будущем.

Обновление рекламной метки

  • Если пользователь переходит на сайт по новой рекламной ссылке, система проверяет параметр "utm_source". Если значение "utm_source" отличается от "adm", существующая кука удаляется, и новая кука не создается.

  • Если значение "utm_source" равно "adm", то старая кука (если она была) заменяется новой.

Удаление куки

Кука удаляется в следующих случаях:

  • После успешного оформления заказа.

  • Если пользователь переходит по ссылке с параметром "utm_source", отличным от "adm".

Преимущества системы

  1. Точный учет рекламных каналов. Система позволяет определить, что пользователь пришел с рекламного канала Admitad по значению utm_source=adm, что помогает в анализе эффективности рекламных кампаний.

  2. Автоматизация. Все процессы происходят автоматически и делать что-то вручную не нужно.

  3. Защита от дублирования. После заказа или при смене метки кука удаляется, что исключает возможность некорректного учета.

Техническая часть реализации под Битрикс

1. Подключение трекера

JS-код трекера можно подключить как напрямую к сайту, так и через GTM. В нашем случае мы использовали загрузку из GTM. Трекер отслеживает поведение пользователя и захватывает его. 

При этом куки из трекера не используются, он нужен только для определения запросов покупателя при настройке рекламной кампании. Инструкцию по подключению трекера предоставляет менеджер Адмитад.

Этот код представляет собой интеграцию с партнерской сетью Адмитад на платформе Битрикс. Основная цель — отслеживание заказов, которые были совершены через партнерские ссылки, и отправка данных о заказах в Адмитад для корректного учета и начисления вознаграждений партнерам.

Давайте разберем основные части кода и их функциональность.

2. Сохранение идентификатора Admitad (куки) 

Пример кода

Скрытый текст
use Bitrix\Main\EventManager;


$eventManager = EventManager::getInstance();


$eventManager->addEventHandlerCompatible(
   'main',
   'OnPageStart',
   [Admitad\Helpers::class, 'checkCookie']
);

Цель

Сохранить идентификатор пользователя — UID, который пришел от Адмитад, в куки браузера. Это нужно для того, чтобы отслеживать, откуда пришел пользователь: через партнерскую ссылку или нет.

Как это работает

  • Подписываемся на событие OnPageStart, которое срабатывает при загрузке страницы.

  • Проверяем наличие параметра admitad_uid или tagtag_uid в запросе — это идентификатор пользователя, который передается через партнерскую ссылку.

  • Если источник трафика utm_source — это Admitad (adm), то сохраняем UID в куки. Если источник другой, то очищаем куки.

Ключевые методы

  • setCookie($val) — сохраняет UID в куки.

  • clearCookie() — очищает куки.

Пример кода

Скрытый текст
namespace Admitad;


use Bitrix\Main\Loader;
use Bitrix\Main\Application;
use Bitrix\Main\Context;
use Bitrix\Main\Web\Cookie;


use O2k\Config\Settings;


Loader::includeModule('o2k.settings');


class Helpers
{

   const COOKIE_NAME = 'ADMITAD_UID'; // название куки и код свойства заказа

   const URL_SEND = 'https://ad.admitad.com/r';

   public static function getPostBackKey()
   {
       $settings = new Settings();
       return $settings->getByCode('ADMITAD_POSTBACK_KEY');
   }

   public static function getCampaignCode()
   {
       $settings = new Settings();
       return $settings->getByCode('ADMITAD_CAMPAIGN_CODE');
   }

   public static function getCookie()
   {

       return Application::getInstance()->getContext()->getRequest()->getCookie(self::COOKIE_NAME);
   }

   public static function checkCookie()
   {
       $request = Context::getCurrent()->getRequest();
       $uid = $request->get('admitad_uid') ?? $request->get('tagtag_uid');
       $source = $request->get('utm_source');

       if ($source == 'adm') {
           self::setCookie($uid);
       } else if ($source && $source !== 'adm') {
           self::clearCookie();
       }
   }

   public static function setCookie($val)
   {
       if($val !== self::getCookie()) {
   
           $cookie = new Cookie(self::COOKIE_NAME, $val, time() + 3600 * 24 * 30);
           $cookie->setDomain(Application::getInstance()->getContext()->getServer()->get('SERVER_NAME'));
           $cookie->setPath('/');
           $cookie->setSecure(false);
           $cookie->setHttpOnly(false);
           $cookie->setSpread(Cookie::SPREAD_DOMAIN);

           Context::getCurrent()->getResponse()->addCookie($cookie);
       }
   }

   public static function clearCookie(){

       $cookie = new Cookie(self::COOKIE_NAME, 'clear', time() - 3600);
       $cookie->setDomain(Application::getInstance()->getContext()->getServer()->get('SERVER_NAME'));
       $cookie->setPath('/');
       $cookie->setSecure(false);
       $cookie->setHttpOnly(false);
       $cookie->setSpread(Cookie::SPREAD_DOMAIN);

       Context::getCurrent()->getResponse()->addCookie($cookie);
   }
}

3. Обработчик формирования заказа

Цель

При создании заказа сохранить UID из куки в свойства заказа и отправить данные о заказе в Адмитад через postback — специальный запрос для учета заказов.

Пример кода

Скрытый текст
use Bitrix\Main\EventManager;

$eventManager = EventManager::getInstance();

$eventManager->addEventHandler(
   'sale',
   'OnSaleOrderBeforeSaved',
   [Admitad\Bus::class, 'onBeforeSaveOrderHandler']
);

$eventManager->addEventHandler(
   'sale',
   'OnSaleOrderSaved',
   [Admitad\Bus::class, 'onSaveOrderHandler']
);

Как это работает

Подписываемся на два события:

  1. OnSaleOrderBeforeSaved — перед сохранением заказа. Здесь UID из куки записывается в свойства заказа.

  2. OnSaleOrderSaved — после сохранения заказа. Здесь отправляются данные о заказе в Адмитад.

Если заказ новый — IS_NEW, то вызывается метод sendOrder(), который формирует данные о заказе и отправляет их в Адмитад.

  Ключевые методы

  • sendOrder() — отправляет данные о заказе в Адмитад.

  • getParamsOrder() — формирует параметры для отправки, включая информацию о товарах, цене, количестве, валюте и т. д.

  • sendPosition() — отправляет данные на сервер Адмитад через HTTP-запрос.

Пример кода

Скрытый текст
namespace Admitad;

use Bitrix\Main\ArgumentException;
use Bitrix\Main\ArgumentNullException;
use Bitrix\Main\ArgumentOutOfRangeException;
use Bitrix\Main\Event;
use Bitrix\Main\NotImplementedException;
use Bitrix\Main\ObjectPropertyException;
use Bitrix\Main\SystemException;
use Bitrix\Sale\BasketItem;
use Bitrix\Sale\Order;
use Bitrix\Sale\Internals;

use Logger\Logger;

class Bus
{
   /**
    * @var Order|null
    */
   protected Order $order;
  
   protected string $activationCode;
   /**
    * @var array
    */
   public array $coupons = [];
   /**
    * @var string|null
    */
   protected $uid = null;
   /**
    * @var int
    */
   public $index = 0;
   /**
    * @var Logger
    */
   protected $logger;
   /**
    * @var int
    */
   protected $countItems;

   const DEBUG = false;

   public function __construct(int $orderId)
   {
       $this->logger = new Logger('admitad/'.date('Y-m-d').'.log');

       $this->order = Order::load($orderId);
       $this->uid = Helpers::getCookie();

       $this->getActionCode();
       $this->getCoupon();

       $this->countItems = count($this->order->getBasket());
   }

   public function sendOrder(): bool
   {
       try {
           foreach ($this->order->getBasket() as $index => $item) {
               $this->index = $index + 1;
               $params = $this->getParamsOrder($item);
               $this->addPromocode($params);
               $this->sendPosition($params);
           }
       } catch (Exception|\Error $e) {

           $this->logger->error(json_encode([
               'method' => __METHOD__,
               'line' => __LINE__,
               'message' => $e->getMessage(),
               'trace' => $e->getTrace()
           ]));

           return false;
       }

       return true;
   }

   private function addPromocode(&$params)
   {
       if($this->coupons) {
           $coupons = $this->coupons;
           $params['promocode'] = array_shift($coupons);
       }
   }

   private function sendPosition(array $params)
   {
       $curl = curl_init();
       curl_setopt_array($curl, [
           CURLOPT_URL => Helpers::URL_SEND . '?' . http_build_query($params),
           CURLOPT_RETURNTRANSFER => true,
           CURLOPT_HEADER => false,
           CURLOPT_SSL_VERIFYPEER => false,
           CURLOPT_SSL_VERIFYHOST => false,
       ]);
       curl_exec($curl);
       $info = curl_getinfo($curl);
       $error = curl_error($curl);
       curl_close($curl);

       if($info['http_code'] != 200) {
           $this->logger->error(json_encode([
               "info" => $info,
               "error" => $error,
           ]));
       } else {
           $this->logger->info("Заказ ".$this->order->getId()." позиция ".$params["position_id"].' товар ID '.$params['product_id']);
       }

       if(self::DEBUG) {
           $this->logger->debug("Заказ " . $this->order->getId() . ' ссылки ' . json_encode($params));
           $this->logger->debug("Ссылка " . Helpers::URL_SEND . '?' . http_build_query($params));
       }
   }


   private function getParamsOrder(BasketItem $basketItem): array
   {
       $fields = $basketItem->getFields()->getValues();
       return [
           'postback' => '1',
           'tariff_code' => '1',
           'payment_type' => 'sale',
           'postback_key' => Helpers::getPostBackKey(),
           'campaign_code' => Helpers::getCampaignCode(),
           'uid' => $this->uid,
           'position_count' => $this->countItems,
           'position_id' => $this->index,
           'price' => $fields['PRICE'],
           'quantity' => (int)$fields['QUANTITY'],
           'currency_code' => $fields['CURRENCY'],
           'product_id' => $fields['PRODUCT_ID'],
           'order_id' => $this->order->getId(),
           'action_code' => $this->activationCode,
       ];
   }

   protected function getEmailOrder(): string
   {
       if ($this->order instanceof Order)
           return (string)$this->order->getPropertyCollection()->getUserEmail()->getValue();

     return '';
   }

   protected function getActionCode(): string
   {
       /*
        *  Целевые действия и тарифы:


           action_code=1 – Оплаченный заказ старого клиента (без купона)
           tariff_code=1 – Тариф по умолчанию


           action_code=2 – Оплаченный заказ старого клиента (с купоном)
           tariff_code=1 – Тариф по умолчанию


           action_code=3 – Оплаченный заказ нового клиента с купоном
           tariff_code=1 – Тариф по умолчанию


           action_code=4 – Оплаченный заказ нового клиента без купона
           tariff_code=1 – Тариф по умолчанию
       */
       $matrix = [
           'ORDER_OLD_USER_0' => '1', //Оплаченный заказ старого клиента (без купона)
           'ORDER_OLD_USER_1' => '2', //Оплаченный заказ старого клиента (с купоном)
           'ORDER_NEW_USER_0' => '4', //Оплаченный заказ нового клиента (без купона)
           'ORDER_NEW_USER_1' => '3', //Оплаченный заказ нового клиента (с купоном)
       ];
       $email = $this->getEmailOrder();
       $key = ($email !== '' && $this->isNewUserByEmail($email)) ? 'ORDER_NEW_USER_' : 'ORDER_OLD_USER_';
       $key .= ($this->isUseCoupon() ? '1' : '0');
       $this->activationCode = $matrix[$key];

       return $this->activationCode;
   }

   protected function getCoupon() {

       $discountData = $this->order->getDiscount()->getApplyResult();
       foreach ($discountData['COUPON_LIST'] as $coupon => $params) {
           if ($params['APPLY'] == 'Y') {
               $this->coupons[] = $params['COUPON'];
           }
       }
       if(self::DEBUG)
           $this->logger->debug("Купоны " . json_encode($this->coupons));
   }

   protected function isUseCoupon(): bool
   {
       $discountData = $this->order->getDiscount()->getApplyResult();
       foreach ($discountData['COUPON_LIST'] as $coupon => $params) {
           if ($params['APPLY'] === 'Y') {
               return true;
           }
       }

       return false;
   }

   protected function isNewUserByEmail($email): bool
   {
       $result = Internals\OrderPropsValueTable::getList([
           "filter" => [
               "CODE" => "EMAIL",
               "VALUE" => $email
           ]
       ])->fetchAll();

       if(self::DEBUG)
           $this->logger->debug("Количество заказов ".$email.' '.count($result));

       if (count($result) > 1) // больше 1 заказа, текущего
           return false;

       return true;
   }

   /**
    * Метод сохраняет куку Admitad
    * @param Event $event
    * @return void
    * @throws ArgumentException
    * @throws ArgumentOutOfRangeException
    * @throws NotImplementedException
    * @throws ObjectPropertyException
    * @throws SystemException
    */
   public static function onBeforeSaveOrderHandler(Event $event)
   {
       $uid = Helpers::getCookie();
       if ($uid) {
           /** @var  Sale\Order $order */
           $order = $event->getParameter('ENTITY');

           $propAdmitad = $order->getPropertyCollection()->getItemByOrderPropertyCode(Helpers::COOKIE_NAME);
           $propAdmitad->setValue($uid);
       }
   }

   /**
    * Метод отправляет заказ в Admitad
    * @param Event $event
    * @return void
    * @throws ArgumentNullException
    */
   public static function onSaveOrderHandler(Event $event)
   {
       $isNew = $event->getParameter('IS_NEW');

       if ($isNew) {
           /** @var \Bitrix\Sale\Order $order */
           $order = $event->getParameter('ENTITY');
           $propAdmitad = $order->getPropertyCollection()->getItemByOrderPropertyCode(Helpers::COOKIE_NAME);
           if ($propAdmitad->getValue()) {
               try {
                   (new self($order->getId()))->sendOrder();
               } catch (Exception|\Error $e) {
                   (new Logger('admitad/error_send.log'))->error(json_encode([
                       "orderId" => $order->getId(),
                       "message" => $e->getMessage(),
                       "line" => $e->getLine(),
                       "file" => $e->getFile(),
                       "trace" => $e->getTrace(),
                   ]));
               }
           }
       }
   }
}

Определение типа заказа (action_code) 

Скрытый текст

Цель

Определить тип заказа в зависимости от того, является ли пользователь новым или старым, а также от того, использован ли купон.

Как это работает

В зависимости от email пользователя и наличия купона в заказе определяется action_code:

  • 1 — оплаченный заказ старого клиента без купона.

  • 2 — оплаченный заказ старого клиента с купоном.

  • 3 — оплаченный заказ нового клиента с купоном.

  • 4 — оплаченный заказ нового клиента без купона.

Также проверяется, использовался ли купон в заказе isUseCoupon().

Логирование

Цель

Записывать информацию об успешных и неудачных операциях для отладки и анализа.

Как это работает

  • Используется класс Logger, который записывает данные в файлы логов (например, admitad/error_send.log).

  • Логируются ошибки, успешные отправки, а также отладочная информация (если включен режим "DEBUG").

Параметры action_code и tariff_code

Цель

Определить тип заказа и тариф для расчета вознаграждения.

Значения

  1. tariff_code=1 — тариф по умолчанию.

  2. action_code — определяется тип клиента и наличие купона.

Где:

  • 1 — заказ старого клиента без купона.

  • 2 — заказ старого клиента с купоном.

  • 3 — заказ нового клиента с купоном.

  • 4 — заказ нового клиента без купона.

Этот код реализует интеграцию с партнерской сетью Адмитад на платформе Битрикс.

  1. Сохраняет идентификатор пользователя (UID) из партнерской ссылки в куки.

  2. При создании заказа записывает UID в свойства заказа.

  3. Отправляет данные о заказе в Адмитад для учета и начисления вознаграждений.

  4. Определяет тип заказа (новый/старый клиент, с купоном/без купона) для корректного расчета вознаграждения.

  5. Логирует все операции для отладки и анализа.

Данный механизм позволяет партнерам получать вознаграждение за привлеченных клиентов, а магазину — отслеживать эффективность партнерской программы.

4. Скриншот отчета для сверки

Загружаем таблицу из Адмитад сайта

У нас есть таблица Excel, которую мы берем из системы Адмитад. Эту таблицу мы загружаем на сайт.

Добавляем данные с сайта

К этой таблице мы прикрепляем информацию с сайта по номерам заказов. Это нужно, чтобы объединить данные о заказах из Адмитад с фактической информацией о заказах с сайта, например, статус заказа: оформлен, отменен, возвращен.

После этого мы скачиваем обновленную таблицу для работы с отчетностью.

Работаем с таблицей

1. Фильтруем данные.

В таблице выбираем только те заказы, которые пришли с рекламного канала Пикабу.

Таблица из Адмитад содержит все заказы, которые были оформлены через рекламный трафик.

Таблица, которая объединена с данными сайта, показывает, что произошло с этими заказами, например, какие заказы были отменены или возвращены. 

2. Считаем переходы.

Количество переходов по рекламе (сколько человек перешли по рекламной ссылке) берется из другого источника, и эти данные предоставляются отдельно.

3. Считаем конверсию.

Формула чистой конверсии:

Чистая конверсия (%) = ((Оформленные - Отмененные) / Количество переходов) * 100 

Примеры расчета конверсии по источникам

Пример для канала Пикабу

  1. Оформленные заказы — 14.

  2. Отмененные заказы — 4.

  3. Количество переходов — 127.

Данные из таблицы.

Подставляем в формулу, получаем:

((14 - 4) / 127) * 100 = ~7.8% 

Если учитывать возвраты, например, товар не подошел покупателю, то возвраты — 3.

Итого: отмененные + возвраты = 7.

Подставляем в формулу:

((14 - 7) / 127) * 100 = ~5.5%  

Пример для канала Промо Хантер

Данные из таблицы.

  1. Оформленные заказы — 34.

  2. Отмененные заказы — 10.

  3. Количество переходов —157.

Подставляем в формулу:

((34 - 10) / 157) * 100 = ~15.3% 

Если учитывать возвраты, то возвраты — 4.

Итого: отмененные + возвраты = 14.

Подставляем в формулу:

((34 - 14) / 157) * 100 = ~12.7%  

Итого

  1. Берем данные из Адмитад и сайта, объединяем их и считаем, насколько эффективны рекламные каналы.

  2. Чистая конверсия показывает, какой процент переходов по рекламе привел к реальным заказам за вычетом отмен и возвратов.

  3. Для канала Пикабу конверсия — около 7.8% или 5.5% с учетом возвратов.

  4. Для канала Промо Хантер конверсия — около 15.3% или 12.7% с учетом возвратов.

На основе подобных данных делаем выводы о размещении на той или или площадке.

Этапы внедрения системы

При работе системы важен комплексный подход — недостаточно просто внедрения, необходим полный цикл запуска рекламной кампании и согласование корректной логики работы интеграции с персональными данными Адмитад. 

Это необходимо, чтобы стоимость покупки клиентов из рекламных источников считалась верно. Если же логика работы не будет соблюдена, данные будут рассчитываться неверно, и клиент будет стоить дороже.

1. Планирование бюджета

  • Четко определить цели кампании: продажи, клиенты, узнаваемость бренда.

  • Сегментировать аудиторию и адаптировать объявления.

2. Оптимизация кампаний

  • Постоянный мониторинг показателей: CTR, CPC, конверсии.

  • Тестирование объявлений, заголовков и целевых страниц.

  • Использование инструментов автоматизации.

3. Управление бюджетом

  • Ответственность маркетологов, performance-отделов или менеджеров по маркетингу.

  • Командная работа для стратегического распределения ресурсов.

4. Сегментация покупателей

  • Использование UTM-меток, промокодов, анализа данных и интеграции с CRM.

  • Отслеживание активности пользователей на сайте.

5. Оценка эффективности

  • Расчет конверсии, CPA и ROI.

  • Учет выполненных и отмененных заказов.

  • Анализ по сегментам: каналы, ключевые слова, аудитории.

6. Синхронизация данных

  • Согласование статусов и триггеров между сайтом и рекламной площадкой.

  • Роль заказчика в настройке и устранении несоответствий.

7. Техническая реализация

  • Использование куки-файлов для отслеживания рекламных меток "utm_source=adm".

  •  Автоматическое удаление куки после заказа или смены метки.

Преимущества нашего решения

Главное, что дает внедрение нашей системы — это отделение одного рекламного канала с возможностью ведения отчетности по заказам, при этом без смешивания с рекламным трафиком из других сред. 

Второй важный момент — система позволяет засчитывать клиентов с отложенной конверсией. То есть если посетитель перешел по рекламной ссылке и ничего не купил, но в течение месяца вернулся на сайт и оформил заказ.

Таким образом бизнес получает:

  1. Автоматизацию процессов.

  2. Учет отложенных конверсий.

  3. Точный учет рекламных каналов.

  4. Защиту от дублирования данных.

  5. Ежемесячные акты сверки по источникам трафика.

  6. Автоматическое удаление куки после заказа или смены метки.

Будет ли подобная система полезна для вашего бизнеса? Поделитесь своим мнением в комментариях.