Перейти к содержанию
NoiseCut
← Все статьи

Подпись запроса NoiseCut на PHP: как избежать Invalid signature

Как сформировать HMAC SHA256 для NoiseCut на PHP: пример v1, отличия v2 и v3, нормализация полей и причины ошибки Invalid signature.

Для разработчика · Пример для совместимого протокола v1 · Обновлено 10 сентября 2026 года

Чтобы проверить заявку через NoiseCut, сервер сайта формирует JSON и подписывает его секретным ключом. Если нормализация полей на клиенте отличается от серверной, API отклонит запрос. Ниже — разбор HMAC SHA256 и пример формирования запроса для v1. Этот шаг не добавляет CAPTCHA посетителю формы.

Материал помогает проверить существующее подключение v1 или подготовить совместимое подключение без сохранённого IP посетителя. Для подключения с поведенческим контекстом подходят v2 и v3: состав подписи отличается. V3 также подписывает отдельные поля email, организации и дополнительного вопроса. Полный маршрут подключения смотри в документации API NoiseCut.

Где формируется подпись

Секрет хранится в серверной конфигурации твоего приложения. Браузер передаёт поля формы своему серверу; сервер формирует подпись и отправляет запрос NoiseCut. Публиковать ключ в HTML или JavaScript страницы нельзя. Встроенный HMAC не заменяет HTTPS.

Используется endpoint https://noisecut.ru/netcat/modules/noisecut/ingest.php, метод POST и JSON.

Какие значения входят в подпись v1

site|timestamp|name_norm|phone_norm|text_norm
  • site — точное значение сайта, связанного с ключом. Удаляются только пробелы по краям; не добавляй протокол, путь или www самостоятельно.
  • timestamp — одно значение времени в секундах Unix. Оно должно совпадать в подписи и JSON.
  • name_norm и text_norm — нижний регистр UTF-8 через mb_strtolower, затем trim.
  • phone_norm — телефон после удаления всех нецифровых символов через preg_replace('/\D+/', '', $phone).

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

Пример формирования JSON на PHP

Нужны PHP 7.4 или новее и расширение mbstring. Пример только формирует данные: он не отправляет запрос, не записывает персональные данные в лог и не меняет маршрут заявки.

<?php
/** Educational payload builder. No HTTP request, logging or routing. PHP 7.4+. */
function noisecutArticlePayloadV1(
    string $site,
    string $secret,
    string $name,
    string $phone,
    string $text,
    ?int $timestamp = null
): array {
    $site = trim($site);
    $name = trim($name);
    $phone = trim($phone);
    $text = trim($text);
    $timestamp = $timestamp ?? time();
    if ($site === '' || $secret === '' || $timestamp <= 0) {
        throw new InvalidArgumentException('Site, secret and positive timestamp are required.');
    }
    $nameNorm = trim(mb_strtolower($name, 'UTF-8'));
    $phoneNorm = preg_replace('/\D+/', '', $phone);
    $textNorm = trim(mb_strtolower($text, 'UTF-8'));
    $dataString = $site . '|' . $timestamp . '|' . $nameNorm . '|' . $phoneNorm . '|' . $textNorm;
    return [
        'site' => $site,
        'name' => $name,
        'phone' => $phone,
        'text' => $text,
        'timestamp' => $timestamp,
        'signature_version' => 1,
        'signature' => hash_hmac('sha256', $dataString, $secret),
    ];
}

Вызови функцию в своём серверном обработчике, передав домен и ключ из серверной конфигурации, а имя, телефон и текст — из проверенных строковых полей формы. Затем сформируй JSON:

$payload = noisecutArticlePayloadV1($site, $secret, $name, $phone, $text);
$json = json_encode($payload, JSON_UNESCAPED_UNICODE | JSON_THROW_ON_ERROR);

Параметр ID не требуется обработчику: владелец определяется по записи сайта и ключу. Не копируй чужой ID из старого примера. Состав функции намеренно ограничен v1: добавление IP в JSON само по себе не включает поведенческий анализ.

Чем отличаются v2 и v3

В v2 к строке подписи добавляются visitor_ip, user_agent и form_id через разделитель |. IP должен быть валидным IP посетителя, сохранённым вместе с заявкой. IP фонового обработчика для этой цели не подходит. Сервер допускает пустой User-Agent; user_agent проходит trim, затем обрезку до 500 байт; form_id — trim, затем обрезку до 100 байт.

Не переключай действующие подключения на другую версию без проверки их контракта. Функция выше предназначена только для v1.

V3 расширяет подпись v2: в конец добавляются нормализованные email, organization, extra_name и extra_value через |. До приведения к нижнему регистру сервер выполняет trim и ограничивает эти поля соответственно до 255, 255, 100 и 2000 символов при доступном mbstring. Клиент должен применить те же ограничения до подписи. В v1 и v2 эти отдельные поля не обрабатываются; добавление их в JSON не заменяет переход на v3.

Как найти причину Invalid signature

  1. Проверь соответствие домена и ключа в конфигурации. Сравни точное значение site, включая регистр и отсутствие лишних частей URL.
  2. Убедись, что timestamp вычисляется один раз, до формирования подписи.
  3. На синтетических данных сравни нормализованные строки. Обрати внимание на кириллицу, пробелы, формат телефона и переносы LF/CRLF.
  4. Проверь signature_version: сервер по умолчанию использует v1, а v2 и v3 требуют расширенной строки.
  5. Убедись, что после подписи поля больше не преобразуются перед отправкой.

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

После проверки подписи

Успешный ответ содержит status: "ok" и объект analysis. HTTP-ошибка, ошибка JSON или поле error — отдельный исход; их нельзя принимать за успешный анализ. Правила обработки таких исходов сохраняй согласно действующей интеграции.

Подпись подтверждает корректность запроса, но не определяет решение по заявке. Маршрутизация в CRM остаётся отдельной частью подключения. Подробнее — фильтрация заявок до CRM.

Открыть документацию API · Перейти в личный кабинет

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