Pangalink
Банковская ссылка (pangalink) — способ обмена данных купли-продажи между клиентом, банком и магазином, очень распространённая в Эстонии. Эта услуга предоставляется банками в виде услуги магазинам, которым надо платить
- За подключение (SEB - 750 крон, Hanza - 1000 крон)
- 1% или 2-50 крон за сделку
- Месячная оплата (Hanza - 1000 крон)
Кроме возможности оплаты имеется возможность авторизации пользователей (что используется например на учебном sais.ee ). Зачем это надо? Потому что для клиента это очень удобно, судите сами - весь процесс оплаты счёта:
- Клиент выбирает нужные товары и получает в итоге счёт и ссылку на банк
- Внутри ссылки зашиты все данные об оплате и счетах, и подтверждены криптоустойчивой подписью (signature). Клиент оплачивает в банке полноценный информативный счёт.
- Банк редиректит клиента обратно на сайт опять со всеми данными об оплате вместе с подписью.
Отчасти поэтому в Эстонии уже есть и arved.ee и практически в каждом магазине иконки банков.
В общем для работы необходимы:
- уникальный id, выдаётся в банке после заключения договора
- сертификаты - публичный ключ банка и собственные публичные и приватные ключи
- собственно программа для обмена данными (об этом чуть ниже)
Что-бы подать заявление, необходимо сначала сгенерировать свой приватный ключ и CSR-запрос в банк. Сергей подробно об этом рассказывает
Html форма, iPizza
Что-бы передать данные в банк необходимо создать в обычном html-документе форму, куда в скрытых параметров прописать нужные данные. Названия параметров - описаны в спецификациях, но в общем почти все банки кроме Nordea следуют протоколу iPizza. Когда параметры готовы, то пользователю остаётся перейти по соответсвующему адрессу формы, который зависит от банка:
Банк | Gateway | VK_REC_ID получателя |
Hanza | https://www.hanza.net/cgi-bin/hanza/pangalink.jsp | HP |
SEB | https://www.seb.ee/cgi-bin/unet3.sh/un3min.r | EYP |
Sampo pank | https://www2.sampopank.ee/ibank/pizza/pizza | SAMPOPANK |
Krediidipank | https://i-pank.krediidipank.ee/teller/maksa | KREP |
Nordea | https://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
-
Sampo: высылает по договорённости доступ к своему серверу с виртуальным доменом *.optiva.ee, поэтому надо прописывать вручную IP в свой hosts файл.
-
Nordea: https://solo3.nordea.fi/cgi-bin/SOLOPM01
SOLOPMT_CUR=EUR
SOLOPMT_RCV_ID=12345678
MAC key=LEHTI -
Krediidipank имеет тестовый доступ по https://secure.krediidipank.ee/teller/maksa
Из личного опыта проблемы возникали из-за того что
-
Сервис на стороне банка не был активирован
-
Различия спецификации и реальной работы:
- длины параметра имени получателя (например Hanza должен его обрезать на 30 символах)
- Nordea - SOLOPMT_LANGUAGE обязателен на самом деле
-
Для тестирования живой системы нужен счёт
Сайты по теме:
-
хорошо с труктурированная библиотека на php от Романа