Keitaro -> Meta Conversions API, версия 2026.10.31 (boostclicks.tech)
Статья с разбором: https://boostclicks.tech/keitaro-i-facebook-conversions-api-capi/

Что делает
  Keitaro шлёт S2S-постбэк при статусе lead или sale, postback.php превращает его
  в событие Lead или Purchase и отправляет в Conversions API нужного пикселя.

Установка
  1. Залейте папку на сервер с PHP 7.4+ и расширениями curl и mbstring. Подойдёт папка лендинга
     в Keitaro (lander/capi) или любой ваш сервер с HTTPS.
  2. Скопируйте config.sample.php в config.php и заполните:
     postback_key  длинная случайная строка, без неё скрипт ничего не отправит;
     pixels        ID пикселя => токен Conversions API;
     log_password  пароль для log.php (пусто = журнал выключен).
  3. Дайте PHP право записи в папку: в ней появится logs/ с журналом.
  4. В Keitaro добавьте S2S-постбэк (метод GET) со статусами lead и sale, адрес ниже.
  5. Проверьте: впишите в config.php test_event_code из Events Manager → «Тестовые
     события», сделайте тестовую конверсию, событие появится во вкладке тестов.
     Такие события Meta учитывает как обычные. После проверки уберите test_event_code.

Адрес постбэка (одна строка, параметры через &):
  https://ВАШ-ТРЕКЕР/lander/capi/postback.php?key=КЛЮЧ&status={status}&subid={subid}
  &pixel={sub_id_10}&fbclid={sub_id_11}&url={sub_id_12}&click_time={date:U}
  &time={conversion_time:U}&ip={ip}&ua={user_agent}&payout={conversion_revenue}
  &country={country}&city={city}

Параметры
  key         ключ из config.php (обязательно)
  status      lead или sale, остальные статусы не отправляются
  subid       ID клика Keitaro: из него event_id и external_id
  pixel       ID пикселя (обязательно)
  fbclid      fbclid клика; из него и времени клика собирается fbc
  fbc, fbp    готовые значения cookie _fbc и _fbp, если вы их сохраняете
  click_time  время клика (для fbc), time  время конверсии
  ua          User-Agent посетителя (обязательно для событий сайта)
  ip          IP посетителя (не обязательно, но сильно помогает сопоставлению)
  payout      для Purchase обязателен явно переданный конечный числовой payout >= 0;
              ноль сохраняется как value=0. Пустое/нечисловое/отрицательное/бесконечное
              значение отклоняется локально с HTTP422, без отправки в Meta.
              Десятичная точка и запятая поддерживаются; значение округляется до 2 знаков.
  currency    для Purchase три латинские буквы, без учёта регистра (пример USD);
              если параметр пуст, используется currency из config.php. Проверяется
              формат, а не весь актуальный справочник валют Meta/ISO.
  url         адрес страницы, где была конверсия (обязательно; или default_url в config.php)
  phone, email, name, city, country  данные для сопоставления: можно передавать
              открытыми или готовым SHA-256, скрипт нормализует и захеширует сам
  buyer       подпись в журнале, например имя байера
  test        код тестовых событий для одного постбэка

Безопасность
  config.php исполняется как PHP и ничего не выводит. Журнал logs/*.php начинается
  со строки-заглушки и по прямой ссылке отдаёт 404. Телефоны и почта в журнал не пишутся.
  Если ставили версию 2025 года (папка s2s): удалите её с сервера целиком, в ней
  база db/conversions.db с токенами открывалась по прямой ссылке. Токены из неё
  считайте скомпрометированными и создайте новые в Events Manager.

Изменения 31.10.2026
  Purchase всегда несёт валидированные value/currency, включая явный payout=0.
  mbstring обязателен: preflight выдаёт локальный HTTP500 при отсутствии расширения,
  а ASCII-fallback для Unicode больше не используется. PHP curl также проверяется.
  Данные со статусом Lead сохраняют прежнее поведение необязательной выплаты.

Проверка без реального Meta API
  Из корня распакованной поставки: php tests/run.php
  Дополнительный отказ без расширений: php -n -d disable_functions=mb_strtolower tests/preflight-no-extensions.php
  Явное отключение функции нужно и для PHP-сборок со статически встроенным mbstring.
  Тесты собирают события локально, не вызывают ktc_send/curl_exec, не читают config.php,
  не пишут журнал, не используют токены и не отправляют никаких событий.
  До выкладки прогоните php -l для всех PHP-файлов. Успешные офлайн-тесты не подтверждают
  доставку в настоящий Meta API и не заменяют проверку вашей конфигурации.

Первоисточники
  https://www.php.net/manual/en/function.mb-strtolower.php
  https://www.php.net/manual/en/function.strtolower.php
  https://github.com/fbsamples/gcp-to-conversions-api-dataflow-template#1-expected-source-format-for-both-bigquery-and-gcs
