Розробка проміжного сервісу обміну 1С і 1С-Бітрікс
Пряма інтеграція 1С і Бітрікс працює доти, поки систем дві. Як тільки з'являється третя — CRM, складська програма, маркетплейс — прямі зв'язки перетворюються на павутину. Проміжний сервіс (middleware) вирішує це архітектурно: кожна система спілкується тільки з ним.
Коли потрібен проміжний сервіс
- Кілька сайтів на Бітрікс підключені до однієї 1С
- 1С + Бітрікс + CRM (AmoCRM, Bitrix24) — дані потрібно синхронізувати між усіма
- Нестандартна конфігурація 1С без HTTP-сервісів — потрібен адаптер
- Вимоги до трансформації даних складніші, ніж можна реалізувати в CommerceML-маппінгу
- Бізнес-логіка обміну має бути ізольована та тестована окремо від 1С і Бітрікс
Архітектура middleware
[1С] ←→ [Middleware] ←→ [Бітрікс]
←→ [CRM]
←→ [Маркетплейс]
Middleware — окремий застосунок (PHP, Node.js, Python, Go — за стеком команди). Функції:
- Адаптери підключення: вміє читати/писати в кожну систему через її API
- Маппінг даних: перетворює об'єкти з формату однієї системи у формат іншої
- Черга завдань: зберігає завдання на синхронізацію, забезпечує повтори при збоях
- Журнал обміну: історія всіх операцій із результатами
- Конфігурація правил: які поля синхронізувати, в якому напрямку, з якими перетвореннями
Технічний стек для middleware на PHP
Laravel (або Symfony) + PostgreSQL + Redis (черга) + Horizon (моніторинг черг)
Структура застосунку:
app/
Adapters/
OneCAdapter.php # Читає/пише в 1С через HTTP-сервіси
BitrixAdapter.php # Читає/пише в Бітрікс через REST API
CrmAdapter.php # AmoCRM / Bitrix24
Mappers/
ProductMapper.php # 1С Номенклатура → Бітрікс елемент інфоблоку
OrderMapper.php # Бітрікс замовлення → 1С документ
Jobs/
SyncProductsJob.php # Завдання синхронізації товарів
SyncOrdersJob.php # Завдання синхронізації замовлень
Models/
SyncLog.php # Модель журналу обміну
SyncQueue.php # Таблиця черги завдань
Адаптер Бітрікс REST API
class BitrixAdapter
{
private string $webhookUrl;
public function getOrders(array $filter = []): array
{
$response = $this->call('crm.deal.list', [
'filter' => $filter,
'select' => ['ID', 'TITLE', 'STAGE_ID', 'OPPORTUNITY', 'UF_ORDER_ID'],
]);
return $response['result'] ?? [];
}
public function updateProductStock(int $productId, int $quantity): bool
{
$response = $this->call('catalog.storeProduct.update', [
'id' => $productId,
'fields' => ['AMOUNT' => $quantity],
]);
return $response['result'] ?? false;
}
public function createOrder(array $fields): int
{
$response = $this->call('sale.order.add', ['fields' => $fields]);
return $response['result']['order']['id'] ?? 0;
}
private function call(string $method, array $params = []): array
{
$response = file_get_contents(
$this->webhookUrl . $method . '.json?' . http_build_query($params)
);
return json_decode($response, true);
}
}
Маппер із правилами трансформації
class ProductMapper
{
private array $categoryMapping; // 1С група → Бітрікс секція
private array $propertyMapping; // 1С реквізит → Бітрікс властивість
public function oneCToBitrix(array $oneCProduct): array
{
return [
'IBLOCK_ID' => config('bitrix.catalog_iblock_id'),
'XML_ID' => $oneCProduct['Ref_Key'],
'NAME' => $oneCProduct['Description'],
'ACTIVE' => $oneCProduct['DeletionMark'] ? 'N' : 'Y',
'DETAIL_TEXT' => $oneCProduct['КомментарийДляСайта'],
'IBLOCK_SECTION_ID' => $this->mapCategory($oneCProduct['ОсновнаяТоварнаяГруппа_Key']),
'PROPERTY_ARTICLE' => $oneCProduct['Артикул'],
'PROPERTY_WEIGHT' => $oneCProduct['Вес'] * 1000, // кг → г
'PROPERTY_BRAND' => $this->resolveBrand($oneCProduct['Производитель_Key']),
];
}
private function mapCategory(string $oneCGroupGuid): int
{
return $this->categoryMapping[$oneCGroupGuid] ?? config('bitrix.default_section_id');
}
}
Черга та надійність
class SyncProductsJob implements ShouldQueue
{
use Dispatchable, InteractsWithQueue, Queueable, SerializesModels;
public int $tries = 3;
public int $backoff = 300; // 5 хвилин між спробами
public function handle(OneCAdapter $oneC, BitrixAdapter $bitrix, ProductMapper $mapper): void
{
$products = $oneC->getModifiedProducts($this->sinceDate);
foreach ($products as $oneCProduct) {
try {
$bitrixFields = $mapper->oneCToBitrix($oneCProduct);
$bitrix->upsertProduct($bitrixFields);
SyncLog::create([
'entity' => 'product',
'external_id' => $oneCProduct['Ref_Key'],
'status' => 'success',
]);
} catch (\Exception $e) {
SyncLog::create([
'entity' => 'product',
'external_id' => $oneCProduct['Ref_Key'],
'status' => 'error',
'message' => $e->getMessage(),
]);
// Не зупиняємо всю партію через один елемент
}
}
}
}
Моніторинг та операційний інтерфейс
Middleware без інтерфейсу управління — чорна скринька. Мінімальний dashboard:
- Статус останніх сеансів обміну (успіх / помилка / час)
- Список помилок із можливістю повторного запуску
- Статистика: скільки об'єктів синхронізовано за добу/тиждень
- Ручний запуск синхронізації для окремого об'єкта або типу даних
Реалізується як простий Laravel/Symfony веб-інтерфейс або через Laravel Horizon (моніторинг черг).
Терміни розробки
| Обсяг middleware | Термін |
|---|---|
| Два адаптери (1С + Бітрікс) + 2–3 маппери + черга | 3–5 тижнів |
| + 3-тя система (CRM) + розширений маппінг | +2–3 тижні |
| + Dashboard моніторингу + ручне управління | +1–2 тижні |
| Повна система для 5+ систем | 3–6 місяців |







