Как реализовать работу с API облачной кассы из 1С?

Программист 1С v8.3 (Обычные формы) IT и автоматизация бизнеса
← На главную

Работа с облачными кассами (такими как Атол Онлайн, Orange Data или Бизнес.Ру) принципиально отличается от работы с локальным фискальным регистратором. Если в случае с обычной кассой мы используем драйвер и синхронные методы, то облачный сервис требует взаимодействия через HTTP API. В данной статье мы подробно разберем, как построить архитектуру обмена данными, реализовать авторизацию и правильно сформировать JSON-пакеты для пробития чеков.

Основные принципы взаимодействия с облачным сервисом

Прежде чем приступать к написанию кода, проанализируем специфику облачных решений. Большинство сервисов работают по асинхронной схеме. Это означает, что процесс фискализации разделен на несколько этапов:

  1. Авторизация: 1С отправляет учетные данные и получает временный токен (token).
  2. Постановка в очередь: 1С отправляет данные чека в формате JSON. В ответ приходит уникальный идентификатор операции (uuid), но не сам фискальный признак.
  3. Запрос статуса: Спустя некоторое время 1С опрашивает сервис по этому uuid, чтобы узнать результат операции.

Рассмотрим подробнее каждый из этих шагов на практических примерах кода.

Шаг 1: Установка защищенного соединения и авторизация

Для работы с любым облачным API нам потребуется объект HTTPСоединение. Поскольку все современные сервисы работают по протоколу HTTPS, обязательным условием является использование объекта ЗащищенноеСоединениеOpenSSL. Выясним, как правильно инициализировать соединение и получить токен доступа.

Посмотрим на пример процедуры авторизации:


// Создаем защищенное соединение
Защита = Новый ЗащищенноеСоединениеOpenSSL();
Соединение = Новый HTTPСоединение("api.service.ru", , , , , , Защита);

// Подготавливаем данные для авторизации (обычно JSON с логином и паролем)
ДанныеАвторизации = Новый Структура;
ДанныеАвторизации.Вставить("login", "vash_login");
ДанныеАвторизации.Вставить("pass", "vash_password");

ЗаписьJSON = Новый ЗаписьJSON;
ЗаписьJSON.УстановитьСтроку();
ЗаписатьJSON(ЗаписьJSON, ДанныеАвторизации);
СтрокаЗапроса = ЗаписьJSON.Закрыть();

// Формируем запрос
Запрос = Новый HTTPЗапрос("/auth/login");
Запрос.УстановитьТелоИзСтроки(СтрокаЗапроса, КодировкаТекста.UTF8, ИспользованиеByteOrderMark.НеИспользовать);
Запрос.Заголовки.Вставить("Content-Type", "application/json; charset=utf-8");

// Отправляем запрос и получаем ответ
Ответ = Соединение.ОтправитьДляОбработки(Запрос);

Если Ответ.КодСостояния = 200 Тогда
    ЧтениеJSON = Новый ЧтениеJSON;
    ЧтениеJSON.УстановитьСтроку(Ответ.ПолучитьТелоКакСтроку());
    Результат = ПрочитатьJSON(ЧтениеJSON);
    ТокенДоступа = Результат.token; // Сохраняем токен для дальнейших запросов
    ЧтениеJSON.Закрыть();
Иначе
    Сообщить("Ошибка авторизации: " + Ответ.КодСостояния);
КонецЕсли;

Шаг 2: Формирование JSON для регистрации чека

Самый трудоемкий этап — правильное формирование структуры чека. Согласно требованиям ФФД 1.05 и 1.2, необходимо передавать множество обязательных реквизитов. Разберем типичную структуру объекта items (товары). Обратите внимание, что ставки НДС передаются строковыми константами (например, vat20), а не числами.

Проанализируем пример формирования структуры данных чека:


ДанныеЧека = Новый Структура;
ДанныеЧека.Вставить("external_id", Строка(ДокументСсылка.Номер)); // Уникальный ID в вашей системе
ДанныеЧека.Вставить("timestamp", Формат(ТекущаяДата(), "ДФ=dd.MM.yyyy HH:mm:ss"));

// Данные покупателя обязательны для электронных чеков
Покупатель = Новый Структура;
Покупатель.Вставить("email", "client@mail.ru");
Покупатель.Вставить("phone", "79991234567");
ДанныеЧека.Вставить("receipt", Новый Структура("client, items, total", Покупатель, Новый Массив, 0));

// Заполнение товарных позиций
Для Каждого СтрокаТЧ Из ДокументСсылка.Товары Цикл
    Позиция = Новый Структура;
    Позиция.Вставить("name", СтрокаТЧ.Номенклатура.Наименование);
    Позиция.Вставить("price", СтрокаТЧ.Цена);
    Позиция.Вставить("quantity", СтрокаТЧ.Количество);
    Позиция.Вставить("sum", СтрокаТЧ.Сумма);
    Позиция.Вставить("measurement_unit", "шт");
    Позиция.Вставить("payment_method", "full_payment"); // Способ расчета
    Позиция.Вставить("payment_object", "commodity");    // Предмет расчета
    
    // Налоги
    Налог = Новый Структура("type", "vat20");
    Позиция.Вставить("vat", Налог);
    
    ДанныеЧека.receipt.items.Добавить(Позиция);
    ДанныеЧека.receipt.total = ДанныеЧека.receipt.total + СтрокаТЧ.Сумма;
КонецЦикла;

Шаг 3: Отправка данных и обработка очереди

После формирования JSON мы отправляем его на сервер. В ответ сервис возвращает uuid. Важно понимать, что в этот момент чек еще не пробит — он только встал в очередь на кассу.

Рассмотрим, как отправить запрос с использованием полученного ранее токена:


Запрос = Новый HTTPЗапрос("/v5/sell"); // Пример пути для Атол Онлайн v5
Запрос.Заголовки.Вставить("Token", ТокенДоступа);
Запрос.Заголовки.Вставить("Content-Type", "application/json; charset=utf-8");

ЗаписьJSON = Новый ЗаписьJSON;
ЗаписьJSON.УстановитьСтроку();
ЗаписатьJSON(ЗаписьJSON, ДанныеЧека);
Запрос.УстановитьТелоИзСтроки(ЗаписьJSON.Закрыть());

Ответ = Соединение.ОтправитьДляОбработки(Запрос);
ЧтениеJSON = Новый ЧтениеJSON;
ЧтениеJSON.УстановитьСтроку(Ответ.ПолучитьТелоКакСтроку());
РезультатЗапроса = ПрочитатьJSON(ЧтениеJSON);

Если РезультатЗапроса.status = "wait" Тогда
    ИдентификаторЧека = РезультатЗапроса.uuid;
    // Теперь нужно запустить цикл ожидания или обработчик ожидания для проверки статуса
КонецЕсли;

Особенности работы с маркировкой и ФФД 1.2

Если вы работаете с маркированными товарами (система "Честный ЗНАК"), в структуру каждой позиции item необходимо добавить реквизит marking_code. Выясним основные моменты:

Полезные советы по реализации

Проанализируем несколько технических нюансов, которые помогут сделать интеграцию более надежной:

  1. Использование External_id: Всегда передавайте уникальный идентификатор документа из 1С в поле external_id. Это защитит вас от двойного пробития чека при сетевых сбоях: если сервис получит повторный запрос с тем же ID, он просто вернет статус уже созданного чека.
  2. Кодировка UTF-8: При использовании ЗаписьJSON 1С корректно формирует текст, однако при ручном формировании строки следите, чтобы отсутствовал BOM (Byte Order Mark), так как многие веб-серверы его не воспринимают.
  3. Обработка таймаутов: Облачные сервисы могут быть временно недоступны. Реализуйте в 1С механизм переотправки чеков (например, через регламентное задание), если сервер вернул ошибку 5xx или соединение не удалось установить.
  4. Логирование: Сохраняйте отправленный JSON и полученный ответ в специальный регистр сведений. Это незаменимо при разборе претензий покупателей или налоговой.

Таким образом, мы рассмотрели полный цикл работы с API облачной кассы. Используя объекты HTTPСоединение и ЗаписьJSON, можно реализовать гибкую систему фискализации, не привязанную к конкретному рабочему месту с физическим оборудованием.

← На главную