Разработка коннекторов для интеграции 1С-Битрикс с внешними системами
Коннектор — изолированный PHP-модуль, инкапсулирующий логику взаимодействия с одной внешней системой. Правильно разработанный коннектор не зависит от конкретной бизнес-логики сайта, легко тестируется и переиспользуется между проектами.
Структура модуля-коннектора
Коннектор реализуется как модуль Битрикса. Структура директории:
/local/modules/vendor.connector_name/
├── install/
│ ├── index.php # Установщик модуля
│ └── db/
│ └── install.sql # Таблицы модуля
├── lib/
│ ├── Client.php # HTTP-клиент к внешней системе
│ ├── Mapper.php # Маппинг данных Битрикс ↔ внешняя система
│ ├── Queue.php # Очередь задач
│ └── EventHandler.php # Подписка на события Битрикса
├── options.php # Страница настроек в админке
└── include.php
Базовый класс клиента
namespace Vendor\ConnectorName;
use Bitrix\Main\Web\HttpClient;
use Bitrix\Main\Data\Cache;
abstract class BaseApiClient {
protected string $baseUrl;
protected array $defaultHeaders = [];
abstract protected function authenticate(HttpClient $http): void;
public function call(string $method, string $endpoint, array $data = []): array {
$http = new HttpClient(['socketTimeout' => 10, 'streamTimeout' => 30]);
$this->authenticate($http);
foreach ($this->defaultHeaders as $name => $value) {
$http->setHeader($name, $value);
}
$url = rtrim($this->baseUrl, '/') . '/' . ltrim($endpoint, '/');
$rawResponse = match(strtoupper($method)) {
'GET' => $http->get($url . '?' . http_build_query($data)),
'POST' => $http->post($url, json_encode($data)),
'PUT' => $http->query(HttpClient::HTTP_PUT, $url, json_encode($data)),
'DELETE' => $http->query(HttpClient::HTTP_DELETE, $url),
default => throw new \InvalidArgumentException("Unknown method: $method"),
};
$statusCode = $http->getStatus();
if ($statusCode >= 400) {
$this->handleError($statusCode, $rawResponse, $endpoint);
}
return json_decode($rawResponse, true) ?? [];
}
protected function handleError(int $code, string $body, string $endpoint): void {
$error = json_decode($body, true)['message'] ?? $body;
\Bitrix\Main\Diag\Debug::writeToFile(
date('Y-m-d H:i:s') . " [{$code}] {$endpoint}: {$error}\n",
'', '/local/logs/connector_errors.log'
);
throw new \RuntimeException("API error {$code}: {$error}");
}
}
Маппер данных
Маппер — отдельный класс, отвечающий за преобразование структур данных. Это ключевое место, которое меняется при изменении контракта внешней системы:
class OrderMapper {
// Битрикс-заказ → формат внешней CRM
public function toExternal(\Bitrix\Sale\Order $order): array {
$props = $order->getPropertyCollection();
return [
'external_id' => $order->getId(),
'total' => $order->getPrice(),
'customer' => [
'email' => $props->getUserEmail(),
'phone' => $props->getItemByOrderPropertyCode('PHONE')?->getValue(),
'name' => $props->getItemByOrderPropertyCode('NAME')?->getValue(),
],
'items' => $this->mapBasketItems($order->getBasket()),
'status' => StatusMap::toExternal($order->getField('STATUS_ID')),
];
}
// Ответ внешней CRM → обновление заказа Битрикс
public function applyToOrder(array $externalData, \Bitrix\Sale\Order $order): void {
$newStatus = StatusMap::toBitrix($externalData['status']);
if ($newStatus && $order->getField('STATUS_ID') !== $newStatus) {
$order->setField('STATUS_ID', $newStatus);
}
}
}
Очередь с повторными попытками
class Queue {
private const TABLE = 'b_vendor_connector_queue';
public static function push(string $type, array $payload): void {
\Bitrix\Main\Application::getConnection()->query(
"INSERT INTO " . self::TABLE . " (TYPE, PAYLOAD, STATUS, ATTEMPTS, DATE_CREATE)
VALUES ('" . $type . "', '" . json_encode($payload) . "', 'pending', 0, NOW())"
);
}
public static function process(int $batchSize = 20): void {
$rows = \Bitrix\Main\Application::getConnection()->query(
"SELECT * FROM " . self::TABLE . "
WHERE STATUS = 'pending' AND ATTEMPTS < 5
ORDER BY DATE_CREATE LIMIT " . $batchSize
);
while ($row = $rows->fetch()) {
try {
self::dispatch($row['TYPE'], json_decode($row['PAYLOAD'], true));
self::markDone($row['ID']);
} catch (\Throwable $e) {
self::markFailed($row['ID'], $e->getMessage());
}
}
}
}
Страница настроек модуля
В options.php размещаем форму ввода параметров коннектора — URL внешней системы, API-ключ, режим (тест/прод), частота синхронизации. Используем стандартный CAdminTabControl Битрикса для интеграции с административным интерфейсом.
Чувствительные данные (API-ключи) шифруем перед записью в b_option через openssl_encrypt() с ключом из .env.
| Задача | Трудозатраты |
|---|---|
| Базовая структура модуля | 4–6 ч |
| HTTP-клиент с обработкой ошибок | 4–6 ч |
| Маппер данных | 4–8 ч |
| Очередь с повторными попытками | 4–6 ч |
| Страница настроек и тесты | 4–6 ч |







