Перейти к основному содержимому

Pangalink

· 5 мин. чтения

Банковская ссылка (pangalink) — способ обмена данных купли-продажи между клиентом, банком и магазином, очень распространённая в Эстонии. Эта услуга предоставляется банками в виде услуги магазинам, которым надо платить

  • За подключение (SEB - 750 крон, Hanza - 1000 крон)
  • 1% или 2-50 крон за сделку
  • Месячная оплата (Hanza - 1000 крон)

Кроме возможности оплаты имеется возможность авторизации пользователей (что используется например на учебном sais.ee ). Зачем это надо? Потому что для клиента это очень удобно, судите сами - весь процесс оплаты счёта:

  1. Клиент выбирает нужные товары и получает в итоге счёт и ссылку на банк
  2. Внутри ссылки зашиты все данные об оплате и счетах, и подтверждены криптоустойчивой подписью (signature). Клиент оплачивает в банке полноценный информативный счёт.
  3. Банк редиректит клиента обратно на сайт опять со всеми данными об оплате вместе с подписью.

Отчасти поэтому в Эстонии уже есть и arved.ee и практически в каждом магазине иконки банков.

В общем для работы необходимы:

  • уникальный id, выдаётся в банке после заключения договора
  • сертификаты - публичный ключ банка и собственные публичные и приватные ключи
  • собственно программа для обмена данными (об этом чуть ниже)

Что-бы подать заявление, необходимо сначала сгенерировать свой приватный ключ и CSR-запрос в банк. Сергей подробно об этом рассказывает


Html форма, iPizza

Что-бы передать данные в банк необходимо создать в обычном html-документе форму, куда в скрытых параметров прописать нужные данные. Названия параметров - описаны в спецификациях, но в общем почти все банки кроме Nordea следуют протоколу iPizza. Когда параметры готовы, то пользователю остаётся перейти по соответсвующему адрессу формы, который зависит от банка:

БанкGatewayVK_REC_ID получателя
Hanzahttps://www.hanza.net/cgi-bin/hanza/pangalink.jspHP
SEBhttps://www.seb.ee/cgi-bin/unet3.sh/un3min.rEYP
Sampo pankhttps://www2.sampopank.ee/ibank/pizza/pizzaSAMPOPANK
Krediidipankhttps://i-pank.krediidipank.ee/teller/maksaKREP
Nordeahttps://netbank.nordea.com/pnbepay/epay.jsp

Защищённая передача

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

  • Банковский публичный ключ что-бы сгенерировать сообщение банку, обычно это файл с расширением .pem (но подходят и сертификаты .cer)
  • Личный ключ что-бы раcкодировать сообщение которое сгенерировал банк публичным ключём магазина
  • Имя банковского сервиса в качестве параметра (VK_SND_ID по iPizza)
  • Счёт на который деньги будут переводиться в качестве параметра (VK_ACC по iPizza)

Таким образом приватный ключ магазина выглядит примерно так (данных в base64 -кодировке больше просто)

-----BEGIN RSA PRIVATE KEY----- MIICWwIBAAKBgQC6GI5uaA7hEkgeP98VHL6TSxJwwPI+Mh+rFxKQPCgarT3/nZCS Gz1r223+gfH/adV4IDvlbYT18VQ4vSspX+QRAidFeZvsfv99FewnwNoTL3LwYp/K r9eW5YCpCEe8Crziks0vf92PNoHgNAL0iVo0Zma1ScDBSPBlQJoZ1UiwoQIDAP// -----END RSA PRIVATE KEY-----

И соответсвенно вместо PRIVATE, у публичного ключа другие данные и PUBLIC заголовок. Естественно что приватный ключ на то и приватный, и если он вдруг засветится, то любой желающий с достаточным умением сможет подписать фиктивную оплату товара, поэтому убедитесь, что ключи находятся в каталогах выше читаемого из сети www-каталога . Ключи можно сгенерировать при помощи OpenSSL. Банку в свою очередь для активирования услуги необходим публичный ключ магазина.

Создание подписи

После того как мы прописали hidden-поля параметров с названиями типа VK_RETURN (ссылка куда надо вернуться после оплаты), необходимо все эти данные подписать переменной VK_MAC, которая генерируется фукциями openssl_pkey_get_private и openssl_sign. 

После того как товар оплачен надо сделать подтверждение оплаты на своём сайте. Иначе получится такая уязвимость. Для этого мы из REQUEST переменной выдираем что нам выслал банк и подтверждаем подпись используя функции openssl_pkey_get_public и openssl_verify из той же VK_MAC. Ну а если подпись банка правильная и VK_SERVICE=1101, то всё в порядке.

Вот пример zone.ee - pay.php с формой оплаты, notify.php с подтверждением и config.php с настройками. Подобное можно сотворить и на c++ , но естественно с большими нервами.

Авторизация

Кроме экзотических способов оплаты есть и способ авторизации пользователя - магазину передаются имя, фамилия и личный код (isikukood) по Эстонии. Дальше всё сводится к аутидентификации с id-картой. Авторизация отличается лишь тем что нет нужды передавать данные об оплате, а вместо этого указать другой код сервиса (4002 для SEB) и VK_REC_ID (EYP для SEB). Кстати по слухам авторизация для клиентов - платная услуга, так что пользуйтесь ID-картой

Nordea e-payment

Банк Nordea решил отличиться — если Hanza, SEB и Sampo отличаются мелкими различиями в длине передаваемых параметров, то в Nordea не используется iPizza вовсе, а вместо этого своя система "e-payment" (префиксу кодов - SOLOPMT). А ведь в мире ещё есть и iTransact …

Главное отличие - отсутсвие RSA, т.е. шифрование симметричное и очень простое, хотя алгоритм очень схож с iPizza. Для создания подписи, MAC (message authentication code) надо просто сложить определённые в спецификации поля вместе (подобно GET запросу), полученную строку сложить с высланным из банка ключём (32 символа) и получить md5-hash. Конечно защита послабей чем у sha-алгоритма, зато реализация проще - на пальцах можно за день сделать.

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

function genMac($arrFields, $strMacKey){
$strMac='';
foreach ((array)$arrFields as $key=>$item){
$strMac.=str_replace('&','&',$item).'&';
}
$strMac.=$strMacKey.'&';
$strMac=strtoupper(md5($strMac));
return $strMac;
}

Подтверждение оплаты в результате такое же простое

$hash = $_REQUEST['SOLOPMT_RETURN_VERSION'].'&'
.$_REQUEST['SOLOPMT_RETURN_STAMP'].'&'
.$_REQUEST['SOLOPMT_RETURN_REF'].'&'
.$_REQUEST['SOLOPMT_RETURN_PAID'].'&'
.$MAC_KEY.'&'; //Mac key из конфигурации

$hash=strtoupper(md5(($hash)));

if($hash==$_REQUEST['SOLOPMT_RETURN_MAC']){} //success
else{} //failure

Отладка

Режим тестирования есть также практически у каждого банка, куда можно зайти при помощи тестового аккаунта, но только SEB сделал его открытым (см. приложенные файлы). Местные программеры даже создали эмулятор всех этих протоколов - pangalink.net

Из личного опыта проблемы возникали из-за того что

  1. Сервис на стороне банка не был активирован

  2. Различия спецификации и реальной работы:

    • длины параметра имени получателя (например Hanza должен его обрезать на 30 символах)
    • Nordea - SOLOPMT_LANGUAGE обязателен на самом деле
  3. Для тестирования живой системы нужен счёт

Сайты по теме: