Как знают держатели дебетовых банковских карт Райффайзенбанка, карта является лишь инструментом доступа к счету: она не имеет собственного баланса, по ней доступны только те средства, которые есть на текущем счете клиента. В этой статье мы расскажем об архитектуре технического решения, которое позволяет картам и счетам в нашем банке использовать единый баланс. И также вы узнаете о том, как был организован проект, который позволил нам эту архитектуру реализовать.

Для начала покажем на примере, чем отличаются схемы «карта к счету» и «карта само по себе». Допустим, через банковскую систему РФ вам поступил безналичный перевод — компенсация от государства за рождение ребенка. В схеме «карта к счету» эта сумма становится доступна для расходных операций по карте в момент зачисления перевода на ваш счет в банке. В схеме «карта само по себе» необходимо перевести некоторую сумму денег с обычного счета на карточный, после чего средства можно тратить картой.

Такая, казалось бы, элементарная и логичная функциональность обеспечивается довольно сложным техническим решением, которое удачно реализовано далеко не в каждом банке. Например, до 2014 года в нашем банке балансы дебетовых карт жили отдельно от балансов счетов: карты в процессинге, счета около АБС. Балансы синхронизировались по утрам рабочих дней. Излишне говорить, что такая схема приводила к проблемам у клиентов: если человек досрочно расторгал депозит, то потратить/снять деньги по карте мог только завтра. А если сегодня суббота, то «завтра» превращалось в понедельник. В те времена добрая треть жалоб на banki.ru была так или иначе связана с этой темой. Внутри банка эта реализация также приводила к сложностям: при любой расходной операции по счету нужно было проверить, а не потратил ли клиент те же самые деньги по карте. В итоге большинство систем использовало программный эмулятор POS-терминала, через который проверялся баланс по карте и ставилась специальная блокировка в процессинге. Эта проверка не во всех случаях работала корректно, часто требовалось ручное вмешательство операциониста. Например, карта временно заблокирована, на ней 100 рублей, клиент снимает со счета 100, эмулятор POS-терминала на такую блокировку выдаёт ошибку, сумму не блокирует. Если эту проблему проигнорировать, то после совершения расходной операции по счету клиент разблокирует карту и снимет еще 100 рублей.

Это далеко не полный перечень проблем, с которыми банк сталкивался при использовании прежней архитектуры. В какой-то момент пришло осознание, что эта архитектура сдерживает развитие сервисов банка, и мы решили переделать техническую реализацию «карта к счету».

Ключевой вопрос, на который необходимо было ответить: в какой системе будет жить текущее значение доступного баланса? Обычно в банках есть два кандидата на эту роль — процессинговая система и АБС. Традиционно, в процессинге живут балансы карт в парадигме «карта сама по себе», а в АБС — балансы текущих счетов. Также традиционно, обе эти системы — покупные коробочные решения от крупных поставщиков с ограниченными возможностями кастомизации. Мы решили пойти по третьему пути — сделать отдельную систему для работы с доступным балансом. На это решение нас подвигло несколько факторов.

Во-первых, большинство «счетовых» банковских продуктов (касса, межбанковские платежи, страховки и так далее) у нас не живут внутри АБС. Это вполне себе самостоятельные системы, которые сгружают в АБС готовые бухгалтерские проводки.

Во-вторых, мы хотели сделать минимум доработок в процессинге и АБС силами поставщиков этих систем.

В-третьих, для контроля баланса по расходным операциям со счетом этими внешними системами не использовался механизм самой АБС.

Исторически операционный день в банке был устроен так, что текущее значение баланса по счету вычислялось специальной системой на основании остатка на начало операционного дня в АБС, уже подтвержденных в АБС транзакций/проводок, и промежуточных операционных данных в некоторых транзакционных системах (всего было три таких системы). А как же устроен контроль баланса по операциям, которые инициируются внутри АБС? Ведь не может же она для проверки баланса обращаться в третью систему?! Для кредитных продуктов (плановые списания по графику платежей, работа с просрочкой) АБС использует свой баланс на конец дня, так как по процессу все промежуточные движения из третьих транзакционных систем записываются в АБС до завершения операционного дня. Для транзакционных продуктов (размещение депозитов, отправка валютных платежей и так далее) контроль баланса происходит либо в ручном режиме (если операция вручную вводится в АБС), либо во внешней системе, которая после всех проверок через API формирует операцию в АБС.

Опытный глаз увидит в этой схеме сразу несколько недостатков. Это и реализация расчета текущего баланса вне АБС, и учет в расчете баланса данных третьих систем (которые хранятся на отдельной от АБС СУБД). Мы постарались свои недостатки обратить в преимущества. Тот факт, что текущее значение доступного баланса счета вычисляется вне АБС, имеет ряд преимуществ. Банк может по своему усмотрению (без доработок АБС) менять алгоритмы расчета баланса, мы можем как-то научиться считать баланс в процессе закрытия дня в АБС. Об этом моменте поговорим чуть подробнее. Наша АБС построена по концепции из прошлого века: в ней предусмотрен процесс закрытия дня, который длится несколько часов, и во время которого с АБС нельзя вообще ничего делать — ни транзакции вводить, ни данные смотреть. Но если баланс считается вне АБС, то эту проблему можно обойти!

image

Итак, мы определились с целевой системой, которая будет является источником истины по доступному балансу — это будет ни АБС, ни процессинг, а некая новая система. Назовем её кодовыми буквами NI. Исходя их обозначенных выше особенностей работы систем банка, для корректной реализации системы NI нужно выполнить следующие действия:

  • Отказаться при расчете баланса от анализа данных транзакционных систем (мы упоминали о трех таких системах — это касса, рублевые платежи, конверсии юридических лиц). Это нужно для надежной и быстрой работы авторизаций по картам, чтобы не ходить на сторонние СУБД.
  • Переключить на NI все системы, использующие текущую специализированную систему для расчета баланса. Или подключить старую систему к NI, что проще; это мы в итоге и выбрали.
  • Научить NI как-то работать в процессе закрытия операционного дня АБС.
  • Интегрировать NI с карточным процессингом.
  • Посмотреть, как все эти изменения отразятся на интернет-банкинге.

Отказ от данных третьих систем при расчете баланса по счету


Как это работало? Допустим, на счете клиента на начало дня в АБС баланс составил 100 рублей. Клиент снял через кассу 50 рублей в 10 часов утра. В кассовой системе есть подтвержденная кассиром операция, но проводки по ней в АБС еще не созданы (вспоминаем, что АБС из прошлого века, проводки она любит принимать крупными пачками, а не по одной штучке). Кассовая система по своему плану эту и прочие подтвержденные операции планирует выгрузить проводками в АБС в 12 часов дня единой пачкой. Как учесть в балансе по счету, что 50 рублей уже нет? В начале 2000-х годов в банке этому нашли «элегантное» решение — система расчета баланса откроет соединение с базой кассовой системы и в ней отберет все операции, подтвержденные кассиром, но еще не выгруженные в АБС. И так по трем разным системам.

Очевидно, что учет в доступном балансе счета операции «в моменте», которая позднее будет выгружена в АБС пачкой проводок — достаточно типовая задача. Вся онлайнизация банковских продуктов последних полутора десятилетий была направлена в эту сторону. Получается, что по мере появления новых подобных систем, нашу систему расчета баланса пришлось бы подключать к каждой из них. Это тупик в плане развития. Мы это осознали, когда систем было всего три, и даже с ними было трудно справиться.

Более правильным нам показалось решение, когда создается единое хранилище всех подтвержденных, но еще не выгруженных в АБС движений по счету. А все системы, которым нужно учитывать свои операции в доступном балансе в реальном времени, должны подключаться к этому хранилищу через набор API, которые должны позволят как рассчитывать текущее значение доступного баланса, так и менять его посредством создания движений по счету. Поскольку новую систему решили обозвать NI, то её API будем называть “NI API”. При этом наша старая система расчета доступного баланса должна научиться смотреть в это новое хранилище NI, а само хранилище, в целях быстродействия и надежности, решили разместить на той же системе, где живет АБС. В нашем случае это платформа IBM i.

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

Также в API по созданию движений по счету разумно добавить опции, при которых движение создается только в случае успешной проверки доступного баланса. Внешняя система как бы говорит: «Создай расходную операцию по счету клиента на 100 рублей, если текущее значение его баланса позволяет это сделать».

Представим, как в нашем примере кассовая система должна работать с NI API. Клиент снимает через кассу 50 рублей в 10 часов утра. Кассовая система обращается в NI API с просьбой: «Создай расходную операцию по счету клиента на 50 рублей, если текущее значение его баланса позволяет это сделать». NI рассчитывает баланс, он позволяет совершить операцию, NI создает движение на 50 рублей в своем промежуточном хранилище и отвечает кассовой системе: «Всё хорошо, выдавай». Если бы баланс по счету клиента был меньше 50 рублей, NI ответил бы: «Дело плохо, текущее значение баланса 40 рублей».

Наступает 12 часов, кассовой системе пора выгружать свою пачку совершенных операций проводками в АБС. По идее, в момент выгрузки операций она должна сообщить NI API, что эти движения уже доехали до АБС, и пора бы их убрать из промежуточного хранилища движений. И тут начинаются сложности. По логике процесса выгрузки пачки проводок в АБС, на всю пачку делается один коммит. Значит, надо также пачкой и с одним коммитом убирать эти движения из хранилища NI. Пачки проводок могут быть достаточно большими, промежуток времени между коммитами может быть довольно большим (десятки секунд максимум, но для нас и это много), в течение которого у клиента на счете будет некорректный баланс. Также возможны технические сбои, когда коммит пачки в АБС прошел успешно, а в NI API по какой-то причине — нет. Из-за этого мы рискуем получить неверные значения текущих балансов по счетам клиентов, а в банке такое неуместно.

К счастью, мы идентифицировали эти риски на этапе проектирования системы NI. Для их нивелирования решили «протянуть» функционал NI до АБС. В API по созданию проводок добавили обязательное поле с идентификатором пачки проводок, в которую внешняя система хочет объединить эти проводки. Также была добавлена отдельная функция «Запиши пачку проводок в АБС», по вызову которой NI сам записывал проводки в АБС, с единым коммитом в своем хранилище и в АБС. В этом сильно помогло то, что базы NI и АБС были размещены, по сути, в одной СУБД. Таким образом, кассовая система в 12 часов просто говорила NI API: «Выгрузи пачку проводок NI в АБС и сообщи мне о возникших проблемах».

Проблемы очень редко, но возникали. Например, когда между добавлением расходного движения по счету в NI и выгрузкой этого движения в АБС в банк пришел судебный пристав и арестовал счет. В подобных случаях кассовая система выдавала пользователю информацию о проблемной операции, и надо было обработать ситуацию вручную.

Был разработан NI API, который предоставлял внешним системам несколько логически сгруппированных API:

  • Получение информации по счету (баланс, статусы и так далее).
  • Работа с пачками (создание, удаление, выгрузка в АБС).
  • Работа с отдельными проводками в пачках.
  • Работа с холдами.

Технически, API представлял собой набор программ, написанных на языке программирования Free format ILE RPG с использованием SQL. Для использования API вне платформы IBM I, программы были обернуты в хранимые процедуры на базе DB2 for i, с которыми внешние системы могли работать по стандартным протоколам ODBC, JDBC и так далее. Также доступ к NI API был реализован с корпоративной интеграционной шины ESB, которая, в свою очередь, также обращалась к API по ODBC/JDBC.

Переключить некоторые системы на NI


Так как мы решили доработать прежнюю систему расчета доступного баланса, чтобы она умела работать с новым промежуточным хранилищем движений по счетам NI, то у нас не было нужды дорабатывать все ИТ-системы банка. Но нам необходимо было переделать упомянутые три системы (касса, рублевые платежи, конверсии юр. лиц), чтобы они начали использовать NI API для промежуточных движений, а при расчете баланса мы бы уже не обращались в транзакционные данные этих систем. На деле это оказалось достаточно сложной доработкой, так как в каждой системе пришлось переделать основную логику по обработке жизненного цикла операции. Для системы рублевых платежей пришлось переделать внутреннюю архитектуру системы, перейдя с двухзвенной на трехзвенную. Это потребовалось для того, чтобы централизовать логику по работе с NI API на сервере приложений.

Но основные сложности на данном этапе были связаны не только с техническими и архитектурными, но и с бизнес-аспектами. Перечисленные системы весьма востребованы заказчиками в плане доработок, в беклоге всегда имеется масса идей по развитию, оптимизации продуктов и процессов. Необходимость выполнить столь масштабные доработки без ощутимой, с точки зрения бизнеса, выгоды была воспринята заказчиками без энтузиазма. Напомним, суть изменений сводилась к тому, чтобы система расчета доступного баланса перестала ходить в базы этих систем, а они сами через API уведомляли централизованную систему NI о движениях по счетам. Для бизнеса это практически не имеет ценности.

Найти выход из сложившейся ситуации и склонить бизнес на свою сторону нам помогло удачное стечение обстоятельств. Как раз в то время в кассовой системе внедрялся модуль по внебалансовому учету пластиковых карт. Карт много, процессы их движения достаточно сложные, что означает большое количество проводок по внебалансовым счетам. В старом механизме формирования проводок из внешних систем в АБС есть существенный изъян: созданные в АБС пакеты проводок необходимо акцептовать вручную, используя пользовательский интерфейс самой АБС. Причем это может сделать пользователь с особенными правами, которые выдают только ограниченному кругу лиц. И в упомянутом проекте по внебалансу шли яростные дебаты между различными подразделениями о том, кто будет эти пакеты акцептовывать, кому какие права можно или нельзя давать. Мы предложили решение: в NI API сделать опцию, которая позволит формировать пакеты проводок в АБС уже в акцептованном виде. Разумеется, для этого весь модуль необходимо перевести на новый API. Эта идея всем очень понравилась, нам дали добро на переделку.

Внедрение механизма создания уже акцептованных пакетов проводок технически оказалось довольно сложной, но интересной задачей. Мы анализировали стек вызовов штатных программ АБС по акцепту проводок, отслеживали по журналам транзакций СУБД её манипуляции с данными. В итоге мы научились обманывать АБС и создавать проводки акцептованными. Кассовый модуль по внебалансу запустился на NI API, проводки потекли в АБС без акцепта оператором, а мы получили понимание, как стимулировать бизнес переходить на NI. Секрет оказался прост — надо предлагать бизнесу при миграции дополнительную функциональность, которая упростит их процессы или каким-то иным образом улучшит продукт. И тут-то нам карта и пошла…

В результате NI оброс функциональностью по созданию проводок по заблокированным счетам (актуально для списаний по решению суда и так далее, в старом процессе счета временно разблокировали вручную), замороченными вариантами расчетами баланса под приоритет, овердрафт и прочими хитростями. Это позволило бизнесу при миграции функциональности получить свои плюшки и существенно оптимизировать процессы. Итак, касса и рублевые платежи — done, остались валютообменные операции корпоративных клиентов.

А с этой системой у нас дело не ладилось. В ней проходило очень мало операций, потребностей в развитии функциональности не было, оптимизация не сулила существенных выгод. В итоге нам так и не удалось убедить партнеров в необходимости доработок, и мы махнули на нее рукой. До сих при расчете баланса по счетам корпоративных клиентов открывается соединение с ее СУБД. Но тогда нас это не расстроило, потому что мы добились своей главной цели — по счетам физических лиц все данные для расчета баланса были сконцентрированы в единой СУБД IBM i, расчет работал быстро (порядка 5 миллисекунд на счет) и надежно.

Научить NI работать в процессе закрытия операционного дня


При ближайшем рассмотрении эта задача оказалось на удивление простой. Так как наша АБС в процессе закрытия дня не способна была принимать в себя никакие движения по счетам, то банк ночью просто замирал. Никакие операции по счетам не проводились. Поэтому наши изменения в NI не надо было синхронизировать ни с какими иными системами, кроме самой АБС. В итоге мы сделали небольшие доработки в АБС, вставив вызов особых управляющих программ NI в самом начале (день->ночь) и в самом конце (ночь->день) процесса закрытия операционного дня.

Программа «день->ночь» просто копировала нужные для расчета баланса таблицы АБС в отдельную библиотеку в той же СУБД. Использовалась примитивная конструкция INSERT SELECT. Всё копирование занимало порядка 20 минут. После завершения копирования NI понимал, что теперь необходимо ходить не в таблицу АБС, а в её копию.

Программа «ночь->день» отрабатывала мгновенно, просто переключая NI на работу с основной базой АБС.

Это решение позволило переходить между фазами дня без прерывания сервиса. Все движения по счетам, которые внешние системы хотели совершить во время закрытия дня АБС, накапливались в NI. Далее, после открытия дня АБС, внешним системам надо было дать команду на выгрузку проводок в АБС через NI API. Это не очень удобно для внешних систем, поэтому в дальнейшем был создан механизм STP (от straight through processing), при котором внешняя система только создает проводку в NI, а дальше он уже сам группирует их в пакеты и выгружает в АБС, когда та для этого доступна.

Реализация схемы день-ночь не лишена изящества. Мы задействовали штатный механизм IBM i по работе с контекстом — список библиотек. Были созданы две библиотеки — дневная и ночная. В них были созданы алиасы на дневные и ночные копии таблиц АБС соответственно. Для каждой таблицы и её ночной копии имя алиаса совпадало. Во всех SQL-выражениях для доступа к данным АБС использовались исключительно алиасы.

Перед обработкой каждого вызова NI API смотрит в специальный объект Data Area (очень быстрый на чтение-запись) системы IBM i чтобы понять, не изменился ли режим с прошлого вызова API в этом процессе. Как нетрудно догадаться, режим в Data Area меняет программы день->ночь и ночь->день. Если режим изменился, то программа просто заменяет библиотеку с алиасами в списке библиотек процесса, это крайне быстрая операция.

В результате, все системы-клиенты NI API смогли рассчитывать баланс и проводить операции 24 часа в сутки без перерывов, не особо заботясь об операционном дне в АБС. Для нас это была революция.

На этом мы не остановили развитие логики перехода ночь/день. Те 20 минут на копирование таблиц силами SQL не давали нам покоя. Была придумана и внедрена схема с репликацией с помощью решения высокой доступности MIMIX. Идея в том, что ночная копия создается не в момент начала закрытия дня АБС, а при открытии дня. В течение дня эта копия в режиме, близком к реальному времени, синхронизируется с данными АБС. А чтобы быть готовыми к любым ударам судьбы, мы делаем репликацию сразу на двух системах IBM i: основной и резервной.

image

В данный момент мы переходим день->ночь и обратно практически мгновенно, сервис не прерывается ни на секунду.

Интеграция с процессингом банковских карт


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

С точки зрения доступного баланса, при авторизации необходимо проверить доступный остаток по счету клиента, заблокировать «холдом» сумму транзакции и ответить в платежную систему о своем решении: одобрено или нет. Желательно еще послать клиенту уведомление об операции, но это мы рассмотрим в главе об интернет-банкинге. При клиринге необходимо попытаться найти холд, который был поставлен ранее при авторизации, удалить его и создать проводку по счету клиента.

Наша процессинговая система на момент начала проекта умела при авторизации обращаться за проверкой доступного баланса во внешние системы. Эта функциональность была создана ранее, при объединении с Импэксбанком, так как Импэкс имел продукт «карта к счету». В процессе авторизации операции, после успешного завершения чисто карточных проверок (криптография, PIN-код и так далее) авторизационная система посылает ISO-8583-сообщение во внешнюю систему для финансовой авторизации и ждет ответа определенное количество секунд. От нас требовалось создать специальный модуль NI, который умел бы общаться с процессинговой системой по этому протоколу. Принять сообщение, разобрать на поля, вызвать NI API, сформировать ответ. Достаточно простая задача, но только на первый взгляд.

Первая сложность подстерегала нас с онлайновыми операциями пополнения счета клиента с помощью банковской карты. Это взносы в банкоматы и входящие переводы с карты на карту. По логике работы этих операций, авторизация и клиринг могут пройти в разные банковские дни. Допустим, клиенту с нулевым балансом на счете поступает перевод из стороннего банка 1 апреля в 10:00. В 10:05 клиент эти средства пускает на досрочное погашение кредита. Клиринг по этой операции придет 2 апреля. Если мы 1 апреля (при авторизаици) не сделаем бухгалтерскую проводку с пополнением счета, а просто поднимем баланс «положительным холдом», то после погашения кредита на счете в бухгалтерском учете возникнет отрицательный остаток, технический овердрафт, который закроется только после получения клиринга. В банковской бухгалтерии технических овердрафтов всячески избегают, и выход у нас один — по операциям пополнения делать проводки при авторизации.

Из первой сложности вытекает вторая — курсовые разницы. Когда перевод приходит из иностранного банка, суммы при авторизации и клиринге могут различаться из-за колебания курсов валют. Проиллюстрируем на реальном примере. Наш клиент 11 июня получил перевод на карту из белорусского банка, сумма перевода 15,00 белорусских рублей. Банк физически не может поддерживать курсы конвертации ко всем валютам мира по карточным операциям, мы ведем курсы по трем валютам — рубли, доллары, евро. Платежная система для авторизации пересчитывает сумму перевода по собственному курсу в валюту эмитента, в данном случае это были рубли РФ, сумма составила 455,50. Счет клиента открыт в рублях, поэтому мы ему провели приход на 455,50 рублей. С этого момента клиент может распоряжаться этими деньгами как угодно.

14 июня к нам пришел клиринг из платежной системы, и по этой операции нашему банку перечислили 7,16 Евро. С точки зрения учета выходит, что мы клиенту провели распределенную во времени конверсионную операцию: за 455,50 рублей купили 7,16 Евро. Неплохо бы понять, заработал банк на такой операции или потерял. По нашим курсам на 14 июня выходит, что 7,16 евро мы купили бы у клиента за 445,35 рублей. Значит, банку не повезло и он потерял 10,15 рублей. Бывает, что везет, и на колебаниях банк зарабатывает. Техническая реализация такой схемы расчетов очень сложна. Зачем морочиться, спросите вы, ведь такие операции с валютным риском можно просто не показывать клиенту в балансе до клиринга. К тому же таких операций сравнительно немного. Что греха таить, некоторые банки так и поступают. Но пойти на это нам не позволяет наш девиз — «разница в отношении». Мы считаем, что клиенту важно иметь возможность распоряжаться деньгами в момент совершения перевода, а бухгалтерские и технические заморочки не должны тому препятствовать.

Третью сложность мы придумали себе сами. Наша процессинговая система не умеет считать транзакционные комиссии в момент авторизации. Эти комиссии она считает в оффлайне, когда в банк приходит клиринг, спустя несколько дней. Соответственно, клиент не видит сумму комиссии в SMS при совершении операции, она внезапно возникает в выписке спустя несколько дней. Следуя тактике реализации дополнительной функциональности, мы взяли на борт расчет этих комиссий. Это повлекло за собой создание реплик тарифных таблиц из процессинговой системы, повторение логики расчета комиссии, специальные экраны для ответов на вопросы клиентов и так далее. Зато в результате наши клиенты сразу видят сумму комиссии и в авторизационной SMS, и в выписке.

С авторизацией разобрались, переходим к клирингу. В прежней схеме работы специальная система-посредник брала клиринговые операции по счетам клиентов из процессинговой системы, превращала их в бухгалтерские проводки и складывала в АБС. Причем на момент, когда наш проект дошел до процессинга, эта система-посредник уже работала с NI API (бонус NI в виде автоакцепта пакетов проводок стимулировал бизнес-владельцев систем на подобный переход). На момент клиринга наша основная задача — найти в NI авторизацию, убрать по ней холд и выполнить проводку. Но данных бухгалтерской проводки недостаточно для поиска авторизации. Мы видели два варианта реализации:

  • Создать отдельный API для поиска авторизации и снятия холда.
  • Встроить в «проводочный» API данные карточной транзакции, чтобы за один вызов и проводку добавить, и холд снять.

После долгих раздумий мы отбросили первый вариант, так как в нем предполагалось два вызова NI API — на поиск авторизации и добавление проводки. Возникает риск, что если первый вызов проходит успешно, то второй по какой-то причине ломается. Тогда у клиента снимется холд, а проводка не добавится, и будет завышен баланс со всеми вытекающими последствиями. Для карточного клиринга мы сделали программу-обертку над NI API по добавлению проводок. В этой обертке появились дополнительные поля, специфичные для карточных операций. На основании данных из этих полей NI производил поиск авторизации, понимал, какая была схема обработки в тот момент, исходя из чего либо создавал проводку, либо модифицировал её (например, для случая с входящими переводами). С точки зрения системы-посредника, доработки минимальны. В самом NI пришлось разработать мощную функциональность по поиску авторизаций и поддержке различных вариантов её проведения.

image

Изменения в интернет-банкинге


По теме интернет-банка интересны две вещи: посмотреть баланс карты/счета и выписку. До реализации проекта эти сущности для дебетовых карт и их счетов жили в инернет-банке раздельно. Невозможно было посмотреть текущее значение баланса счетов, отображался лишь баланс на начало дня из АБС. Выписка по счетам также бралась из АБС за прошедшие дни. Сегодня пришел платеж на ваш счет? Увидите в интернет-банке завтра!

По картам клиенты видели реальный баланс и реальные списки операций. Но какая техническая реализация за этим стояла! Интернет-банк постоянно, каждые две минуты обращался в базу процессинга, забирая из нее свежие авторизации по картам и изменения балансов карт. Всё это он складывал в своей базе. Так как балансы из АБС загружались в процессинг раз в день, это событие интернет-банк ловил в логах процессинга и начинал массовую перегрузку балансов всех карт и активных холдов. Эта процедура занимала продолжительное время; пока она шла, клиенты могли увидеть некорректную информацию.

image

С переходом на NI для интернет-банка всё упростилось. Он перестал ходить в базу процессинга, перестал загружать остатки и проводки по счетам из АБС. В момент отображения страницы пользователю интернет-банк через NI API запрашивает балансы и выписки по картам и счетам. Теперь клиенты всегда видят актуальную информацию. По сути, мы перешли от сильной связанности на уровне БД интернет-банка с АБС и системой процессинга к сервисно-ориентированной архитектуре.

Отдельно мы обещали рассказать про SMS-информирование по факту авторизации по карте. До реализации NI SMS генерировались в системах интернет-банкинга по факту получения свежих авторизаций из БД процессинга. В этом проекте мы попробовали реализовать событийно-управляемую архитектуру. Специально для NI был создан топик в системе управления очередями IBM WebSphere MQ. NI публикует в этот топик все события, связанные с изменением баланса: появился холд, появилась проводка, удалился холд и так далее. При этом атрибуты событий выведены в заголовки сообщений, что позволяет подписчикам гибко выбирать только те события, которые им нужны. Система SMS-информирования клиентов первой подключилась к этому топику, клиенты стали получать сообщения быстрее. Наши сотрудники, участвующие в пилоте, даже жаловались, что в новой схеме SMS приходит быстрее, чем банкомат успевает набрать пачку и выдать наличность.

Результаты эксперимента с событийно-управляемой архитектурой были признаны крайне удачными, внутри банка этот подход теперь применяется в широком спектре задач.

image

Заключение


Реализовав столь масштабный проект, банк сумел устранить ряд архитектурных огрехов в процессах обработки транзакций и отображения информации для клиентов, что создало мощную базу для развития продуктов. Вслед за физическими лицами эта функциональность была востребована корпоративными клиентами. Были выпущены специальные карты «Business 24x7», в которых акцент делается на общем балансе счета/карта. Интернет-банк для юридических лиц также оброс онлайновыми сервисами.

Ну, а вы теперь знаете, что стоит за вашей картой Райффайзенбанка, и как мы относимся к надежности и клиентскому опыту. И что у нас переводы на карты зачисляются на счет мгновенно!
Немного сухой статистики:

  • Порядка 70% проводок в банке формируется через NI.
  • API по запросу баланса вызывается в среднем 5 млн раз в сутки, в пиковые дни доходит до 8. Примерно половина всех запросов приходится на ДБО (отображение информации клиентам).
Поделиться с друзьями
-->

Комментарии (23)


  1. SkazochNik
    27.07.2017 19:04
    +1

    А можете сказать слова, какие использовались для объяснения бизнесу не искать еще одно коробочное решение, а сделать систему самим?


    1. aBozhiev
      27.07.2017 21:54
      +2

      Отвечая на Ваш вопрос буквально — никакие. В данном проекте не требовалось объяснять бизнесу выбор того или иного варианта технической реализации проекта. Инициатива исходила от ИТ и операционных подразделений, а бизнес на первых порах не проявлял вовлечения в проекте.
      В сущности, при реализации любой задачи в ИТ встает вопрос делать VS покупать. Мы всегда прорабатываем возможные варианты с различных аспектов — наличие готовых решений на рынке, стоимость внедрения и владения, гибкость и возможность дальнейшего развития… Перечень достаточно большой и часто формируется под конкретную задачу. А когда все оценено и сведено в таблицу, обычно решение о выборе варианта становится очевидным, даже для бизнеса.
      В данном проекте, если рассматривать вариант интеграции существующего процессинга и АБС с помощью сторонней «коробки», предложения на рынке нет. Мы первые и, насколько мне известно — единственные, кто в принципе к данной линейке АБС в режиме Online 24x7 подключил хоть что-нибудь. Поставщик АБС был очень удивлен, узнав что у нас это получилось.


  1. Cobolorum
    27.07.2017 20:34
    +1

    Вы уверены что это надо писать?
    Вы описали тут не лучшую реализацию онланй взаимодействия АБС и Процессинга. Ладно бы это была статья из 2010 года, но сейчас же 2017!
    Не позорьтесь уберите этот срам!


  1. lehha
    27.07.2017 22:13

    Теперь понимаешь, почему в одном банке платеж тебе поступает через 1-2 дня, а в другом через час после отправления. И это межбанк юр.лиц, где скорость тоже важна. Видимо, устаревшие системы и миллиардная чистая прибыль банка никак не могут сойтись друг с другом.

    Ваш случай достаточно интересен, чтобы понять как там всё устроено. Не одна табличка users_balance и SQL-запросы на обновление :)


  1. bromium
    27.07.2017 22:35
    -1

    Мы постарались свои недостатки обратить в преимущества

    Вы выдаете желаемое за действительное. Срамота. Видимо, банк сделал все, чтобы нормальные разрабы от него разбежались


  1. xpancy
    28.07.2017 00:05

    Вы 77 раз упомянули АБС ни разу не сказав, как это расшифровывается? Изумительно!

    Почему вы не использовали реализацию от Импэксбанка? У них было ещё хуже?


    1. aBozhiev
      28.07.2017 09:41

      Прошу прощения, банковская профдеформация. АБС — это автоматизированная банковская система, ядро банка, центральная система, где живут остатки, проводки, считаются проценты, предоставляются данные для отчетности и делается много другой работы.

      Мы как раз использовали реализацию от Импэксбанка на стороне процессинга, и это нам сэкономило довольно много времени. Коллеги, которые в прошлом делали интеграцию процессинга и АБС Импэкса, серьезно помогли нам с подготовкой ТЗ для модуля NI по работе с ISO-8583 сообщениями. Если говорить про саму АБС, то решение Импекса не подходило по целому ряду критичных показателей, в серьез не рассматривали замену АБС.


  1. grokinn
    28.07.2017 07:11

    за 455,50 рублей продали 7,16 Евро. Неплохо бы понять, заработал банк на такой операции или потерял. По нашим курсам на 14 июня выходит, что 7,16 евро мы продали бы клиенту за 445,35 рублей. Значит, банку повезло и он заработал 10,15 рублей.


    Разве не наоборот? В первом случае на счету клиента оказалось 455,50 рублей, во втором оказалось бы меньше — 445,35 рублей, значит банку не повезло и он потерял 10,15 рублей, а клиент заработал их.


    1. aBozhiev
      28.07.2017 10:09

      Спасибо за Вашу внимательность! Клиенту при авторизации дали на 10,15 рублей РФ больше, чем дали бы при клиринге. Значит, банк потерял, а клиент в выигрыше. В этом участке статьи есть еще одна неточность — банк Евро не продал клиенту, а купил у него. Будем инвертировать логику в статье.


  1. kolabaister
    28.07.2017 10:11

    Очень интересная статья, спасибо.
    Во всем тексте меня много раз удивляло отношение к АБС как к чему то незыблемому, все огрехи системы надо воспринимать как должное, и даже не пытаться что то сделать с самой системой, лучше и проще построить обвязку, забирающую у системы значительную часть функционала.
    Я понимаю, что вопрос, вероятно, покажется поверхностным — но АБС вообще не развивается?


    1. aBozhiev
      28.07.2017 10:23

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


  1. luka
    28.07.2017 12:24

    Спасибо, aBozhiev, монументальный труд!
    Вопрос: что будет с NI, если банк решит заменить АБС (гипотетически)?


    1. aBozhiev
      28.07.2017 12:52

      Зависит от того, что будет уметь новая АБС. Если в ней будут возможности работы Online 24x7, удобный API по балансам/проводкам/холдам, рассылка событий о движениях по счетам, штатный и гибкий модуль для интеграции с процессингом, то NI отправится на свалку истории.
      Гипотетическая миграция на новую АБС будет постепенной, некоторый счета из старой будут мигрированы в новую. На этапе параллельной эксплуатации обеих АБС NI сослужит добрую службу, обеспечив для всех внешних систем прозрачность расчета баланса и создания проводок.


  1. kolabaister
    28.07.2017 12:50

    В такой ситуации, вероятно, находятся все старые банки?
    К примеру, я знаю всего один банк, который все учетные движения делает при авторизации сумм по картам, а не при клиринге, и это молодой банк (ну особо не слежу, но это подавалось как очень большое достижение).
    Теперь вот еще ваш.


    1. aBozhiev
      28.07.2017 12:57

      Вопрос в том, что Вы понимаете под термином «учетные движения». Если это бухгалтерсике проводки, то мы не делаем все проводки при авторизации. Покупки в торговых точках мы холдим на счетах клиента при авторизации, проводки формируем при клиринге. Это связано с тем, что суммы при авторизации и клиринге по таким операциям могут расходиться очень сильно. По переводам с карты на карту дисциплина крайне высокая, там можно полностью доверять сумме при авторизации, а значит можно делать проводку.


      1. kolabaister
        28.07.2017 13:24

        Ну, возьмем пример — гашение кредита (или кредитки). Слышал много раз (и сам сталкивался), что многие считают датой поступления дату клиринга. Даже при внесении денег в банкомате часто дата реального поступления отстает от физической операции. Например, этим грешит один банк с патриотичным названием. У него же я встречал случаи проведения платежей задним числом.
        После прочтения этой статьи я понимаю, что ребята, очевидно нагородили костылей вокруг своей системы, что и вызывает подобные казусы.
        Так вот, возвращаясь к примеру — такое поведение систем может вызвать невыполнение, с точки зрения банка, обязательств клиента.


        1. aBozhiev
          28.07.2017 14:03

          Хороший пример. Взносы всегда выжны для клиентов, так как часто они делаются под платеж по кредиту. Поэтому мы делаем проводки по счетам по взносам (либо Cash-In в наш банкомат, либо входящий перевод с чужих карт) в момент авторизации.
          Но в любом случае приходится подводить черту между «сегодня» и «завтра». Допустим, у вас сегодня дата планового платежа по потребительскому кредиту в нашем банке. А Вы находитесь в США, и в 19 часов вечера местного времени отправили перевод с американской карты на карту в нашем банке. У вас «сегодня», а у нас «завтра», поэтому мы засчитаем просрочку по платежу в 1 день.
          В нашем банке по дебетовым картам черта между «сегодня» и «завтра» проходит в районе 22 часов вечера по Москве.


  1. kolabaister
    28.07.2017 15:37

    Достойная позиция, спасибо за ответ. Последний вопрос) А почему 22 часа, почему не полночь? Это тоже объясняется двухчасовым закрытием дня АСБ?


    1. aBozhiev
      28.07.2017 17:34

      Совершенно верно, это время выбрано из-за продолжительности закрытия дня в АБС. Только оно у нас, к сожалению, занимает более двух часов. Время выбрано с таким расчетом, чтобы АБС успела открыться к началу рабочего дня наших восточных филиалов.


  1. vialz
    01.08.2017 15:56

    Спасибо за статью, интересный пример. Но часть решений вызывает, конечно вопросы :) Зачем делать новый бэк в данном случае? Почему все таки не процессинг будет мастером по остатку? Почему не поднимать данные из других бэков через какой нибудь кэшовый слой? Зачем в этот же новый бэк запихивать комиссии? Логичней имхо или в единый каталог продуктовый их запихивать, или вести в ИС, которая мастер по договору клиента (если тарифы предполагают индивидуальность).


    1. aBozhiev
      01.08.2017 16:44

      Зачем делать новый бэк в данном случае? Почему все таки не процессинг будет мастером по остатку?

      Бывают счета без карт. И таких счетов достаточно много. Если остатки хранить в процессинге, то придется либо во всех системах делать две логики и выбор между ними (есть карты/нет карт), либо сгружать в процессинг данные даже по тем счетам, где карт нет. Первый вариант плох тем, что придется переделывать все системы банка, работающие со счетами. И этот вариант не понятно как будет работать, когда к счету карты долгое время не было, и тут ее открыли. Второй вариант плох тем, что на процессинг вырастет нагрузка, а также плата за лицензии (они зависят от числа карт, счетов и т.д. в системе). Также не понятно, как быть с процессинговыми лимитами. Например, у нас есть лимит на сумму одной операции, это глобальное ограничение по рискам. Этот лимит достаточно велик для карточных операций, но для счетовых он слишком мал, ведь клиенты могут переводить десятки/сотни миллионов рублей.

      Почему не поднимать данные из других бэков через какой нибудь кэшовый слой?

      Потому что любой кеш — это задержки. И даже если задержки сделать минимальными, этот подход имеет риск в случае сбоя системы, наполняющей кеш. Допустим, деньги из кассы выданы, но по какой-то причине кассовая система не выложила эту информацию в кеш. В итоге имеем неверный баланс счета.

      Зачем в этот же новый бэк запихивать комиссии? Логичней имхо или в единый каталог продуктовый их запихивать, или вести в ИС, которая мастер по договору клиента (если тарифы предполагают индивидуальность).

      Согласен, логично все комиссии собирать в единое место, там же вести тарифные планы и исключения из них. И у нас такая система есть. Вся сложность в Online 24x7. Довольно небольшой перечень систем по-настоящему могут работать в таком режиме и имеют адекватную поддержку. Наша комиссионная система так не умеет, и затраты на ее доработку в тот момент казались нерациональными. Возможно, в будущем мы это реализуем.


      1. vialz
        01.08.2017 16:50

        Спасибо за ваши комментарии.
        И на первый и на второй вопрос ответ, кмк: OGG + in memory data grid. SLA в 3-4 секунды вполне дозволительный зазор в данном случае. Но да, штука дорогая. Ввод и сопровождение нового in-house бэка в ландшафт в данный момент может казаться дешевле, но на горизонте 3-5 лет ответ останется тем же? :)


        1. aBozhiev
          01.08.2017 17:19

          Спасибо за интересную дискуссию.
          OGG — это Oracle Golden Gate? Довольно дорогая штука, надо признаться. И он тоже может по какой-то причине сломаться и не обновлять данные в кеше, при этом на системе-источнике данные вполне успешно будут писаться. Да и задержка в 3-4 секунды, на мой взгляд — недопустима, мошенники не дремлют.

          in memory data grid с заполнением данных на основе CDC (Change Data Capture, к которым в том числе относится и Golden Gate) — отличная штука для кеша в каналах интернет-банка (отображение балансов). Это решение не нагружает системы авторизационного контура, задержка даже в 20 секунд с обновлением там ОК, а в редких случаях падения CDC финансовых последствий не будет. Это был наш планБ на случай, если NI не потянет запрос баланса для интернет-банков в реальном времени. Но нагрузочные тесты и плавный запуск в промышленной среде показали, что с производительностью и нагрузкой проблем нет, так что этот план не понадобился.

          Описанное решение работает в промышленной среде на всех клиентов уже несколько лет, и проблем не доставляет. Благодаря простой и надежной архитектуре в нем крайне мало сбоев, и случаев ошибок с расчетом балансов я не припоминаю. Повторюсь, тонкое место в этом решении — производительность, но с ней пока все очень хорошо. Количество вызовов NI API постоянно растет (новые продукты, рост числа транзакций), деградации производительности не наблюдаем.