При проведении безналичной оплаты через эквайринговый терминал (например, Ingenico ipp320 или Verifone) в программах 1С («1С:Розница», «1С:Управление торговлей» и др.) может возникать критическая ошибка: операция по карте на терминале успешно проходит, деньги с покупателя списываются, но 1С выдает сбой XDTO и фискальный чек не печатается.
Рассмотрим подробнее причины возникновения этой проблемы и разберем по шагам варианты её решения — от настройки банковского ПО до программной очистки данных и действий кассира.
Проанализируем техническую суть проблемы. В логе ошибки 1С указывается причина:
Ошибка преобразования данных XDTO: Текст XML содержит недопустимый символ в позиции...
Эта ошибка возникает в момент, когда клиентский модуль 1С получает от драйвера эквайрингового терминала текст слип-чека и пытается передать его в серверную процедуру для последующей печати на фискальном регистраторе (ККТ).
Передача параметров с клиента на сервер в управляемом приложении выполняется посредством механизмов XML-сериализации. По стандарту XML 1.0 в текстовых данных недопустимо использовать служебные управляющие символы ASCII с кодами от 0 до 31 (за исключением табуляции 0x09, перевода строки 0x0A и возврата каретки 0x0D). Эквайринговый терминал или банковская внешняя компонента (DLL) иногда возвращает в тексте слип-чека непечатные символы (например, нулевой байт 0x00, символ прогона страницы 0x0C или ESC-коды для оформления псевдографики и форматирования колонок). При попытке платформы 1С передать такую строку с клиента на сервер происходят аварийный останов и ошибка сериализатора XDTO.
Выясним, какие действия необходимо предпринять со стороны банковского оборудования и драйверов:
pinpad.ini или sbrf.ini) следует отключить использование расширенного форматирования, ESC-последовательностей и графических разделителей в тексте слип-чека.Если конфигурация находится на доработке и нужно быстро устранить сбой в коде, разберем программный способ фильтрации невалидных символов. Обработка текста должна производиться строго на клиенте (&НаКлиенте) до вызова серверного метода.
Посмотрим на пример функции очистки с использованием встроенного метода платформы НайтиНедопустимыеСимволыXML():
&НаКлиенте
Функция ОчиститьТекстОтНедопустимыхСимволовXML(Знач ИсходныйТекст)
НедопустимыеСимволы = НайтиНедопустимыеСимволыXML(ИсходныйТекст);
Если ЗначениеЗаполнено(НедопустимыеСимволы) Тогда
Для Индекс = 1 По СтрДлина(НедопустимыеСимволы) Цикл
СимволДляУдаления = Сред(НедопустимыеСимволы, Индекс, 1);
ИсходныйТекст = СтрЗаменить(ИсходныйТекст, СимволДляУдаления, "");
КонецЦикла;
КонецЕсли;
Возврат ИсходныйТекст;
КонецФункции
Данная функция находит все недопустимые для XML символы в полученной от терминала строке и вырезает их через СтрЗаменить(). После такой очистки строка передается в серверный контекст без сбоев сериализации.
Разберем порядок действий кассира, если списание денег с карты покупателя на терминале уже успешно произошло, но 1С завершилась ошибкой и фискальный чек не распечатался: