Эскроу‑счета из двух банков в 1С по API с нуля: из чего состоит интеграция и где подстелить соломку
У застройщика деньги дольщиков лежат не на его счёте, а на эскроу — и до ввода дома в эксплуатацию он видит их, но не распоряжается ими. Для финансиста это отдельная вселенная: нужно знать, сколько поступило по каждому договору долевого участия, что раскрыто, что ещё ждёт. А рядом — обычные расчётные счета, по которым идёт вся текущая жизнь компании.
До интеграции этой информации в 1С не было вообще. Дольщики получали информацию по своим счетам с задержкой до трёх дней.
Задача звучала просто: пусть движение по эскроу и расчётным счетам появляется в 1С само. Готового решения под эскроу‑часть не нашлось, поэтому интеграции со Сбербанк API и Альфа‑Банк API я писал с нуля. Банков два, и API у них разные — это приходится учитывать с первого дня. Ниже — не пересказ документации банка (её лучше читать в первоисточнике, она меняется), а то, из каких частей состоит такая интеграция на стороне 1С и какие решения я бы принял снова.
Из чего состоит интеграция
Если убрать детали, интеграция с банковским API на стороне 1С — это пять слоёв:
Транспорт и авторизация. HTTPS‑запросы, получение и продление доступа к API.
Клиент API. Тонкий слой: «получить список счетов», «получить операции за период», «получить сведения по эскроу‑счёту». Ничего не знает про документы 1С.
Хранилище сырых ответов. Всё, что пришло от банка, сохраняется как есть — до разбора.
Сопоставление. Счёт банка → банковский счёт организации в 1С, контрагент по ИНН, операция по эскроу → договор долевого участия.
Отражение в учёте. Создание документов или записей регистров, идемпотентно.
У Сбербанка и Альфа‑Банка различалось всё, что касается первых двух слоёв: авторизация, устройство API, форматы данных. При таких различиях я бы держал транспорт и клиент API отдельными для каждого банка, а всё, что ниже, — общим: ответ любого банка приводится к одному внутреннему формату операции, и дальше сопоставление и отражение в учёте уже не знают, откуда пришли данные.
Смешивать эти слои — главная ошибка, которую хочется сделать в начале, когда «надо просто скачать выписку». Через месяц окажется, что изменился формат ответа, и ремонт затрагивает всё сразу.
Слой 1. Аутентификация: токены живут своей жизнью
Банковские API почти всегда используют короткоживущий access‑токен и более долгоживущий refresh‑токен. На стороне 1С из этого следуют простые, но обязательные вещи:
токены хранятся в безопасном хранилище (
ОбщегоНазначения.ЗаписатьДанныеВБезопасноеХранилищев БСП), а не в реквизите справочника;обновление токена — одна точка в коде, с блокировкой: если два регламентных задания одновременно решат обновить токен, одно из них может получить уже недействительный refresh;
при ошибке «токен недействителен» — одна попытка обновить и повторить запрос, не больше. Бесконечный цикл ретраев против банковского API — плохая идея.
Функция ВыполнитьЗапросКБанку(Метод, Ресурс, Тело = Неопределено) Экспорт
Ответ = HTTPЗапросСТокеном(Метод, Ресурс, Тело, ТекущийТокен());
Если Ответ.КодСостояния = 401 Тогда
ОбновитьТокенСБлокировкой();
Ответ = HTTPЗапросСТокеном(Метод, Ресурс, Тело, ТекущийТокен());
КонецЕсли;
СохранитьСыройОтвет(Ресурс, Ответ); // до любой обработки
Возврат Ответ;
КонецФункции
Процедура ОбновитьТокенСБлокировкой()
Блокировка = Новый БлокировкаДанных;
Элемент = Блокировка.Добавить("РегистрСведений.СостояниеИнтеграцииСБанком");
Элемент.Режим = РежимБлокировкиДанных.Исключительный;
НачатьТранзакцию();
Попытка
Блокировка.Заблокировать();
// Пока ждали блокировку, токен мог обновить другой сеанс
Если ТокенЕщёДействителен() Тогда
ЗафиксироватьТранзакцию();
Возврат;
КонецЕсли;
НовыеТокены = ЗапроситьТокеныПоRefresh();
СохранитьТокены(НовыеТокены);
ЗафиксироватьТранзакцию();
Исключение
ОтменитьТранзакцию();
ВызватьИсключение;
КонецПопытки;
КонецПроцедуры
Проверка «пока ждали — уже обновили» выглядит лишней ровно до первого дня, когда регламент и ручная кнопка «Загрузить сейчас» сработают одновременно.
Доступы и тестовый контур
Отдельная статья сроков — не код, а доступы: получить тестовый контур, сертификаты, согласовать права приложения со стороны банка и клиента. Закладывайте это в план с самого начала и запускайте параллельно с разработкой.
В нашем случае всё сначала настраивалось на тестовых контурах банков — и это однозначно плюс: транспорт, авторизацию и разбор ответов можно отладить, не касаясь реальных счетов.
Главная сложность: документация и реальное поведение API
Самым трудным оказался не код, а то, что документация не совпадала с тем, как API вёл себя на самом деле. Когда описание метода говорит одно, а ответ приходит другой, угадывать бесполезно — можно долго подстраиваться под поведение, которое завтра снова изменится.
Помогло одно: найти в банке контактное лицо, которое могло разобраться в вопросе, и общаться напрямую. Разговор напрямую со специалистом банка снимал вопросы, которые по документации не решались. Если начинаете похожую интеграцию — ищите такой контакт в самом начале, а не тогда, когда застряли.
Здесь же пригодятся сохранённые сырые ответы (о них — в следующем разделе): с ними на руках разговор идёт о конкретном запросе и конкретном ответе, а не о том, «как оно вроде бы работает».
Слой 3. Сохраняйте сырые ответы
Это правило я повторяю в каждой интеграции, но с банком оно особенно важно. Когда финансист спрашивает «почему в 1С эта сумма, а в банке другая», ответ должен начинаться с «вот что банк прислал в такое‑то время», а не с «давайте попробуем воспроизвести».
Сырой ответ хранится с ключом «ресурс + параметры + время запроса». Разбор идёт из хранилища, а значит его можно повторить после исправления ошибки в сопоставлении — без повторного похода в банк.
Слой 4. Сопоставление: эскроу — это не просто ещё один счёт
С расчётными счетами всё относительно привычно: операция, контрагент по ИНН, назначение платежа. С эскроу появляется ещё одна сущность — договор долевого участия, к которому привязан счёт, и события по нему: поступления от дольщика, раскрытие, закрытие.
Что здесь важно:
Ключ сопоставления — не назначение платежа. Текст назначения пишут люди, и он бывает любым. Надёжнее опираться на идентификаторы, которые отдаёт банк, и один раз связать их с объектами 1С.
Несопоставленное — не ошибка, а очередь. Операция, для которой не нашёлся договор, не должна валить загрузку. Она попадает в список «требует внимания», где человек связывает её руками — и связь запоминается.
Хешируйте ключи поиска. Составной ключ (например, счёт + дата + сумма + идентификатор операции), нормализованный и захешированный, превращает повторный поиск в одно обращение к индексу.
Функция КлючОперации(Операция)
Части = Новый Массив;
Части.Добавить(НРег(СокрЛП(Операция.НомерСчёта)));
Части.Добавить(НРег(СокрЛП(Операция.ИдентификаторОперации)));
Части.Добавить(Формат(Операция.Сумма, "ЧДЦ=2; ЧРД=.; ЧГ=0"));
Хеш = Новый ХешированиеДанных(ХешФункция.SHA256);
Хеш.Добавить(СтрСоединить(Части, "|"));
Возврат ПолучитьHexСтрокуИзДвоичныхДанных(Хеш.ХешСумма);
КонецФункции
Обратите внимание на Формат суммы: без явного формата Строка(1500.5) на разных серверах может дать разный результат из‑за региональных настроек — и хеш «поплывёт».
Слой 5. Идемпотентность: одна операция — один документ
Загрузка будет запускаться повторно — по расписанию с перекрывающимися периодами, вручную, после сбоя. Поэтому до создания документа всегда проверяем, не создан ли он уже по этому ключу. Перекрытие периодов (запрашивать не «с последней загрузки», а «с последней загрузки минус запас») — дешёвая страховка от операций, которые банк проводит задним числом.
Для Каждого Операция Из Операции Цикл
Ключ = КлючОперации(Операция);
Если ОперацияУжеОтражена(Ключ) Тогда
Продолжить;
КонецЕсли;
НачатьТранзакцию();
Попытка
Документ = СоздатьДокументПоОперации(Операция);
ЗапомнитьКлюч(Ключ, Документ);
ЗафиксироватьТранзакцию();
Исключение
ОтменитьТранзакцию();
ПоставитьВОчередьРазбора(Операция, ИнформацияОбОшибке());
КонецПопытки;
КонецЦикла;
Транзакция на каждую операцию, а не на всю выписку: одна проблемная строка не должна блокировать отражение остальных.
Время и даты
Отдельный пункт, потому что он тихий. Банк отдаёт даты в своём формате и часовом поясе; сервер 1С живёт в своём; пользователи — в своём. Договоритесь, какая дата считается датой операции для учёта, и приводите явно. Особенно внимательно — к операциям около полуночи и на границе месяца, где «не та дата» означает «не тот период».
Как это тестировать, не рискуя деньгами
Банковская интеграция — не то место, где хочется «проверить на проде». Порядок, который я считаю правильным:
Тестовый контур банка — для транспорта, авторизации и формата ответов. Мы начинали именно с него.
Копия рабочей базы 1С — для сопоставления и отражения. Именно на копии всплывают проблемы самих данных: контрагенты без КПП, опечатки в номерах банковских счетов организации и тому подобное.
Прогон на реальных сырых ответах. Поскольку ответы банка сохраняются, их можно многократно «проигрывать» на копии, меняя логику сопоставления, — не дёргая банк.
Мониторинг: банк молчит — это тоже событие
Для банковской интеграции я бы выделил три сигнала, о которых ответственный должен узнавать сам, не открывая 1С:
ошибка аутентификации, которую не вылечило обновление токена, — чаще всего это истёкший сертификат или отозванные права приложения;
растущая очередь несопоставленных операций — значит, появился новый контрагент, счёт или договор, о котором 1С не знает;
тишина: за рабочий день по счёту, где обычно есть движение, не пришло ни одной операции. Ошибок нет, а данных нет — самый неприятный вид сбоя.
Отдельно полезно следить за сроком действия сертификата и предупреждать заранее: истёкший сертификат — это день без выписок, который легко предотвратить.
Что получилось
Главное изменение для заказчика — информация по счетам вообще стала доступна в системе: раньше её в 1С не было. Загрузка идёт три раза в день, поэтому дольщики получают информацию день в день, а не с задержкой до трёх дней, как раньше.
Масштаб — около 24 000 счетов по 30 объектам строительства в двух банках (Сбербанк и Альфа‑Банк) с разными API.
Вместо выводов
Банковская интеграция — одна из самых «нервных» для 1С: в ней деньги. Она прощает медленную разработку и не прощает потерянную операцию или задвоенный документ. Поэтому порядок работы у меня такой: сначала хранилище сырых данных и идемпотентность, потом всё остальное. Отладка — на тестовом контуре банка и копии базы. И как можно раньше — живой контакт в банке, потому что документация не всегда совпадает с реальностью.
Если делаете похожую интеграцию и хотите обсудить детали — пишите в комментариях.
KioskNews shows a cleaned-up reading view extracted from the publisher’s page — the original always lives on their site, not ours.