---
title: Pangalink
date: 2007-04-25T10:00
tags: [ai, integration, php, tech]
---

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

<!-- truncate -->

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

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

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

Отчасти поэтому в Эстонии уже есть и [arved.ee](https://www.arved.ee/) и практически в каждом магазине иконки банков.

[![](https://www.arved.ee/public/gfx/banklink_seb.gif)](http://seb.ee/index/010227020201)[![](https://www.arved.ee/public/gfx/banklink_sampo.gif)](http://www.sampopank.ee/et/14730.html)[![](https://www.arved.ee/public/gfx/banklink_krediidi.gif)](http://www.krediidipank.ee/ari/arveldus/pangalink/index.html)[![](https://www.arved.ee/public/gfx/banklink_nordea.gif)](http://www.nordea.ee/Teenused+ettev%C3%B5ttele/E-lahendused/E-makse/787812.html)


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

- уникальный id, выдаётся в банке после заключения договора
- сертификаты - [публичный ключ](http://en.wikipedia.org/wiki/Public_key) банка и собственные публичные и приватные ключи
- собственно программа для обмена данными (об этом чуть ниже)

Что-бы подать заявление, необходимо сначала сгенерировать свой приватный ключ и CSR-запрос в банк. Сергей [подробно об этом рассказывает](http://setor.net/pangalink.html)

---

### 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](http://www.php.net/manual/en/function.base64-encode.php) -кодировке больше просто)

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

И соответсвенно вместо PRIVATE, у публичного ключа другие данные и PUBLIC заголовок. Естественно что приватный ключ на то и приватный, и если он вдруг засветится, то любой желающий с достаточным умением сможет подписать фиктивную оплату товара, поэтому убедитесь, что ключи находятся в каталогах выше читаемого из сети www-каталога . Ключи можно [сгенерировать](http://www.kaubandus.fantaasia.com/votmed.html) при помощи [OpenSSL](http://www.slproweb.com/products/Win32OpenSSL.html). Банку в свою очередь для активирования услуги необходим публичный ключ магазина.

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

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

После того как товар оплачен **надо сделать подтверждение** оплаты на своём сайте. Иначе получится [такая уязвимость](http://math.ut.ee/~arnis/bankauth/thesis.pdf). Для этого мы из REQUEST переменной выдираем что нам выслал банк и подтверждаем подпись используя функции _openssl_pkey_get_public_ и _openssl_verify_ из той же VK_MAC. Ну а если подпись банка правильная и VK_SERVICE=1101, то всё в порядке.

Вот пример [zone.ee](http://blog.zone.ee/2006/12/12/pangalink/) - [pay.php](https://data.zone.ee/phpsn/banklink/pay.php) с формой оплаты, [notify.php](https://data.zone.ee/phpsn/banklink/notify.php) с подтверждением и [config.php](https://data.zone.ee/phpsn/banklink/config.php) с настройками. Подобное можно сотворить и [на c++](http://www.php.ee/foorum/index.php?post=11187&j=2) , но естественно с большими нервами.

### Авторизация

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

### Nordea e-payment

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

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

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

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

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

```php
$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](https://www.pangalink.net/en/)

- SEB: https://www.seb.ee/cgi-bin/dv.sh/un3min.r
- 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

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

1. Сервис на стороне банка не был активирован
2. Различия спецификации и реальной работы:
    
    - длины параметра имени получателя (например Hanza должен его обрезать на 30 символах)
    - Nordea - SOLOPMT_LANGUAGE обязателен на самом деле
    
3. Для тестирования живой системы нужен счёт

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

- [среда для тестирования](https://www.pangalink.net/)   
    
- [хорошо структурированная библиотека](http://banklink.inoryy.com/#examples) на php от Романа
[img/61.pdf](img/61.pdf)
[img/60.pdf](img/60.pdf)

## Related

- [Авторизация в Google с OAuth 1.0](/ru/blog/tech/integration/avtorizatsiya-v-google-s-oauth-10/)
- [Интеграция оплаты paypal](/ru/blog/tech/integration/integratsiya-oplaty-paypal/)
- [Соединяем блог и Livejournal через XML-RPC](/ru/blog/tech/integration/soedinyaem-blog-i-livejournal-cherez-xml-rpc/)
