Разработка · 8 мин чтения

Интеграция Битрикс24 CRM с сайтом: вебхуки и REST API

Официальные лицензии Битрикс24, Облако и Коробка

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

Подробнее об услуге

У вас сайт на Битрикс и CRM на Битрикс24 - но они живут отдельно? Форма на сайте отправляет заявку на почту, менеджер вручную создаёт лид в CRM, потом забывает обновить статус. Знакомо? Интеграция через REST API и вебхуки решает это: заявка с сайта автоматически создаёт лид, смена статуса сделки обновляет данные на сайте. Показываем как.

Два способа интеграции

Способ Когда использовать Сложность
Входящий вебхук Сайт отправляет данные в CRM Простая
Исходящий вебхук CRM отправляет данные на сайт Средняя
Приложение (OAuth) Полная интеграция, маркетплейс Высокая

Для большинства задач хватает вебхуков. OAuth нужен, если вы делаете публичное приложение для маркетплейса Битрикс24.

Создание входящего вебхука

Входящий вебхук - это URL, по которому ваш сайт может вызывать REST API Битрикс24.

  1. Битрикс24 → Приложения → Разработчикам → Другое → Входящий вебхук
  2. Задайте название (например, «Сайт - лиды»)
  3. Выберите права доступа: crm, user
  4. Скопируйте URL вида: https://your-domain.bitrix24.ru/rest/1/abc123xyz/

Этот URL - ваш ключ доступа. Храните его в безопасности, не коммитьте в git.

Создание лида из формы на сайте

PHP-класс для работы с Битрикс24 REST API. Методы crm.lead.add, crm.deal.add и crm.contact.add, которые он оборачивает, в документации помечены DEPRECATED: развитие остановлено, актуальная замена crm.item.add с параметром entityTypeId (лид 1, сделка 2, контакт 3) и полями в camelCase, сами вызовы пока доступны:

// /local/php_interface/classes/Bitrix24Api.php

namespace App;

class Bitrix24Api
{
    private string $webhookUrl;

    public function __construct(string $webhookUrl)
    {
        $this->webhookUrl = rtrim($webhookUrl, '/');
    }

    public function call(string $method, array $params = []): array
    {
        $url = $this->webhookUrl . '/' . $method . '.json';

        $ch = curl_init();
        curl_setopt_array($ch, [
            CURLOPT_URL => $url,
            CURLOPT_POST => true,
            CURLOPT_POSTFIELDS => http_build_query($params),
            CURLOPT_RETURNTRANSFER => true,
            CURLOPT_TIMEOUT => 10,
            CURLOPT_SSL_VERIFYPEER => true,
        ]);

        $response = curl_exec($ch);
        $httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
        curl_close($ch);

        if ($httpCode !== 200) {
            throw new RuntimeException("Bitrix24 API error: HTTP $httpCode");
        }

        $data = json_decode($response, true);

        if (isset($data['error'])) {
            throw new RuntimeException("Bitrix24 API: {$data['error_description']}");
        }

        return $data;
    }

    public function createLead(array $fields): int
    {
        $result = $this->call('crm.lead.add', [
            'fields' => $fields,
        ]);

        return (int)$result['result'];
    }

    public function createDeal(array $fields): int
    {
        $result = $this->call('crm.deal.add', [
            'fields' => $fields,
        ]);

        return (int)$result['result'];
    }

    public function getDeal(int $id): array
    {
        $result = $this->call('crm.deal.get', ['id' => $id]);
        return $result['result'];
    }

    public function updateDeal(int $id, array $fields): bool
    {
        $result = $this->call('crm.deal.update', [
            'id' => $id,
            'fields' => $fields,
        ]);

        return $result['result'];
    }
}

Использование при обработке формы:

// Обработчик формы на сайте
use App\Bitrix24Api;

$api = new Bitrix24Api(getenv('BITRIX24_WEBHOOK_URL'));

try {
    $leadId = $api->createLead([
        'TITLE' => 'Заявка с сайта: ' . $_POST['name'],
        'NAME' => $_POST['name'],
        'PHONE' => [['VALUE' => $_POST['phone'], 'VALUE_TYPE' => 'WORK']],
        'EMAIL' => [['VALUE' => $_POST['email'], 'VALUE_TYPE' => 'WORK']],
        'COMMENTS' => $_POST['message'],
        'SOURCE_ID' => 'WEB',
        'UTM_SOURCE' => $_COOKIE['utm_source'] ?? '',
        'UTM_MEDIUM' => $_COOKIE['utm_medium'] ?? '',
        'UTM_CAMPAIGN' => $_COOKIE['utm_campaign'] ?? '',
    ]);

    echo "Лид создан: #$leadId";
} catch (Throwable $e) {
    // Логируем ошибку, но пользователю показываем успех
    // (заявка сохранена в базе сайта, лид создастся при повторной попытке)
    error_log('Bitrix24 error: ' . $e->getMessage());
}

Интеграция с формами Битрикс

Если сайт на 1С-Битрикс, подписываемся на событие отправки формы через init.php:

// /local/php_interface/init.php

use Bitrix\Main\EventManager;

EventManager::getInstance()->addEventHandler(
    'form',
    'onAfterResultAdd',
    'sendLeadToBitrix24'
);

function sendLeadToBitrix24($WEB_FORM_ID, $RESULT_ID)
{
    if ($WEB_FORM_ID != 3) return; // ID формы обратной связи

    $answers = CFormResult::GetDataByID($RESULT_ID, [], $arResult, $arAnswerList);

    $fields = [];
    foreach ($answers as $sid => $rows) {
        $row = $rows[0] ?? [];
        $fields[$sid] = ($row['USER_TEXT'] ?? '') ?: ($row['ANSWER_TEXT'] ?? '');
    }

    $api = new App\Bitrix24Api(getenv('BITRIX24_WEBHOOK_URL'));

    try {
        $api->createLead([
            'TITLE' => 'Заявка #' . $RESULT_ID,
            'NAME' => $fields['FIO'] ?? '',
            'PHONE' => [['VALUE' => $fields['PHONE'] ?? '']],
            'EMAIL' => [['VALUE' => $fields['EMAIL'] ?? '']],
            'COMMENTS' => $fields['MESSAGE'] ?? '',
            'SOURCE_ID' => 'WEB',
        ]);
    } catch (Throwable $e) {
        Bitrix\Main\Diag\Debug::writeToFile($e->getMessage(), '', '/local/logs/b24.log');
    }
}

Передаём данные заказа с товарами в Битрикс24

Частый сценарий: на сайте оформлен заказ с несколькими товарами - нужно создать сделку в CRM с полным составом заказа: наименования, количество, цены. Для этого используем связку crm.deal.add + crm.deal.productrows.set. Оба метода в документации помечены DEPRECATED, замена: crm.item.add с entityTypeId 2 и crm.item.productrow.set с ownerType D; старые вызовы пока доступны. Тот же статус у crm.contact.list и crm.contact.add из примера ниже: в документации стоит «Развитие метода остановлено», замена - crm.item.list и crm.item.add с entityTypeId 3.

function sendOrderToBitrix24(array $order, Bitrix24Api $api): void
{
    // 1. Проверяем, есть ли контакт с таким телефоном
    $existing = $api->call('crm.contact.list', [
        'filter' => ['PHONE' => $order['phone']],
        'select' => ['ID'],
    ]);

    if (!empty($existing['result'])) {
        $contactId = (int)$existing['result'][0]['ID'];
    } else {
        // Создаём новый контакт
        $contactId = (int)$api->call('crm.contact.add', [
            'fields' => [
                'NAME'  => $order['name'],
                'PHONE' => [['VALUE' => $order['phone'], 'VALUE_TYPE' => 'MOBILE']],
                'EMAIL' => [['VALUE' => $order['email'], 'VALUE_TYPE' => 'WORK']],
            ],
        ])['result'];
    }

    // 2. Создаём сделку
    $dealId = $api->createDeal([
        'TITLE'       => 'Заказ #' . $order['id'] . ' с сайта',
        'CONTACT_ID'  => $contactId,
        'OPPORTUNITY' => $order['total'],
        'CURRENCY_ID' => 'RUB',
        'SOURCE_ID'   => 'WEB',
        'COMMENTS'    => 'Адрес: ' . ($order['address'] ?? ''),
    ]);

    // 3. Добавляем товарные позиции к сделке
    $products = [];
    foreach ($order['items'] as $item) {
        $products[] = [
            'PRODUCT_NAME' => $item['name'],
            'PRICE'        => $item['price'],
            'QUANTITY'     => $item['quantity'],
            'MEASURE_NAME' => 'шт',
        ];
    }

    $api->call('crm.deal.productrows.set', [
        'id'   => $dealId,
        'rows' => $products,
    ]);
}

Вызов после оформления заказа:

$api = new Bitrix24Api(getenv('BITRIX24_WEBHOOK_URL'));

sendOrderToBitrix24([
    'id'      => 1042,
    'name'    => 'Иван Петров',
    'phone'   => '+79001234567',
    'email'   => 'ivan@example.com',
    'address' => 'Москва, ул. Ленина 10',
    'total'   => 15000,
    'items'   => [
        ['name' => 'Футболка', 'price' => 2500, 'quantity' => 2],
        ['name' => 'Кепка',    'price' => 1500, 'quantity' => 1],
        ['name' => 'Доставка', 'price' => 500,  'quantity' => 1],
    ],
], $api);

Результат в Битрикс24: сделка с контактом, суммой 15 000 ₽ и тремя товарными позициями. Менеджер видит полный состав заказа в CRM сразу после оформления.

Подключение к WooCommerce

Если сайт на WordPress + WooCommerce, вешаем отправку на хук нового заказа:

// functions.php или отдельный плагин
add_action('woocommerce_new_order', function ($orderId) {
    $wcOrder = wc_get_order($orderId);
    if (!$wcOrder) return;

    $items = [];
    foreach ($wcOrder->get_items() as $item) {
        $items[] = [
            'name'     => $item->get_name(),
            'price'    => (float)$item->get_total() / $item->get_quantity(),
            'quantity' => $item->get_quantity(),
        ];
    }

    // Доставка как отдельная позиция
    $shipping = (float)$wcOrder->get_shipping_total();
    if ($shipping > 0) {
        $items[] = ['name' => 'Доставка', 'price' => $shipping, 'quantity' => 1];
    }

    $api = new App\Bitrix24Api(getenv('BITRIX24_WEBHOOK_URL'));

    sendOrderToBitrix24([
        'id'      => $orderId,
        'name'    => $wcOrder->get_billing_first_name() . ' ' . $wcOrder->get_billing_last_name(),
        'phone'   => $wcOrder->get_billing_phone(),
        'email'   => $wcOrder->get_billing_email(),
        'address' => $wcOrder->get_billing_address_1(),
        'total'   => (float)$wcOrder->get_total(),
        'items'   => $items,
    ], $api);
});

Подключение к Тильде

На Тильде данные формы/корзины можно отправить на ваш серверный скрипт через Webhook URL в настройках формы. Тильда передаст POST-запрос с полями заказа - вы их разберёте и отправите в Битрикс24 тем же способом.

Исходящий вебхук - CRM уведомляет сайт

Сценарий: менеджер перевёл сделку в статус «Оплачено» - на сайте автоматически открывается доступ к контенту.

Создаём исходящий вебхук в Битрикс24:

  1. Приложения → Разработчикам → Другое → Исходящий вебхук
  2. Событие: ONCRMDEALADD или ONCRMDEALUPDATE
  3. URL обработчика: https://your-site.ru/api/bitrix24-webhook.php
  4. Скопируйте токен аутентификации

Обработчик на сайте:

// /api/bitrix24-webhook.php

// Проверка токена
$authToken = getenv('BITRIX24_OUTGOING_TOKEN');

if ($_POST['auth']['application_token'] !== $authToken) {
    http_response_code(403);
    die('Forbidden');
}

$event = $_POST['event'] ?? '';
$dealId = (int)($_POST['data']['FIELDS']['ID'] ?? 0);

if (!$dealId) {
    http_response_code(400);
    die('No deal ID');
}

// Получаем данные сделки через REST API
$api = new App\Bitrix24Api(getenv('BITRIX24_WEBHOOK_URL'));
$deal = $api->getDeal($dealId);

switch ($event) {
    case 'ONCRMDEALUPDATE':
        handleDealUpdate($deal);
        break;

    case 'ONCRMDEALADD':
        handleDealCreate($deal);
        break;
}

function handleDealUpdate(array $deal): void
{
    $stageId = $deal['STAGE_ID'];

    // Сделка оплачена: активируем доступ
    if ($stageId === 'WON') {
        $email = ''; // Получаем email контакта
        if ($deal['CONTACT_ID']) {
            $api = new App\Bitrix24Api(getenv('BITRIX24_WEBHOOK_URL'));
            $contact = $api->call('crm.contact.get', ['id' => $deal['CONTACT_ID']]);
            $email = $contact['result']['EMAIL'][0]['VALUE'] ?? '';
        }

        if ($email) {
            // Активируем доступ в базе сайта
            activateUserAccess($email, $deal['ID']);
        }
    }

    // Сделка отменена: деактивируем доступ
    if ($stageId === 'LOSE') {
        deactivateAccess($deal['ID']);
    }
}

http_response_code(200);
echo json_encode(['status' => 'ok']);

JavaScript: создание лида из фронтенда

Для SPA или виджетов можно вызывать Битрикс24 API из JavaScript. Но не напрямую (нельзя раскрывать вебхук-токен) - через прокси на сервере:

// Фронтенд: отправка формы
async function submitForm(formData) {
  try {
    const response = await fetch('/api/lead/', {
      method: 'POST',
      headers: { 'Content-Type': 'application/json' },
      body: JSON.stringify({
        name: formData.get('name'),
        phone: formData.get('phone'),
        email: formData.get('email'),
        message: formData.get('message'),
      }),
    });

    const result = await response.json();

    if (result.success) {
      showNotification('Заявка отправлена!');
    } else {
      showNotification('Ошибка. Попробуйте позже.');
    }
  } catch (error) {
    console.error('Form submission error:', error);
  }
}

document.querySelector('#contact-form').addEventListener('submit', (e) => {
  e.preventDefault();
  submitForm(new FormData(e.target));
});

Батчевые запросы

Если нужно создать несколько сущностей за раз - используйте batch:

// Создаём контакт + сделку одним запросом
$result = $api->call('batch', [
    'halt' => 0,
    'cmd' => [
        'contact' => 'crm.contact.add?' . http_build_query([
            'fields' => [
                'NAME' => 'Иван',
                'LAST_NAME' => 'Петров',
                'PHONE' => [['VALUE' => '+79001234567']],
            ],
        ]),
        'deal' => 'crm.deal.add?' . http_build_query([
            'fields' => [
                'TITLE' => 'Разработка сайта',
                'CONTACT_ID' => '$result[contact]',  // ID из предыдущей команды
                'OPPORTUNITY' => 150000,
                'CURRENCY_ID' => 'RUB',
            ],
        ]),
    ],
]);

$contactId = $result['result']['result']['contact'];
$dealId = $result['result']['result']['deal'];

Обработка ошибок и retry

Битрикс24 ограничивает количество запросов - не более 2 в секунду для вебхуков. При превышении лимита вернётся ошибка QUERY_LIMIT_EXCEEDED:

public function callWithRetry(string $method, array $params = [], int $maxRetries = 3): array
{
    $attempt = 0;

    while ($attempt < $maxRetries) {
        try {
            return $this->call($method, $params);
        } catch (RuntimeException $e) {
            if (str_contains($e->getMessage(), 'QUERY_LIMIT_EXCEEDED')) {
                $attempt++;
                sleep(1); // Ждём секунду и повторяем
                continue;
            }
            throw $e;
        }
    }

    throw new RuntimeException("Bitrix24 API: превышено количество попыток");
}

Что можно делать через REST API

Метод Описание
crm.lead.add Создать лид (DEPRECATED, замена crm.item.add с entityTypeId 1)
crm.deal.add Создать сделку (DEPRECATED, замена crm.item.add с entityTypeId 2)
crm.contact.add Создать контакт (DEPRECATED, замена crm.item.add с entityTypeId 3)
crm.deal.update Обновить сделку (DEPRECATED, замена crm.item.update)
crm.deal.list Список сделок с фильтром (DEPRECATED, замена crm.item.list)
crm.lead.productrows.set Добавить товары к лиду (DEPRECATED, замена crm.item.productrow.*)
crm.timeline.comment.add Добавить комментарий в таймлайн
task.item.add Создать задачу
im.notify Отправить уведомление в чат

Не хотите разбираться сами?

Настрою интеграцию вашего сайта с Битрикс24 под ключ: заявки с форм, заказы из корзины, лиды с UTM-метками - всё автоматически попадает в CRM. Работаю с сайтами на WordPress, Тильде, 1С-Битрикс и самописных решениях.

Что входит:

  • Настройка вебхука и прав доступа в Битрикс24
  • Серверный скрипт для передачи данных
  • Проверка дублей контактов
  • Тестирование на реальных заявках
  • Инструкция для вашей команды

Обычно занимает 1-3 дня. Написать в Телеграме - расскажите, какой у вас сайт и CRM, оценю задачу бесплатно.

Условия и возможности Битрикс24 меняются, поэтому перед запуском я уточняю их у самого сервиса.

Есть задача?

Обсудим в мессенджере

Расскажите, что нужно сделать — отвечу в течение 4 часов в рабочее время. Первая консультация бесплатно.

Продолжая пользование настоящим сайтом Вы выражаете своё согласие на обработку Ваших персональных данных (файлов куки) с использованием Yandex.Metrika.
Понятно