При работе с интегрированными банковскими терминалами в конфигурации 1С:Розница пользователи часто сталкиваются с критической проблемой: денежные средства успешно списываются с карты клиента, но фискальный чек продажи не пробивается. Такая ситуация вызывает неудобства как для покупателя, так и для продавца, требуя оперативного и корректного решения. Рассмотрим различные подходы к устранению этой проблемы, основываясь на опыте пользователей и технических рекомендациях.
Прежде чем перейти к решениям, давайте проанализируем основные причины, по которым возникает подобный сбой. Понимание корневых проблем поможет нам выбрать наиболее подходящий метод их устранения или предотвращения:
Один из наиболее простых и часто применяемых на практике способов оперативного решения проблемы, когда деньги списаны, но чек не пробит, предлагает нам создать запасной вариант оплаты. Рассмотрим его по шагам.
В справочнике Контрагенты создадим две записи для банка-эквайера. Например, если основным банком является Сбербанк, мы создадим:
Сбербанк (основной контрагент).Использовать в случае сбоя Сбербанк (или аналогичное название, которое четко указывает на его предназначение).Несмотря на то, что поступления на расчетный счет будут приходить от одного фактического банка, использование двух контрагентов на уровне 1С:Розница позволит нам гибко управлять процессом пробития чеков. В дальнейшем, при получении выписки, нам, возможно, придется вручную соотнести поступления с этими контрагентами, если потребуется точный управленческий учет по каждому из них.
В справочнике Эквайринговые терминалы также создадим две записи, привязанные к конкретной кассе ККМ:
подключаемое оборудование. Этот терминал будет использоваться для штатных операций оплаты картой с непосредственным взаимодействием с банковским терминалом.использовать ЭТ без подключения к системе. Этот терминал не будет пытаться связаться с физическим банковским терминалом и позволит пробить фискальный чек, минуя фазу авторизации через него. Привязываем его к соответствующему "сбойному" контрагенту.При осуществлении оплаты платежной картой в РМК кассир всегда будет иметь выбор банковского терминала. Если произошел сбой: деньги с карты клиента списались (это подтверждает слип-чек от банковского терминала), но штатная оплата в 1С:Розница не завершилась и фискальный чек не пробит, кассир должен:
использовать ЭТ без подключения к системе.Таким образом, мы гарантируем, что покупатель получит фискальный чек, а продажа будет корректно отражена в системе.
Если кассир по ошибке выбрал дублирующий терминал Использовать в случае сбоя Сбербанк вместо основного, и чек был пробит без фактической банковской операции, нам придется сделать возврат денежных средств покупателю по этому чеку, а затем заново создать и пробить чек, используя основной банковский терминал для фактического списания средств.
Часто возникает вопрос, происходит ли возврат денег покупателю при сверке итогов, если чек не был пробит или пробит наличными. Опыт показывает, что ситуация может развиваться по-разному в зависимости от банка-эквайера и настроек его процессинга:
Всегда рекомендуем настраивать автоматическую сверку итогов на банковском терминале и обучать кассиров процедурам ручного возврата.
Другой программный подход позволяет пробить чек по безналу без отправки данных в банк, защищая эту операцию паролем. Это предотвращает случайное или злонамеренное использование функции. Рассмотрим шаги и необходимый код.
При возникновении сбоя, когда деньги с карты списаны, но фискальный чек не пробит, кассир вызывает специальную функцию, которая запросит 11-значный пароль. После ввода верного пароля система создает и пробивает чек по безналу, но при этом явно указывает, что ДанныеПереданыВБанк установлены в Истина, имитируя успешную банковскую операцию без фактической отправки данных в банк в этот момент.
Для реализации этого функционала нам потребуется добавить или модифицировать процедуры в модуле управляемой формы РМК, а также добавить вызов этих процедур по нажатию кнопки.
На стороне клиента нам понадобится процедура для обработки оповещения о вводе пароля:
&НаКлиенте
Процедура ОповещениеОткрытьФормуВводаЧислаВвестиПарольПробитьБезналичный(РезультатОткрытияФормы, ДополнительныеПараметры) Экспорт
//фдуч
Если НЕ РезультатОткрытияФормы = Неопределено Тогда
ЧислоВвода = РезультатОткрытияФормы.ВведенноеЧисло;
// Здесь 'пароль' должен быть переменной или константой, хранящей требуемый пароль
Если ЧислоВвода <> пароль Тогда
Возврат;
КонецЕсли;
фдЗаполнитьСтрокуОплаты;
ЗаполнитьТаблицуЧеков;
ЗавершитьОплатуТоваров(Ложь);
КонецЕсли;
КонецПроцедуры
На стороне сервера потребуется процедура для заполнения строки оплаты, которая будет использовать данные об эквайринговом терминале и виде оплаты:
&НаСервере
Процедура фдЗаполнитьСтрокуОплаты() //фдуч
фдЭквайринговыйТерминал = Справочники.ЭквайринговыеТерминалы.ПустаяСсылка;
фдВидОплаты = Справочники.ВидыОплатЧекаККМ.ПустаяСсылка;
Запрос = Новый Запрос;
Запрос.Текст =
"ВЫБРАТЬ РАЗРЕШЕННЫЕ
| ЭквайринговыеТерминалыТарифыЗаРасчетноеОбслуживание.Ссылка КАК ЭквайринговыйТерминал,
| ЭквайринговыеТерминалыТарифыЗаРасчетноеОбслуживание.ВидОплаты КАК ВидОплаты
|ИЗ
| Справочник.ЭквайринговыеТерминалы.ТарифыЗаРасчетноеОбслуживание КАК ЭквайринговыеТерминалыТарифыЗаРасчетноеОбслуживание
|ГДЕ
| ЭквайринговыеТерминалыТарифыЗаРасчетноеОбслуживание.Ссылка.Касса = &КассаККМ
| И ЭквайринговыеТерминалыТарифыЗаРасчетноеОбслуживание.Ссылка.Организация = &Организация
| И НЕ ЭквайринговыеТерминалыТарифыЗаРасчетноеОбслуживание.Ссылка.ПометкаУдаления";
Запрос.УстановитьПараметр("КассаККМ" , ТаблицаКассККМОрганизаций[0].КассаККМ);
Запрос.УстановитьПараметр("Организация", ТаблицаКассККМОрганизаций[0].Организация);
Результат = Запрос.Выполнить();
ТаблицаВидовОплат = Результат.Выгрузить();
Если ТаблицаВидовОплат.Количество > 0 Тогда
фдЭквайринговыйТерминал = ТаблицаВидовОплат[0].ЭквайринговыйТерминал;
фдВидОплаты = ТаблицаВидовОплат[0].ВидОплаты;
КонецЕсли;
СтрокаОплаты = Объект.Оплата.Добавить;
СтрокаОплаты.ВидОплаты = фдВидОплаты;
СтрокаОплаты.Сумма = Объект.Товары.Итог("СуммаВсего");
СтрокаОплаты.Организация = ТаблицаКассККМОрганизаций[0].Организация;
СтрокаОплаты.ЭквайринговыйТерминал = фдЭквайринговыйТерминал;
СтрокаОплаты.ДанныеПереданыВБанк = Истина;
КонецПроцедуры
И наконец, код для вызова этой операции по нажатию кнопки в РМК:
//фдуч пробить чек с оплатой по карте без отправки данных в банк
ОбработчикОповещения = Новый ОписаниеОповещения("ОповещениеОткрытьФормуВводаЧислаВвестиПарольПробитьБезналичный", ЭтотОбъект);
ПолучитьИнтерактивноЧисло("Введите пароль для завершения операции", 0, 99999999999, Ложь, Ложь, ОбработчикОповещения);
Обратите внимание, что переменная пароль должна быть определена и хранить правильное значение. Для обеспечения безопасности, этот пароль должен быть известен только ответственным сотрудникам и не должен быть легкодоступным для обычных кассиров.
Этот подход направлен на изменение стандартной логики обработки ошибок при печати слип-чеков банковским терминалом. Идея заключается в том, чтобы, если банковская операция по списанию средств уже подтверждена (например, по внешнему слип-чеку), но возникла проблема с печатью слип-чека через драйвер 1С, система все равно позволила бы пробить фискальный чек. Это решение требует осторожности и понимания влияния на всю систему.
В типовой конфигурации 1С:Розница, в модуле ПодключаемоеОборудованиеУниверсальныйДрайверКлиент, есть процедура ПечатьТекста, которая отвечает за печать слип-чеков. Если эта процедура сталкивается с ошибкой при печати, она возвращает Ложь, что может привести к отмене всей операции и непробитию фискального чека. Проанализируем участок кода, который вызывает такую ситуацию:
// Оригинальный фрагмент кода (для понимания)
Попытка
Для Каждого ТекстПечати Из ДанныеЧека Цикл
Результат = ОбъектДрайвера.НапечататьТекстовыйДокумент(ПараметрыПодключения.ИДУстройства, ТекстПечати);
Если НЕ Результат Тогда
ВыходныеПараметры.Очистить();
ВыходныеПараметры.Добавить(999);
ВыходныеПараметры.Добавить("");
ОбъектДрайвера.ПолучитьОшибку(ВыходныеПараметры[1]);
Возврат Результат; // Здесь происходит выход, если печать слипа не удалась
Иначе
ВыходныеПараметры.Очистить();
ВыходныеПараметры.Добавить(0);
ВыходныеПараметры.Добавить(0);
ВыходныеПараметры.Добавить(0);
ВыходныеПараметры.Добавить(МенеджерОборудованияКлиентПереопределяемый.ДатаСеанса);
КонецЕсли;
КонецЦикла;
Исключение
Результат = Ложь;
ВыходныеПараметры.Очистить();
ВыходныеПараметры.Добавить(999);
ВыходныеПараметры.Добавить(НСтр("ru='Ошибка вызова метода .'") + Символы.ПС + ОписаниеОшибки);
КонецПопытки;
Как мы видим, если ОбъектДрайвера.НапечататьТекстовыйДокумент возвращает Ложь, процедура немедленно завершается, препятствуя дальнейшему пробитию фискального чека.
Предлагается изменить логику таким образом, чтобы даже при ошибке печати слип-чека, если банковская операция фактически прошла, процедура не прерывалась. Мы установим переменную Результат в Истина после попытки печати слипа, тем самым "обманывая" систему и позволяя ей продолжить пробитие фискального чека.
Измененный фрагмент кода будет выглядеть следующим образом:
// Модифицированный фрагмент кода в ПодключаемоеОборудованиеУниверсальныйДрайверКлиент.ПечатьТекста
//...
Попытка
Для Каждого ТекстПечати Из ДанныеЧека Цикл
СлипЧек = ОбъектДрайвера.НапечататьТекстовыйДокумент(ПараметрыПодключения.ИДУстройства, ТекстПечати);
Результат = Истина; // Принудительно устанавливаем Результат в Истина, даже если СлипЧек вернул Ложь
Если НЕ Результат Тогда // Это условие теперь всегда будет Ложь, если предыдущая строка выполнилась
ВыходныеПараметры.Очистить();
ВыходныеПараметры.Добавить(999);
ВыходныеПараметры.Добавить("");
ОбъектДрайвера.ПолучитьОшибку(ВыходныеПараметры[1]);
Возврат Результат;
Иначе
ВыходныеПараметры.Очистить();
ВыходныеПараметры.Добавить(0);
ВыходныеПараметры.Добавить(0);
ВыходныеПараметры.Добавить(0);
ВыходныеПараметры.Добавить(МенеджерОборудованияКлиентПереопределяемый.ДатаСеанса);
КонецЕсли;
КонецЦикла;
Исключение
Результат = Ложь;
ВыходныеПараметры.Очистить();
ВыходныеПараметры.Добавить(999);
ВыходныеПараметры.Добавить(НСтр("ru='Ошибка вызова метода .'") + Символы.ПС + ОписаниеОшибки);
КонецПопытки;
//...
Этот код сначала пытается напечатать слип (результат сохраняется в СлипЧек), но затем принудительно устанавливает Результат = Истина. Это означает, что последующая проверка Если НЕ Результат Тогда будет проигнорирована, и процесс продолжится, позволяя пробить фискальный чек. Если слип-чек не напечатался, кассир может распечатать его копию через штатную функцию банковского терминала.
Независимо от выбранного метода решения, существуют общие рекомендации, которые помогут минимизировать возникновение проблем и обеспечить стабильную работу:
Выбирая между организационными и программными решениями, оцените свои ресурсы, уровень квалификации персонала и требования к безопасности. Организационные методы проще внедрить, но требуют строгого соблюдения процедур. Программные решения могут быть более гибкими и автоматизированными, но требуют компетенции программиста 1С и внимательности при модификации стандартного функционала.