Интеграция 1С-Битрикс с системой Меркурий
Меркурий — федеральная государственная информационная система ветеринарной сертификации (ФГИС). Предприятия, работающие с продукцией животного происхождения (мясо, рыба, молочные продукты, яйца), обязаны оформлять электронные ветеринарные сертификаты (эВСД) при каждом перемещении товара. Интернет-магазин, принимающий заказы на такие товары, сталкивается с задачей: при поступлении товара на склад и при отгрузке нужно гасить входящие эВСД и оформлять исходящие через систему Меркурий.
Архитектура взаимодействия
Меркурий предоставляет REST API (https://api.vetrf.ru/schema/platform/v2/). Авторизация — через API-ключ, выдаваемый Россельхознадзором после регистрации предприятия в системе.
Поставщик → отгрузил товар с эВСД в Меркурий
→ Магазин получает товар → гасит входящий эВСД (acceptVetDocument)
→ Хранение на складе: учётная единица с ID эВСД
→ Заказ оформлен → продажа физлицу
→ Списание через транзакцию возврата (transferReceiptTransaction)
При продаже конечному потребителю-физлицу оформлять новый эВСД не нужно — достаточно погасить документ в части проданного количества.
PHP-клиент для Меркурий API
class MerkuryClient
{
private string $apiUrl = 'https://api.vetrf.ru/schema/platform/v2';
private string $apiKey;
private string $issuerId; // ID предприятия в Меркурий
public function __construct(string $apiKey, string $issuerId)
{
$this->apiKey = $apiKey;
$this->issuerId = $issuerId;
}
public function getIncomingDocuments(string $enterpriseGuid): array
{
return $this->request('GET',
"/enterprises/{$enterpriseGuid}/vetDocuments",
['status' => 'CONFIRMED', 'type' => 'INCOMING']
);
}
public function extinguishDocument(
string $enterpriseGuid,
string $vetDocId,
float $quantity,
string $unit
): string {
$response = $this->request('POST',
"/enterprises/{$enterpriseGuid}/vetDocuments/{$vetDocId}/extinguish",
[
'returnedQuantity' => $quantity,
'returnedUnit' => $unit,
'operatorId' => $this->issuerId,
]
);
return $response['application']['applicationId'];
}
public function processTransaction(
string $enterpriseGuid,
string $transactionId
): array {
return $this->request('POST',
"/enterprises/{$enterpriseGuid}/applications/{$transactionId}/process"
);
}
private function request(string $method, string $path, array $params = []): array
{
// ... HTTP-запрос с заголовком 'apiKey: {KEY}'
}
}
Хранение эВСД в Битрикс
Каждая партия товара на складе соответствует одному или нескольким эВСД. Таблица:
class VetDocumentTable extends \Bitrix\Main\ORM\Data\DataManager
{
public static function getTableName(): string { return 'local_merkury_vet_docs'; }
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'), // товар в каталоге
new \Bitrix\Main\ORM\Fields\StringField('VET_DOC_ID'), // UUID документа в Меркурий
new \Bitrix\Main\ORM\Fields\StringField('ENTERPRISE_GUID'), // GUID предприятия
new \Bitrix\Main\ORM\Fields\FloatField('QUANTITY'), // остаток на складе
new \Bitrix\Main\ORM\Fields\StringField('UNIT'), // ед. изм: kg, piece
new \Bitrix\Main\ORM\Fields\StringField('STATUS'), // 'active', 'extinguished'
new \Bitrix\Main\ORM\Fields\DatetimeField('EXPIRE_DATE'), // срок годности
];
}
}
При поступлении партии товара — создаётся запись с ID эВСД и количеством. При продаже — количество уменьшается, при исчерпании — статус меняется на extinguished.
Погашение эВСД при отгрузке
public function handleOrderShipped(\Bitrix\Sale\Order $order): void
{
$basket = $order->getBasket();
foreach ($basket as $item) {
$productId = $item->getProductId();
$quantity = $item->getQuantity();
// Находим активный эВСД для товара
$vetDoc = VetDocumentTable::getList([
'filter' => ['PRODUCT_ID' => $productId, 'STATUS' => 'active'],
'order' => ['EXPIRE_DATE' => 'ASC'], // сначала ближайшие к истечению
'limit' => 1,
])->fetch();
if (!$vetDoc) {
\Bitrix\Main\Diag\Debug::writeToFile(
"Нет эВСД для товара {$productId}",
'[MERKURY ERROR]', '/local/logs/merkury.log'
);
continue;
}
$appId = $this->merkury->extinguishDocument(
$vetDoc['ENTERPRISE_GUID'],
$vetDoc['VET_DOC_ID'],
$quantity,
$vetDoc['UNIT']
);
// Обрабатываем транзакцию
$this->merkury->processTransaction($vetDoc['ENTERPRISE_GUID'], $appId);
// Обновляем остаток в локальной таблице
$newQty = $vetDoc['QUANTITY'] - $quantity;
VetDocumentTable::update($vetDoc['ID'], [
'QUANTITY' => max(0, $newQty),
'STATUS' => $newQty <= 0 ? 'extinguished' : 'active',
]);
}
}
Кейс: магазин фермерских продуктов
Интернет-магазин мяса и молочной продукции от фермерских хозяйств. ~250 заказов/неделю. Товары поступают от 15 поставщиков, каждая партия — с отдельным эВСД. Задача: автоматизировать приёмку (гашение входящих эВСД) и отгрузку (списание при продаже).
Особенности:
Меркурий API работает асинхронно: запрос на погашение создаёт «заявку» (application), которую нужно обработать отдельным вызовом. Иногда заявки обрабатываются несколько минут — система Меркурий нагружена.
Реализована двухшаговая модель: при отгрузке создаётся заявка, записывается в очередь, cron-обработчик каждые 2 минуты вызывает processTransaction для ожидающих заявок.
Приёмка товара: кладовщик через административный раздел Битрикс вводит ID прихода из накладной поставщика → система автоматически запрашивает список входящих эВСД от этого поставщика за последние сутки → кладовщик подтверждает соответствие партий → Меркурий фиксирует приёмку.
| Показатель | До | После |
|---|---|---|
| Время оформления приёмки (1 партия) | 15 мин (ручной ввод в Меркурий) | 3 мин (подтверждение) |
| Погашение эВСД при продаже | Не производилось (нарушение) | Автоматически |
| Проверки Россельхознадзора | Предписание | Без замечаний |
Синхронизация остатков
Периодическая сверка: остатки в таблице local_merkury_vet_docs сравниваются с остатками на предприятии в Меркурий (GET /enterprises/{guid}/stockEntries). Расхождения — в лог и уведомление администратору.
Состав работ
- Регистрация в Меркурий, получение API-ключа (через Россельхознадзор)
- Разработка PHP-клиента: входящие документы, погашение, сверка
- Таблица хранения эВСД в Битрикс
- Интерфейс приёмки в административном разделе
- Автопогашение при отгрузке с очередью ретраев
- Синхронизация остатков (cron), мониторинг расхождений
Сроки: 6–10 недель в зависимости от количества поставщиков и сложности складского учёта.







