Інтеграція 1С-Бітрікс з системою Честний Знак
Честний Знак — система обов'язкового маркування товарів у Росії. З 2020–2024 років маркування поширилося на взуття, одяг, молочну продукцію, тютюн, воду, парфумерію, БАД, антисептики та ряд інших категорій. Інтернет-магазин, що торгує маркованими товарами, зобов'язаний при продажу виводити коди Data Matrix з обігу. Без інтеграції з Честним Знаком — адміністративні штрафи та блокування.
Принцип роботи маркування в e-commerce
При надходженні товару на склад — коди маркування приймаються в Честний Знак (введення в обіг). При продажу — виводяться з обігу (фіксується факт продажу кінцевому споживачу). Виведення з обігу відбувається через чек ОФД або безпосередньо через API Честного Знаку.
Для інтернет-магазину схема виглядає так:
- Товар надійшов на склад → сканування кодів → введення в обіг через API ЧЗ
- Замовлення оформлено → при відвантаженні/видачі — формується чек через ОФД з кодом маркування → ОФД автоматично виводить код з обігу
Якщо ОФД не використовується (самовивіз без чека через касу, доставка кур'єром з електронним чеком) — пряме виведення через API Честного Знаку.
API Честного Знаку (ГІС МТ)
API доступний за адресою https://ismp.crpt.ru/api/v3/. Авторизація — через JWT-токен, що отримується за допомогою КЕП:
class ChestnyZnakClient
{
private string $baseUrl = 'https://ismp.crpt.ru/api/v3';
private string $token;
public function __construct(private string $inn, private string $certSerial)
{
$this->token = $this->authenticate();
}
private function authenticate(): string
{
// Крок 1: отримуємо дані для підпису
$authData = $this->httpGet('/auth/cert/key');
$uuid = $authData['uuid'];
$data = $authData['data'];
// Крок 2: підписуємо дані КЕП
$signature = $this->signWithCert($data, $this->certSerial);
// Крок 3: отримуємо токен
$tokenResponse = $this->httpPost('/auth/cert/', [
'uuid' => $uuid,
'data' => $data,
'signature' => base64_encode($signature),
]);
return $tokenResponse['token'];
}
public function withdrawCodes(array $codes, string $docType = 'SELL'): string
{
$documents = [];
foreach ($codes as $code) {
$documents[] = [
'certificateDocument' => '',
'certificateDocumentDate' => '',
'certificateDocumentNumber' => '',
'tnvedCode' => '',
'uitCode' => $code,
'uituCode' => '',
];
}
$response = $this->httpPost('/lk/documents/create', [
'document_format' => 'MANUAL',
'product_document' => base64_encode(json_encode([
'participantInn' => $this->inn,
'documentFormat' => 'MANUAL',
'type' => $docType, // SELL, RETURN, LOSS
'transferDate' => date('Y-m-d'),
'products' => $documents,
])),
'signature' => $this->signPayload(...),
'type' => $docType,
]);
return $response['documentId'];
}
}
Зберігання кодів маркування в 1С-Бітрікс
Коди Data Matrix зберігаються у власній таблиці, пов'язаній з позиціями замовлення:
class MarkingCodeTable extends \Bitrix\Main\ORM\Data\DataManager
{
public static function getTableName(): string { return 'local_marking_codes'; }
public static function getMap(): array
{
return [
new \Bitrix\Main\ORM\Fields\IntegerField('ID', ['primary' => true, 'autocomplete' => true]),
new \Bitrix\Main\ORM\Fields\IntegerField('PRODUCT_ID'), // ID товару в каталозі
new \Bitrix\Main\ORM\Fields\StringField('CODE'), // код Data Matrix
new \Bitrix\Main\ORM\Fields\StringField('STATUS'), // 'in_stock', 'in_order', 'sold'
new \Bitrix\Main\ORM\Fields\IntegerField('ORDER_ID'), // null доки не в замовленні
new \Bitrix\Main\ORM\Fields\IntegerField('BASKET_ITEM_ID'),
new \Bitrix\Main\ORM\Fields\DatetimeField('WITHDRAWAL_DATE'),
];
}
}
При додаванні товару до замовлення — резервується конкретний код маркування для цієї позиції. При скасуванні замовлення — код повертається до статусу in_stock.
Виведення з обігу при відвантаженні
// Обробник події відвантаження замовлення
public function handleOrderShipped(\Bitrix\Sale\Order $order): void
{
$markedItems = $this->getMarkedItemsFromOrder($order);
if (empty($markedItems)) return;
$codes = array_column($markedItems, 'CODE');
$chestnyZnak = new ChestnyZnakClient(CZ_INN, CZ_CERT_SERIAL);
$documentId = $chestnyZnak->withdrawCodes($codes, 'SELL');
// Оновлюємо статус кодів
foreach ($markedItems as $item) {
MarkingCodeTable::update($item['ID'], [
'STATUS' => 'sold',
'ORDER_ID' => $order->getId(),
'WITHDRAWAL_DATE' => new \Bitrix\Main\Type\DateTime(),
'CZ_DOCUMENT_ID' => $documentId,
]);
}
}
Кейс: магазин одягу з обов'язковим маркуванням
Магазин жіночого одягу, ~1 500 замовлень/місяць. Товари — марковані вироби легкої промисловості. Завдання: при кожному відвантаженні автоматично виводити коди з обігу, при поверненні — повертати в обіг.
Особливості реалізації:
Коди маркування надходять від постачальників у форматі Excel. Розроблено імпортер: завантаження Excel через обробник в адміністративному розділі 1С-Бітрікс → парсинг → додавання кодів до local_marking_codes зі статусом in_stock.
При комплектації замовлення на складі — комірник сканує коди кожного товару. Мобільний застосунок (React Native, WebView з 1С-Бітрікс) надсилає результат сканування на сервер → прив'язує конкретні коди до позицій замовлення.
При відвантаженні — автоматичне виведення з обігу. При поверненні — POST /api/v3/lk/documents/create з типом RETURN, код повертається до статусу in_stock.
| Показник | До | Після |
|---|---|---|
| Ручне виведення з обігу | 1,5–2 години/день | Автоматично |
| Помилки виведення (невірний код) | ~3%/міс | < 0,3% |
| Повернення до Честного Знаку | Пропускалися | Автоматично при оформленні повернення |
Перевірка коду перед продажем
Перед відвантаженням — перевірка статусу коду в ЧЗ (чи не виведено його вже з обігу іншим шляхом):
$codeInfo = $chestnyZnak->httpGet("/facade/identificationtools?uitCode={$code}");
if ($codeInfo['status'] !== 'IN_CIRCULATION') {
throw new \Exception("Код {$code} не перебуває в обігу: {$codeInfo['status']}");
}
Склад робіт
- Реєстрація в Честному Знаку, підключення до API, сертифікат КЕП
- Розробка PHP-клієнта: автентифікація, виведення з обігу, повернення
- Таблиця зберігання кодів маркування в 1С-Бітрікс
- Імпорт кодів від постачальників
- Інтеграція зі складським обліком: резервування кодів при замовленні
- Автовиведення при відвантаженні, повернення при поверненні замовлення
- Моніторинг: статуси документів ЧЗ, помилки виведення
Терміни: базова інтеграція (виведення при продажу, повернення) — 4–6 тижнів. З імпортом кодів, складським обліком, мобільним скануванням — 10–16 тижнів.







