Пример разработки web-приложения

В данном разделе приведен пример разработки web-приложения для обслуживания держателей EMV-карт по протоколу ISO8583.

Общие положения

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

Говоря об обслуживании держателей EMV-совместимых банковских карт, можно выделить три составляющих системы обслуживания:

  1. Централизованная система авторизации операций;

  2. Пользовательский интерфейс;

  3. Информационная безопасность.

Централизованная система авторизации обрабатывает данные, собранные платежным терминалом для выполнения финансовой операции, либо уведомляет об отказе от ее проведения.

Пользовательский интерфейс служит для указания реквизитов платежа. Безопасность пользовательских данных обеспечивается соблюдением регламентов платежных систем, которые включают требования к шифрованию PIN-кода и использованию карточного приложения.

Для обеспечения возможности обслуживания чиповых банковских карт, совместимых со стандартом EMV, была создана библиотека MBK_AuthService, позволяющая реализовать терминальную логику, связанную с проведением операций по международным банковским картам. Ключевым классом библиотеки является MBKService. Он представляет собой COM-объект для доступа к карточному приложению и включает в себя всю бизнес-логику компонента. Можно представить компонент в виде совокупности двух взаимодействующих частей:

  1. Низкоуровневое EMV-ядро, обеспечивающее физическое и информационное взаимодействие между банковской картой и платежным терминалом. Низкоуровневая реализация ядра позволяет минимизировать затраты при необходимости миграции кода на другую аппаратную платформу (например, при необходимости поддержки ARM-процессоров), или операционную систему (например, при миграции на Linux).

  2. Интеграционная составляющая EMV-ядра – компонент, удобный для использования прикладными программистами. Реализует следующие функции:

    • Подготовка EMV-ядра к работе, в частности, настройка для работы с различными типами карточных приложений. Так, например, можно управлять условиями эксплуатации: какие типы банковских карт ядро будет обслуживать (VISA, MasterCard и т.д.).

    • Упрощение доступа к низкоуровневому EMV-ядру с целью снижения сложности задачи встраивания ядра в прикладное ПО. Как отмечалось выше, низкоуровневое EMV-ядро написано в парадигме структурного программирования, обеспечивающего простоту процесса миграции кода на другие платформы. Замена парадигмы структурного программирования в пользу объектно-ориентированного позволяет значительно снизить риски возникновения ошибок при создании платежных приложений.

    • Унификация способа доступа к функциям EMV-ядра из прикладного ПО, работающего в среде Microsoft Windows. Низкоуровневый код EMV-ядра написан на языке Си, но для прикладных программистов предлагается использовать COM-интерфейс, что позволяет встраивать ядро как в web-приложение функционирующие в среде Microsoft Internet Explorer, так и, например, в Embarcadero C++ Builder, или в приложения, разработанные на Python.

Дополнительно с помощью библиотеки MBK_AuthService можно унифицировать работу с чиповыми картами и с картами, работающими по магнитной полосе.

В случае обслуживания карт с магнитной полосой типовой сценарий выглядит следующим образом:

  1. Клиент вставляет карту в считыватель карт.

  2. Производится считывание данных со второй дорожки магнитной полосы. Посредством FIT-таблиц данные проверяются на принадлежность известным финансовым системам. Если карта не является банковской, или не может быть обслужена подключенными платежными системами, она возвращается пользователю.

  3. Предлагается ввести PIN-код карты.

  4. Плательщик выбирает банковскую операцию и указывает значения реквизитов (если это требуется).

  5. Номер карты, зашифрованный PIN-код, сумма и реквизиты финансовой операции отправляются в банковский процессинг (чаще всего для этого используется финансовый протокол ISO8583 или управляющий – NDC).

  6. Если процессинг авторизует (разрешает) операцию, соответствующий ответ будет отправлен устройству самообслуживания. Если операция требует перечисления денежных средств, соответствующая сумма «замораживается» (hold) на счете клиента.

  7. Информация о результатах платежа передается плательщику – она может быть выведена на экран, и/или распечатана на клиентском чеке.

В случае использования EMV-совместимой карты типовой сценарий расширяется за счет взаимодействия с приложением платежной системы, размещенной на банковской карте. Участие карточного приложения заключается в формировании криптограммы – зашифрованного набора реквизитов платежа, к которым относятся сумма (включая код валюты и экспоненту), наличие PIN-кода в запросе, номер терминала, код операции, и т.д. В ответ на запрос хост присылает криптограмму эмитента для проверки карточным приложением. В ряде случаев (в частности, всегда при смене PIN-кода) хост эмитента может отправить набор исполняемых скриптов, которые изменяют состояние приложения (изменение PIN-кода, хранимого на карте, блокировка, разблокировка, изменение данных карты и пр.)

Таким образом, при помощи библиотеки MBK_AuthService разработчики могут создавать приложения для взаимодействия с любыми типами карт, используя один и тот же доступный инструментарий. Общая схема этапов обслуживания карт по магнитной полосе и с использованием приложения на банковской карте приведена на рис. 92. На рисунке указано, на каких этапах сценария обслуживания может быть использован MBKService.

Web-расширение window.external.iso8583

Один из наиболее удобных способов расширения возможностей web-приложения состоит в использовании дополнительных функций, реализуемых приложением, контролирующим web-browser.

../../_images/web+protatm_general_scheme.png

Рисунок 74. Общая схема взаимодействия

В соответствии с данной схемой web-приложение, исполняя javascript-код, обращается, например, к функции с составным именем window.external.iso8583.Withdrawal(). Браузер, обрабатывая этот вызов, осуществляет поиск зарегистрированных расширений посредством интерфейса IDocHostUIHandler и если находит расширение, готовое отработать запрос к подсистеме iso8583, вызывает метод расширения Withdrawal(), передавая ему в качестве параметра объект request.

ПроАТМ содержит расширение «iso8583», в задачу которого входит формирование финансовых и служебных запросов к фронтальной системе банковского процессинга (часто такую систему называют «хостом») по протоколу ISO8583. В ПроАТМ реализована комплексная система взаимодействия с хостом, включающая управление сервисными операциями, такими как проверка работоспособности хоста, сверка итогов (балансировка), и т.д. Также в ПроАТМ реализована мощная система трассировки событий времени исполнения, база данных сформированных запросов и специальный режим оператора, позволяющий настраивать параметры работы системы по протоколу ISO8583, а также управлять крипто-инфраструктурой.

К счастью, почти все сложные алгоритмы реализованы непосредственно в ПроАТМ, что позволяет разработчикам web-приложений сфокусироваться на бизнес-функциях, описывая сценарий обслуживания в терминах реквизитов платежей.

В общем случае, web-программист разрабатывает сценарий обслуживания держателя банковской карты и, когда все реквизиты собраны, использует mbkService для формирования криптограммы (см. «Технические спецификации. МБК сервис»), а затем вызывает одну из функций расширения «iso8583» с целью авторизовать операцию.

Следует заметить, что взаимодействие с хостом является асинхронным, т.е. после того, как запрос на авторизацию операции сформирован, web-приложение может продолжить свою работу, например, отображая на экране анимацию тикающих часов, с сообщением «Пожалуйста, подождите…». Как только будет получен ответ хоста, web-расширение вызовет одну из определенных на web-странице javascript-функций, которая должна будет отработать ответ хоста. В типовом случае, с каждой операцией связано три функции обработки результата (callback): «успешная операция» (On[функция]Completed), «хост отказал в выполнении операции» (On[функция]Declined) и «в процессе взаимодействия с хостом возникла ошибка» (On[функция]AttemptFailure).

Например, если разработчик web-приложения вызвал функцию Withdrawal(), то по ее завершении расширение «iso8583» вызовет одну из трех callback-функций OnWithdrawalCompleted(), OnWithdrawalDeclined() или OnWithdrawalAttemptFailure(). В качестве параметров функций OnWithdrawalCompleted() и OnWithdrawalDeclined() будут переданы ассоциативные списки, содержащие результат операции. Типичный результат операции содержит дату и время операции (поля «AuthDateTime» и «AuthDateTimeUnix»), код ответ хоста (поле «ResponseCode»), код авторизации операции (поле «AuthCode»), номер транзакции «TrxNumber» и данные, которые необходимо передать карточному приложению, исполняющемуся на чипе банковской карты (поле «ChipData»). Конкретный состав полей ассоциативного списка с результатом операции зависит от типа операции.

Внимание

Для изучения особенностей работы расширения «iso8583» настоятельно рекомендуется ознакомиться с web-приложением «webDemoIso8583.html», являющимся одностраничным web-приложением и позволяющим выполнить большинство операций расширения.

Целью разработки демонстрационного приложения является ускорение процесса обучения web-программиста способам обслуживания держателей банковских карт по протоколу ISO8583, с использованием платформы ПроАТМ. В этом приложении реализованы алгоритмы выполнения типовых операций с банковскими картами, в частности, запроса баланса и оплаты услуг (безналичное списание). В процессе работы web-приложение использует как компонент mbkService, так и расширение iso8583, взаимодействие с которым осуществляется через механизм window.external.

Пользовательский интерфейс приложения разделен на четыре части: управляющую консоль (CONTROL PANEL), текущее время (используется для демонстрации отсутствия блокировок web-приложения во время обращений к хосту), окно состояния авторизатора (в том числе – состояние соединения с хостом), а также журнал времени исполнения (LOG).

Внимание

Web-приложение «webDemoIso8583.html» запускается при старте ПроАТМ. Обязательным условием работы приложения является наличие физических сервисов узлов устройства самообслуживания, совместимых с CEN/XFS 3.X. Таким образом, web-приложение работоспособно на УС (банкомат, платежный терминал) или на эмуляторе.

../../_images/start_application_example.png

Рисунок 75. Начало работы приложения

В соответствии с рекомендациями, отражаемыми на синем фоне, следует вставить банковскую карту.

Примечание

Для того чтобы отлаживать web-приложения, связанные с обслуживанием EMV-карт на эмуляторе XFS, в системе должен быть установлен PC/SC-считыватель. XFS/Эмулятор автоматически обнаружит картридер и попытается адресовать запросы, поступающие к чипу, на карту, вставленную в считыватель. Кроме того, существует возможность удаленного подключения к PC/SC-ридеру по каналам TCP/IP (более подробно – см. руководство пользователя на продукт XFS/Эмулятор).

Исследуя демонстрационное web-приложение, следует в первую очередь обращать внимание на содержимое окна с трассировкой времени исполнения. Такой подход позволит увидеть происходящие в системе события и оценить, каким образом они должны быть отражены в логике разрабатываемого приложения.

В дополнение к логам демонстрационного web-приложения, крайне полезным может оказаться использование сервиса «RedLabel», являющегося составной частью платформы ПроАТМ. Сервис «RedLabel» сохраняет информацию о множестве решений, принятых разными подсистемами, включая COM/ActiveX-компоненты, сервисы ПроАТМ, физические сервисы уровня XFS, а также Xfs/эмулятор.

../../_images/selecting_an_operation_example.png

Рисунок 76. Пример экрана выбора операции

API расширения «iso8583»

Внимание

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

Запрос состояния (синхронный вызов)

Функция GetStatus() позволяет получить информацию о текущем состоянии расширения «iso8583». Эта функция является синхронной и сразу же возвращает целочисленное значение, характеризующее текущее состояние. Пример использования (текстовое описание соответствует целочисленным кодам в порядке возрастания: 0, 1, 2, ..):

 var description = [
     "Авторизатор готов к проведению клиентских операций",// 0
     "Нет лицензии на использование",
     "Не активен",
     "Потеряна связь",
     "Ошибка хранилища транзакций",
     "Ошибка криптомодуля",// 5
     "Сессионные ключи не загружены",
     "Неверная или недостаточная конфигурация сервиса",
     "Ошибка настройки связи",
     "Фоновая отмена операции",
     "Фоновый докат смены PINа",// 10
     "Фоновая сверка итогов"
     "Поломка счетчика транзакций"
     "Активна фоновая клиентская операция"
];

var status = window.external.iso8583.GetStatus();
return description[status];

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

Взаимное использование сервисов window.external.iso8583 и mbkService

Для работы подсистемы window.external.iso8583 задействование сервиса mbkService является необходимым условием. Даже в том случае, если предполагается обслуживание только магнитных карт, mbkService следует рассматривать как подчиненную службу, отвечающую за:

  1. Работа с картами EMV (в частности, определение типа карты).

  2. Ведение счетчика транзакций.

  3. Хранение даты/времени транзакции.

Для корректной работы связки window.external.iso8583 и mbkService необходимо настроить конфигурацию mbkService таким образом, чтобы счетчик транзакций генерировался внутри mbkService:

termCfg.TranSeqCounterManagement = EMM_INTERNALLY_MANAGED

После отработки mbkService::Completion() необходимо в обязательном порядке передать контроллеру ISO8583 сведения о финальных EMV-данных (см. описание метода window.external.iso8583.ConveyEmvCompletionData).

Безналичное списание (асинхронный вызов)

Запрос на безналичное списание формируется посредством вызова функции Withdrawal(). Соответствующий javascript-код может выглядеть следующим образом:

var request = {Currency: 643, ProcessingCode: 400000};
request.Track2 = '676280389083828110=10121010070100000';
request.PinBlock = '01 02 03 04 05 06 07 08';
request.Amount = 15000;

if( CT_EMV == mbkService.GetCardType() ) {

    var onlineChipData = new ActiveXObject( 'MBK_AuthService.BerTlvCon     tainer' );
    mbkService.ConstructOnlineChipData( onlineChipData );
    request.ChipData = onlineChipData.FormatAsciiHex( true );
}

result = window.external.iso8583.Withdrawal( request );

Разработчик javascript-кода осуществляет подготовку параметров запроса, к которым относятся:

  • Currency – цифровой код валюты ISO4217 (643 – российские рубли)

  • ProcessingCode – код операции «безналичное списание» в процессинге

  • Track2 – значение, считанное со второй полосы магнитной карты, либо его эквивалент, полученный от чипа

  • PinBlock – зашифрованный PIN-код

  • Amount – сумма операции в minor currency units (в случае российского рубля – сумма в копейках)

  • ChipData – набор EMV данных, в числе которых криптограмма транзакции

  • TrxNumber – номер транзакции. Опциональный параметр. Если не указан – берется из контекста МБК Сервиса.

    Внимание

    Если явно назначается, то должен быть идентичен значению тэга Transaction Sequence Counter в контексте EMV.

Как легко заметить из примера, данные передаются посредством ассоциативного массива (associative array), что позволяет передавать параметры в произвольном порядке, а также пропускать те параметры, для которых определены и устраивают значения по умолчанию.

Внимание

Состав полей запросов варьируется в пределах различных диалектов ISO8583. За дополнительной информацией следует обращаться к разделу приложений настоящего документа, в котором уточняется специфика работа с конкретным диалектом ISO8583.

Для упрощения написания скриптов web-приложения, ПроАТМ автоматизирует формирование целого ряда полей запроса:

  • часть полей являются статическими (например, Function Code), и их значения уже прописаны в определении диалекта;

  • другая часть полей относится к идентификационным параметрам терминала (TerminalID, Merchant No, Acquirer ID и т.п.) – подставляется из конфигурации терминала;

  • POS Entry Mode – формируется на основе типа карты в контексте mbkService;

  • Дата/время и номер транзакции – берутся из контекста mbkService.

Использование функции Withdrawal() может привести к последующему обратному вызову одной из трех callback-функций, объявленных в скрипте web-приложения: OnWithdrawalCompleted(), OnWithdrawalDeclined() или OnWithdrawalAttemptFailure(). Сама по себе функция Withdrawal() возвращает true, если задача успешно поставлена на исполнение, либо false, если этого сделать не удалось. Среди причин может быть неготовность авторизатора (см. GetStatus) либо наличие фонового исполнения предыдущего запроса.

В случае если операция разрешена хостом, будет вызвана функция OnWithdrawalCompleted(). Если обслуживается EMV карта, то необходимо осуществить вызов функции mbkService::Complete(): финальное решение о том, является ли операция успешной или нет, принимает карточное приложение. Представляется вполне вероятной ситуация, в которой хост одобрил операцию, но карта посчитала сформированную хостом криптограмму некорректной. В этом случае, необходимо отменить операцию, незамедлительно вызвав функцию LastOperationReversal().

В случае если хост отверг запрос на выполнение операции, расширение вызовет функцию OnWithdrawalDeclined(). Наиболее важным полем ответа будет являться «ResponseCode», поясняющим, по какой именно причине операция была отклонена.

В случае если при обмене с хостом возникли неустранимые технические проблемы, расширение «iso8583» вызовет callback-функцию OnWithdrawalAttemptFailure(), единственным параметром которой будет уведомление о том, была ли автоматически запущена операция отмены запроса, или нет.

Внимание

Независимо от исхода операции (одобрена, отклонена, ошибка связи), при обслуживании карт EMV необходимо всегда вызывать функцию mbkService::Complete(). Это позволит формально завершить транзакцию EMV (важно для соответствия стандарту EMV).

Отмена последней операции (асинхронный вызов)

Вызов функции LastOperationReversal() позволяет инициировать процесс фоновой отмены последней операции. Этот вызов является асинхронным и не содержит параметров. Всю необходимую работу по доставке сообщения выполнит ПроАТМ. Выполнив вызов LastOperationReversal(), web-приложение может начать свою работу «с чистого листа». Пример вызова:

result = window.external.iso8583.LastOperationReversal();

Возвращаемое значение может принимать значение TRUE – команда отмены последней финансовой операции поставлена в очередь исполнения и будет выполнена; значение FALSE – по каким-то причинам, отмена операции не представляется возможной.

После успешной отмены или нескольких попыток безуспешной отмены будет вызван callback-обработчик вида OnReversalDetails( strDetails ). Если из-за ошибки связи не удается отменить операцию, ПроАТМ продолжит фоновые попытки отмены операции, до тех по, пока не получит подтверждение от хоста. Начиная с этого момента GetStatus будет возвращать код ошибки 9 («Фоновая отмена операции»). В случае если при исполнении LastOperationReversal возникнет исключение, будет вызван callback-обработчик вида OnReversalAttemptFailure().

Зачисление средств на карточный счет (асинхронный вызов)

Операция зачисления на карточный счет крайне похожа на безналичное списание с одной лишь разницей – денежные не списываются, а зачисляются на счет. Название функции - CashDeposit(), а callback-функции называются соответственно: OnCashDepositCompleted(), OnCashDepositDeclined() или OnCashDepositAttemptFailure().

var request = {ProcessingCode: 430000}
...
result = window.external.iso8583.CashDeposit( request )

Запроса баланса карточного счета (асинхронный вызов)

Запрос баланса по карточному счету осуществляется посредством вызова функции BalanceInquiry(). Соответствующий javascript-код может выглядеть следующим образом:

var request = {ProcessingCode: 310000};
request.Track2 = '676280389083828110=10121010070100000';
request.PinBlock = '01 02 03 04 05 06 07 08';

    if( CT_EMV == mbkService.GetCardType() ) {

        var onlineChipData = new ActiveXObject( 'MBK_AuthService.BerTlvContainer' );
        mbkService.ConstructOnlineChipData( onlineChipData );
        request.ChipData = onlineChipData.FormatAsciiHex( true );
    }

    result = window.external.iso8583.BalanceInquiry( request )

Результат вызова BalanceInquiry() будет передан в web-приложение посредством одной из трех callback-функций: OnBalanceInquiryCompleted(), OnBalanceInquiryDeclined() или OnBalanceInquiryAttemptFailure(). В случае положительного ответа, в ответном пакете содержится информация о балансе в представлении, специфичном для конкретного диалекта (см. соответствующее приложение к документу).

Смена PIN-кода (асинхронные вызовы)

По сравнению с другими операциями, смена PIN-кода является двух-фазовой. В рамках первой фазы хосту передается как старый PIN-код, так и новый (оба – в виде зашифрованных PIN-блоков). Получив и успешно проверив PIN-код, хост эмитента формирует ответные данные, которые содержат специальные скрипты (issuer scripts) - набор инструкций, приводящих к смене оффлайн PIN-кода на карте. После того как карта отработает эти инструкции, результат выполнения следует передать хосту. В случае успешной доставки этих результатов, хост помечает транзакцию как исполненную и фиксирует новый PIN-код банковской карты в своей базе данных. Первая фаза смены PIN-кода выглядит следующим образом:

var request = {ProcessingCode: 700000}
request.Track2 = '676280389083828110=10121010070100000';
request.PinBlock = '01 02 03 04 05 06 07 08';
request.NewPinBlock = '08 07 06 05 04 03 02 01';
...
var onlineChipData = new ActiveXObject( 'MBK_AuthService.BerTlvContainer' );
mbkService.ConstructOnlineChipData( onlineChipData );
request.ChipData = onlineChipData.FormatAsciiHex( true );

result = window.external.iso8583.ChangePin1( request )

В результате обработки ответа хоста на первую фазу операции по смене PIN-кода, может быть вызвана одна из callback-функций: OnChangePin1Completed(), OnChangePin1Declined() или OnChangePin1AttemptFailure(). Обработка альтернативных потоков первой фазы ничем не отличается от логики финансовых запросов: обязательный вызов mbkService.Complete(), передача финальных EMV-данных в контроллер ISO8583.

Если первая фаза успешно завершена, переходим ко второй фазе: отправка подтверждения на хост. Для EMV-карт включаются финальные EMV-данные и результат исполнения скриптов эмитента.

var request = { ProcessingCode: 700001 };
request.Track2 = '676280389083828110=10121010070100000';

if( CT_EMV == mbkService.GetCardType() ) {

         // Результат выполнения скриптов эмитента
         request.IssuerScriptResults = mbkService.IssuerScriptResults.GetRawResult(true);

        // Заново запрашиваем Финальные EMV-данные для включения в запрос
        var onlineChipData = new ActiveXObject( 'MBK_AuthService.BerTlvContainer' );
        mbkService.ConstructOnlineChipData( onlineChipData );
        request.ChipData = onlineChipData.FormatAsciiHex( true );

result = window.external.iso8583.ChangePin2( request )

Соответственно, после обработки ответа хоста будет вызвана одна из callback-функций: OnChangePin2Completed(), OnChangePin2Declined() или OnChangePin2AttemptFailure(). Поскольку к этому моменту операция смены PIN-кода уже завершилась, то следует лишь обработать ее результат:

function OnChangePin2Completed( results )
{
    if( results.ResponseCode == '00' ) {

        // Успешная смена PIN-кода

    } else {

       // Хост отклонил операцию смены PIN-кода
    }
 }

Передача финальных EMV-данных в контроллер ISO8583 (синхронный вызов)

После отработки mbkService::Completion() необходимо передать контроллеру ISO8583 сведения о финальных EMV-данных (содержат вторую криптограмму, статусную информацию на момент окончания транзакции, результат исполнения скриптов эмитента и пр.). Данная информация размещается в хранилище транзакций и впоследствии может быть использована при выгрузке пакета (операция балансировки), отмене операции, формировании ADVICE-сообщений и пр. Пример того, как это можно сделать:

var onlineChipData = new ActiveXObject( 'MBK_AuthService.BerTlvContainer' );
mbkService.ConstructOnlineChipData( onlineChipData );
var finalEmvData = {};
finalEmvData.ChipData = onlineChipData.FormatAsciiHex( true );
finalEmvData.IssuerScriptResults = mbkService.IssuerScriptResults.GetRawResult( true );
window.external.iso8583.ConveyEmvCompletionData( finalEmvData );

Проверка карты хостом (асинхронный вызов)

Иногда, перед тем как начать ввод реквизитов для осуществления банковской операции, бывает полезным убедится, что у этой операции есть шанс завершится успешно. Одним из тестов потенциальной успешности является проверка номера карты хостом. Примером такой операции в рамках диалекта SmartVista POS TF является функция CheckCardSvPosTf():

var request = {ProcessingCode: 370000}
request.Track2 = '676280389083828110=10121010070100000';
request.PinBlock = '01 02 03 04 05 06 07 08';
...
result = window.external.iso8583.CheckCardSvPosTf( request )

Как и в результате вызова других операций, после обработку ответа хоста, расширение iso8583 осуществит вызов одной из трех callback-функций: OnCheckCardSvPosTfCompleted(), OnCheckCardSvPosTfDeclined() и OnCheckCardSvPosTfAttemptFailure().

Особенности разработки web-приложения на платформе ПроАТМ

Особенностями платформы ПроАТМ, предлагаемой в качестве основы для создания эффективных и надежных систем банковского самообслуживания являются:

  1. Организация пользовательского интерфейса на базе web-технологий (система рендеринга браузера Microsoft Internet Explorer).

  2. Управление узлами устройства самообслуживания посредством COM-объектов, входящих в состав ПроАТМ.

  3. Доступ к карточному приложению – посредством COM-объекта mbkService.

  4. Подготовка данных для авторизации операций в процессинге IS

  5. O8583 – через web-расширение window.external.iso8583.

Перед разработкой web-приложения разработчику web-приложения важно понимать, каким образом javascript-код, исполняемый браузером во время отображения HTML-документа, взаимодействует с COM-объектами, а также то, каким образом этот код может вызывать расширения через механизм «window.external» интернет-браузера.

Номер транзакции и дата/время терминала

Изучая код демонстрационного приложении (webDemoIso8583.html) можно заметить, что в API параметр «номер транзакции» (TrxNumber), являющейся ключевым в запросах хосту по протоколу ISO8583, фигурирует только как результат выполнения операции. Дело в том, что за выбор (генерацию) номера транзакции отвечает компонент mbkService, который ведет сквозную нумерацию в энергонезависимой памяти терминала. В случае если web-приложение должно сохранять информацию о номере транзакции принятой window.external.iso8583 к исполнению, следует запрашивать его через функцию TransactionSeqNo() компонента mbkService.То же самое можно сказать и про дату/время терминала – этими параметрами, если они требуются в конкретном диалекте протокола ISO8583, управляет mbkService.

EMV-карта

Решение о том, что карта содержащая чип является EMV-совместимой можно принимать только на основании списка «уникальных номеров карточных приложений» (AID). При разработке кода web-приложения следует держать в голове, что после получения ARPC от хоста, карта анализирует его и может дать Decline даже в случае успешного ResponseCode. В случае если карточное приложение ответило «Terminate», или «Decline», web-приложение должно запустить процесс отмены операции на хосте. В случае если карточное приложение ответило «Approve», web-приложение должно послать команду подтверждения на хост (Confirmation), либо передать его хосту в процессе сверки итогов (балансировки).

Ошибка проверки PIN-кода

Если в ответ на запрос хост сигнализирует о неверном PIN-коде, стандартная практика – дать возможность повторно ввести PIN-код и попытаться авторизоваться еще раз (особенно важно, если клиент внес деньги в устройство приема наличных, которое не обладает способнотью их вернуть назад). Не смотря на то, что функциональные реквизиты операции никак не меняются (тип, сумма, валюта, и пр.), необходимо по всем правилам стартовать новую транзакцию EMV и ISO8583 средствами mbkService.BeginAnotherTransaction.

Смена PIN-кода

При смене PIN-кода рекомендуется просить картхолдера ввести новый PIN-код два раза, а затем сравнивать значения полученных PIN-блоков. Применение формата PIN-блока ISO FORMAT-0 гарантирует идентичность PIN-блоков, если они собраны на одном и том же значении PIN-кода. Также рекомендуется игнорировать запрос на смену PIN-кода в том случае, если новый PIN-код идентичен текущему.

Выполнение сервисных операций

а выполнение сервисных операций, таких как балансировка, загрузка сессионных ключей, проверка соединения с хостом отвечает ПроАТМ, и web-приложение не должно содержать какого-либо программного кода, связанного с запуском, или выполнением этих операций. Узнать о том, что выполняется какая-либо сервисная операция, можно используя синхронную функцию window.external.iso8583.GetStatus(). Настройка параметров выполнения сервисных операций, а также мастер-ключей, осуществляется в РОП или посредством настройки параметров в реестре ОС.

RRN

К числу параметров, потребность в котором имеется только у некоторых диалектов протокола ISO8583 можно отнести «RRN». Этот параметр является акронимом от «Retrieval Reference Number» и является уникальным номером операции в системе авторизации и расчетов обслуживающего банка. Обычно, хост присылает «RRN» в ответе на выполнение финансовой операции и этот параметр следует распечатать на клиентском чеке с целью предоставления возможности держателю банковской карты запустить процесс апелляции (претензии) в отношении действий банка. В некоторых диалектах протокола, «RRN» должен быть указан среди параметров запроса, например, при отмене операции. Можно говорить о том, что «RRN» является частью составного ключа при поиске транзакции в базе данных на стороне хоста.

Применение стилей к Active-X компонентам ПроАТМ

Нельзя применять стиль «display:none» к ActiveX-компонентам ПроАТМ.

При создании ActiveX-компонента, браузер использует т.н. комбинированный орган управления, в котором очередью оконных сообщений владеет DOM-элемент браузера (описывается в HTML), а дополнительная логика и функционал взаимодействия с аппаратными узлами реализован в COM-объекте.

Логика работы с аппаратным обеспечением работает в отдельном потоке, а код, связанный с DOM-моделью и javascript-ов, работает в основном потоке браузера. В результате возникает необходимость синхронизации работы нескольких потоков. Сделать это проще всего, используя очередь оконных сообщений, которой владеет DOM-элемент.

Из потока, работающего с аппаратным обеспечением, отправляется асинхронное сообщение «окну» DOM-элемента, используя функцию PostMessage(). Это сообщение помещается в очередь, и браузер по готовности извлечет это сообщение (в своем потоке исполнения) и выполнит связанные с ним функции. Например, сообщение о считывании штрих-кода будет передано в соответствующий обработчик, написанный на языке javascript и определенный непосредственно в HTML-документе загруженном в ПроАТМ, в режиме Web-расширения NDC.

Можно утверждать, что вызов PostMessage() и использование очереди сообщения DOM-элемента решают задачу синхронизации работы потоков исполнения.

Достаточно не очевидным является тот факт, что использование стиля «display:none» приводит к тому, что окно DOM-элемента с соответствующей очередью сообщения не создается/удаляется. Как результат, выполнить PostMessage() не удастся, сообщение о получении данных от аппаратного узла не будет получено и соответствующий javascript-обработчик не будет вызван.

Особенности работы с диалектом SmartVista POS TF

Ответ на любой запрос, если не оговаривается отдельно, содержит общие поля: ResponseCode, AuthCode, RRN, AuthDateTime, AuthDateTimeUnix, TrxNumber. При обслуживании карт EMV в запрос и ответ включаются поля ChipData, содержащие данные кодировка BER-TLV согласно требованиямм стандарта EMV. При отправке запроса должны быть сформированы ниже следующие тэги: 4F, 5F2A, 5F34, 82, 84, 95, 9A, 9B, 9C, 9F02, 9F09, 9F10, 9F1A, 9F1E, 9F26, 9F27, 9F33, 9F34, 9F35, 9F36, 9F37, 9F41, 9F53.

Получение баланса карты

Обязательные поля запроса: Track2, PinBlock, ProcessingCode.

Необязателньые поля запроса: Currency.

При формировании запроса существует возможность адресации конкретного счета по его типу или валюте:

  1. Поле ProcessingCode в запросе имеет формат 31n000, где n принимает следующие значения:

    • 0 – Default-unspecified;

    • 1 – Savings account;

    • 2 – Checking account;

    • 3 – Credit account.

  2. Поле Currency служит для адресации счета по валюте.

Ответ содержит значения баланса адресованного счета в полях Balance.Amount и Balance.Currency. Сумма представлена в минорных единицах валюты.

Проверка карты

Служит для получения идентификационных данных клиента из банковской системы.

Обязательные поля запроса: Track2, PinBlock. В ответе содержится PrivateDataRaw – составное поле, в котором кодируется информация о клиенте и номере контракта в представлении TLV. Пример:

001 020 12345678901234567890 002 006 123456

Тег 001 – содержит ID клиента. Тег 002 – содержит ID контракта.

Взнос наличных

Обязательные поля запроса: Track2, PinBlock, Amount, Currency, ProcessingCode.

При формировании запроса существует возможность адресации конкретного счета по его типу с помощью поля ProcessingCode: 21n000, где n принимает следующие значения:

  • 0 – Default-unspecified;

  • 1 – Savings account;

  • 2 – Checking account;

  • 3 – Credit account.

Безналичное списание (покупка)

Обязательные поля запроса: Track2, PinBlock, Amount, Currency, ProcessingCode.

При формировании запроса существует возможность адресации конкретного счета по его типу с помощью поля ProcessingCode: 00n000, где n принимает следующие значения:

  • 0 – Default-unspecified;

  • 1 – Savings account;

  • 2 – Checking account;

  • 3 – Credit account.

Смена PIN-кода

Обязательные поля запроса при выполнении первой фазы: Track2, PinBlock, NewPinBlock.

Обязательные поля запроса при выполнении второй фазы: Track2.

На момент написания настоящего документа нет полной ясности того, каким образом хост в рамках проведения второй фазы проверяет успешность смены оффлайн PINа на карте.

Можно предложить дополнить логику терминала промежуточным анализом результата IssuerScriptResults. Если хотя бы один скрипт выполнен неуспешно, можно предположить, что смены PIN-кода не произошло и вместо подтверждения отправить на хост отмену. Данная схема идет вразрез со стандартом EMV, однако может оказаться более предпочтительной.

Поступили разъяснения БПЦ по части порядка проведения транзакции смена PINа. Перед выполнение подтверждения, терминал обязывают прогнать транзакцию EMV еще раз. Вот отсюда и станет известно значение 9F10, в котором закодирован результат смены PINа.