Как интегрировать Digital Fraud Protection на сайт

По этой инструкции вы подключите DFP к своему сайту: добавите JavaScript-библиотеку на страницы, настроите расшифровку ответа DFP на бэкенде и встроите его в бизнес-логику.

1. Выберите, по какому домену ваш сайт будет обращаться к API DFP

В ходе интеграции вы подключите JavaScript-библиотеку на нужных страницах своего сайта. Эта библиотека будет отправлять запросы к API DFP. Она может обращаться к API через:

  • Стандартный адрес https://fp.servicepipe.tech/fp/. Работает по умолчанию, ничего настраивать не нужно.

  • Ваш поддомен. В этом случае мы выделим для вас IP, а вам нужно настроить A-запись своего поддомена на этот IP.

Если хотите использовать свой поддомен, сообщите нам. Если нет, ничего делать не нужно, просто переходите к шагу 2.

Ниже в примерах используется стандартный адрес API — https://fp.servicepipe.tech/fp/.

2. Получите токен и секретный ключ

Мы передадим вам два значения:

  • CUSTOMER-TOKEN — токен для загрузки JavaScript-библиотеки и вызова API;

  • SECRET-KEY — секретный ключ (передаём в формате Hex), которым ваш бэкенд будет расшифровывать payload.

SECRET-KEY храните только на бэкенде. Не добавляйте его в код страницы и не передавайте в браузер пользователя.

Если у вас есть доверенные источники (например, IP-адреса ваших разработчиков), для которых нужно по умолчанию разрешать защищённые действия:

  1. Передайте нашей техподдержке список признаков, по которым можно распознать трафик таких источников: например, IP-адреса, используемые параметры запроса, особые cookie, HTTP-заголовки и так далее.

    Мы настроим DFP так, чтобы доверенный трафик получал значение параметра white_bot: true.

  2. На своём бэкенде задайте автопропуск запросов с white_bot: true (настраивается на шаге 14 данной инструкции).

3. Подключите библиотеку к сайту

Добавьте JavaScript-библиотеку DFP на страницы, где хотите проверять клиентское окружение и признаки активности ботов:

<script src="https://fp.servicepipe.tech/fp/v1/<CUSTOMER-TOKEN>/fp.js"></script>

После загрузки библиотеки на странице станет доступен класс ServicepipeFP. Через него вы будете вызывать DFP из кода страницы.

Если вам важно разобраться, как работает библиотека, напишите в тех. поддержку — мы всё подробно расскажем.

Код библиотеки обфусцирован с использованием анти-LLM техник, поэтому ответы ИИ при ревёрс-инжиниринге могут быть ошибочными и вводить в заблуждение. Кроме того, при загрузке библиотеки в ChatGPT, Claude, Grok или другой ИИ-сервис есть риск блокировки аккаунта в этом сервисе.

4. Создайте экземпляр ServicepipeFP

На шагах 4-11 вы настроите клиентский код: создадите экземпляр ServicepipeFP, зададите опции, запустите сбор данных, передадите дополнительные параметры, получите результат DFP и отправите его на бэкенд.

Пример готового клиентского кода:

const fp = new ServicepipeFP(
  "https://fp.servicepipe.tech/fp/",
  "<CUSTOMER-TOKEN>",
  {
    prework: true,
    maxRetries: 3
  }
);

await fp.initSP();
await fp.run();

const dfpOptions = {
  customData: JSON.stringify({
    event: "login_attempt"
  })
};

const result = await fp.get(dfpOptions);

await fetch("/api/dfp/check", {
  method: "POST",
  headers: {
    "Content-Type": "application/json"
  },
  body: JSON.stringify(result)
});

Создайте объект ServicepipeFP и передайте в него адрес API DFP и ваш токен:

const fp = new ServicepipeFP(
  "https://fp.servicepipe.tech/fp/",
  "<CUSTOMER-TOKEN>"
);

Если используете свой поддомен, укажите его вместо стандартного адреса:

const fp = new ServicepipeFP(
  "https://fp-check.example.com/fp/",
  "<CUSTOMER-TOKEN>"
);

5. (Опционально) настройте поведение библиотеки

Минимальная рекомендация: включите prework — с ним DFP будет работать быстрее, при этом опция не несёт никаких минусов.

При создании ServicepipeFP можно передать третий аргумент — объект с настройками. Они управляют тем, как библиотека будет собирать данные и что будет делать, если запрос к API DFP не удался.

Пример добавления:

const fp = new ServicepipeFP(
  "https://fp.servicepipe.tech/fp/",
  "<CUSTOMER-TOKEN>",
  {
    prework: true,
    maxRetries: 3,
    fullScan: false
  }
);

Доступны три опции:

Опция Что делает

prework

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

Благодаря этому при вызове get() библиотеке нужно будет выполнить меньше работы — ведь часть операций уже будет сделана. В результате DFP будет работать быстрее.

maxRetries

Задаёт, сколько раз можно повторить запрос к API DFP, если первая попытка не удалась.

fullScan

Позволяет включить дополнительные методы сбора данных. Например:

  • надёжное обнаружение открытия текущей браузерной вкладки пользователем,

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

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

По умолчанию дополнительные методы выключены. Если хотите включить, согласуйте это с нашими инженерами.

6. Добавьте инициализацию библиотеки

Добавьте вызов initSP(), чтобы библиотека получила конфигурацию с сервера Servicepipe:

await fp.initSP();

Если не вызвать initSP() явно, библиотека инициализируется при вызове get(). Но отдельный вызов делает интеграцию предсказуемее: вы заранее понимаете, когда библиотека готова к работе.

7. Добавьте сбор данных

Добавьте вызов run(), чтобы библиотека собрала параметры клиентского окружения. Прежде чем вызывать get(), дождитесь завершения run() — например, с помощью await:

await fp.run();

Если не вызвать run() явно, сбор данных произойдёт внутри get().

Рекомендуем запускать сбор данных о клиентском окружении как можно раньше (например, при открытии страницы), а отправлять их в API DFP — в момент целевого действия (например, входа в аккаунт, отправки формы или подтверждения операции).

Так вы будете получать ответ DFP быстрее и его точность будет выше. Отправка данных настраивается на шаге 10.

8. (Опционально) передайте дополнительный контекст через customData

Дополнительные параметры для запроса DFP передавайте в объекте dfpOptions. Позже вы передадите этот объект методу get().

customData — это произвольная строка с вашими данными. DFP вернёт её в неизменном виде внутри payload как поле custom_data.

Длина строки customData не должна превышать 4096 символов.

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

Пример: один и тот же пользователь может открыть страницу входа, отправить форму, подтвердить платёж или сменить пароль. Через customData вы связываете результат DFP с конкретным событием в своей системе.

Пример объекта dfpOptions с customData:

const dfpOptions = {
  customData: JSON.stringify({
    event: "login_attempt",
    form_id: "main_login"
  })
};

Не передавайте в customData пароли, платёжные данные, токены авторизации и другие секреты.

9. (Опционально) передайте customID

Используйте это поле только после согласования с нашими инженерами.

customID — это стабильный идентификатор пользователя, аккаунта или другого объекта в вашей системе. Он позволяет связать этот объект с его user_id ещё на стороне Servicepipe.

Длина значения customID не должна превышать 128 символов.

Как именно Servicepipe будет использовать эту связь, зависит от вашего сценария. Логику обработки customID, правила, которые нужно реализовать на стороне Servicepipe, и то, как результат отразится в ответе DFP, согласуйте с нашими инженерами. Такая настройка выполняется индивидуально для каждого клиента.

Чтобы передать customID, добавьте его в объект dfpOptions. Если используете и customData, и customID, передайте оба поля в одном объекте:

const dfpOptions = {
  customData: JSON.stringify({
    event: "login_attempt"
  }),
  customID: "account_12345"
};

10. Отправьте собранные данные в DFP и получите результат

Чтобы получить результат DFP, добавьте один из двух вызовов get():

  1. Если на предыдущих шагах вы создали объект dfpOptions, передайте его методу:

    const result = await fp.get(dfpOptions);
  2. Если вы не передаёте customData или customID, вызовите метод без аргументов:

    const result = await fp.get();

Метод отправит собранные данные в Servicepipe.

Если DFP успешно обработал запрос, он вернёт ответ с зашифрованным payload.

Если при обработке запроса возникла ошибка, DFP вернёт незашифрованный ответ в формате JSON, например: { "error": "device data was not collected" }. Возможные ошибки:

Ошибка HTTP-статус Описание

request data is missing

400

В запросе отсутствуют данные отпечатка.

Чтобы избежать этой ошибки, перед вызовом get() дождитесь завершения run() — например, с помощью await.

malformed request

400

Данные запроса повреждены или изменены при передаче.

invalid request configuration

400

Для вашего сервиса в DFP задана некорректная конфигурация. Обратитесь в поддержку.

service is not identified

400

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

device data was not collected

400

Библиотека не смогла собрать отпечаток устройства и браузера пользователя — например, из-за блокировщика или ограничений браузера. Пользователь не идентифицирован.

device data is malformed

400

Данные отпечатка повреждены или имеют неверный формат.

device data is incomplete

400

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

custom_client_id is too long, maximum 128 bytes

400

Значение custom_client_id превышает максимальную длину — 128 байт.

custom_data is too long, maximum 4096 bytes

400

Значение custom_data превышает максимальную длину — 4096 байт.

duplicate request_id

409

Только для S2S-интеграции. Запрос с таким request_id уже принят, поэтому повторно отправлять его не нужно.

internal error

500

Внутренняя ошибка DFP. Повторите запрос позже.

service temporarily unavailable

503

DFP не успел обработать запрос. Повторите его позже.

11. Отправьте ответ DFP на бэкенд

Передайте ответ DFP на свой бэкенд. Именно там должна происходить расшифровка payload, проверка результата и принятие решения.

await fetch("/api/dfp/check", {
  method: "POST",
  headers: {
    "Content-Type": "application/json"
  },
  body: JSON.stringify(result)
});

12. Расшифруйте payload на бэкенде

Для расшифровки:

  1. Декодируйте SECRET-KEY из Hex в бинарные данные.

  2. Декодируйте iv, payload и tag из Base64 в бинарные данные.

  3. Расшифруйте payload с помощью AES-256-GCM, используя SECRET-KEY, iv и tag.

  4. Интерпретируйте результат расшифровки как JSON.

Пример расшифровки на Node.js:

import * as crypto from "crypto";

const secretKey = Buffer.from("<SECRET-KEY>", "hex");
const iv = Buffer.from(input.iv, "base64");
const payload = Buffer.from(input.payload, "base64");
const tag = Buffer.from(input.tag, "base64");

const decipher = crypto.createDecipheriv(
  "aes-256-gcm",
  secretKey,
  iv
);

decipher.setAuthTag(tag);

const decrypted = Buffer.concat([
  decipher.update(payload),
  decipher.final()
]);

const result = JSON.parse(decrypted.toString("utf8"));

Пример расшифрованного payload:

{
  "details": {
    "antidetect": false,
    "bot_hosting": false,
    "bot_score": 0.1,
    "engine": "gecko",
    "hosting": false,
    "incognito": false,
    "isp_active_subnet": true,
    "mobile": false,
    "os": "linux",
    "proxy_score": 0,
    "proxy_signs": [],
    "rdp": false,
    "tor": false,
    "vm": false,
    "vpn": false,
    "webview": false,
    "new_user": false,
    "confidence_score": 1
  },
  "custom_data": "{\"event\":\"login_attempt\",\"form_id\":\"main_login\"}",
  "referer_md5": "9f0b84073da2ef97a63c2f4179981a2e",
  "timestamp": 1777404974833,
  "user_id": "3849965ed6d75d7dc67568d620950bbb",
  "version": 2,
  "white_bot": false
}

О каждом поле подробнее читайте в статье Что значат поля из ответа DFP.

При получении success: false сохраните request_id и передайте его в нашу тех. поддержку.

13. Проверьте свежесть результата

Ваш бэкенд должен сравнить значение поля timestamp с текущим временем UTC.

Не принимайте ответы старше нескольких секунд — это защитит ваш ресурс от replay-атак, то есть атак, в которых злоумышленник пытается выдать старый результат DFP за новый.

Если timestamp свежий, всё в порядке, можно продолжать обработку.

14. Обработайте данные в рамках своей бизнес-логики

Сначала проверьте white_bot. Если значение true, рекомендуем автоматически разрешить защищённое действие. Если false — переходите к проверке других полей: user_id, bot_score, proxy_score, proxy_signs, incognito, antidetect, vm, vpn, rdp, webview, tor, hosting, bot_hosting, isp_active_subnet, engine, os, mobile, new_user, confidence_score и custom_data. Используйте их для решения ваших бизнес-задач.

Ниже пример логики для обнаружения подозрительных попыток входа, основанной на user_id и bot_score. Ваш бэкенд:

  1. Получает user_id из расшифрованного payload.

  2. Проверяет, связан ли этот user_id с аккаунтом пользователя в вашей базе.

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

  4. Если user_id новый и при этом средний/высокий bot_score, запрашивает дополнительное подтверждение для входа.

  5. Сохраняет user_id, результат дополнительной проверки и связь с аккаунтом, чтобы учитывать эти данные при следующих попытках входа.

Мы подготовили для вас готовые инструкции, как использовать DFP для конкретных бизнес-задач:

15. Проверьте интеграцию

После настройки проверьте интеграцию на своём ресурсе:

  1. Откройте страницу, где подключена библиотека DFP.

  2. Выполните действие, для которого вы настроили проверку: например, войдите в аккаунт, отправьте форму или подтвердите операцию.

  3. Убедитесь, что браузер получил результат DFP и отправил его на бэкенд.

  4. Проверьте, что бэкенд расшифровал payload, проверил timestamp, обработал другие поля из ответа DFP и применил ваши правила.