При интеграции торгового оборудования, особенно банковских терминалов через COM-соединение, разработчики часто сталкиваются с мистической ситуацией: программный код идеально отрабатывает при пошаговой отладке, но в реальном режиме «1С:Предприятие» функции просто игнорируются. Разберем эту проблему на примере работы с терминалами Ingenico Desk/3200 и библиотекой ECRCommX.BPOS1Lib (протокол Arcus2).
Ситуация выглядит следующим образом: при вызове метода возврата Refund в обычном режиме работы терминал никак не реагирует, а состояние COM-объекта не меняется. Однако стоит поставить точку останова и пройти тот же самый код по шагам — всё начинает работать корректно, терминал оживает и запрашивает карту.
Проанализируем типовой код вызова функции:
ОбъектДрайвера.Refund(Сумма * 100, 0, Мерчант, КодRRN);
// В режиме отладки здесь терминал просит карту
// В обычном режиме — тишина
Первое подозрение обычно падает на асинхронность или нехватку времени для инициализации порта. Однако простая вставка пауз через Предупреждение или ПриОстановке часто не приносит результата. Рассмотрим причины, по которым это происходит.
Основная причина такого поведения кроется в монопольном доступе к ресурсам. Библиотека ECRCommX.BPOS1Lib взаимодействует с физическим или виртуальным COM-портом (или TCP-сокетом). Если в системе создается еще один экземпляр этого же объекта или происходит попытка обращения к драйверу из другого потока/сеанса, библиотека может «зависнуть» или заблокировать выполнение команд.
Почему в отладке работает? При пошаговом проходе возникают естественные задержки, которые могут позволить операционной системе или драйверу освободить занятый ресурс. Но главное не в этом. Зачастую проблема скрыта в регламентных заданиях, которые запускаются параллельно с вашим сеансом.
В процессе исследования выяснилось, что виновником блокировки часто выступает механизм регламентных заданий 1С. Рассмотрим цепочку событий:
ПриУстановкеПараметровСеанса прописана логика инициализации торгового оборудования, фоновый сеанс пытается «захватить» COM-объект.ECRCommX не поддерживает многопоточность должным образом и блокирует доступ для основного пользовательского сеанса.Важный момент: Операция Void (аннуляция) может работать, так как она часто выполняется по упрощенному протоколу без глубокой сверки с хостом, в то время как Refund (возврат) требует полнофункционального соединения и проверки всех параметров транзакции (RRN, суммы), что делает её более чувствительной к блокировкам драйвера.
Для исправления ситуации выполним следующие действия:
ECRCommX.BPOS1Lib происходит только в клиентском сеансе и только тогда, когда это необходимо. Не стоит инициализировать драйвер терминала «на всякий случай» при старте системы.Чтобы избежать подобных проблем в будущем, рекомендуется использовать защищенный механизм создания объекта. Рассмотрим пример:
Попытка
ОбъектДрайвера = Новый COMОбъект("ECRCommX.BPOS1Lib");
Исключение
Сообщить("Не удалось инициализировать драйвер терминала. Возможно, порт занят другим процессом.");
Возврат;
КонецПопытки;
// Перед выполнением операции проверим готовность
Если ОбъектДрайвера.Init() <> 0 Тогда
Сообщить("Ошибка инициализации устройства: " + ОбъектДрайвера.ErrorDescription);
Иначе
Результат = ОбъектДрайвера.Refund(Сумма * 100, 0, Мерчант, КодRRN);
// Обязательно анализируем код возврата
Если Результат <> 0 Тогда
ПроанализируемПричину(ОбъектДрайвера.ResultCode);
КонецЕсли;
КонецЕсли;
Использование явной проверки ResultCode после вызова метода Refund позволит сразу увидеть причину отказа в обычном режиме. Часто там возвращается код, соответствующий ошибке "Device busy" или "Port locked".
Если код в 1С работает только в режиме отладки, это верный признак конфликта ресурсов или проблем с таймингами. В случае с банковскими терминалами Arcus2 основной причиной является конкуренция за COM-объект со стороны фоновых процессов. Отключение флага запуска отдельного сеанса для регламентных заданий или перенос логики работы с оборудованием строго в клиентскую часть позволяет полностью устранить проблему «зависания» функций возврата и оплаты.