---
title: "Пангалинк сегодня (2026): архитектура iPizza и облачные альтернативы"
date: 2026-08-21T12:00:00
tags: [integration, payments, estonia, security, api, tech]
description: "Как на самом деле устроены эстонские банковские ссылки: браузер как транспорт, подпись VK_MAC, версии 008 и 009, сервисы 1011/1012/1111/1911. Почему сертификаты до сих пор выдаются вручную, чем от этого отличаются Montonio, LHV, Maksekeskus и EveryPay, и какие библиотеки живы в PHP, Ruby, Node.js и Go."
---

![Пангалинк сегодня (2026): курьер несёт запечатанную коробку iPizza между магазином и банком](img/pangalink-segodnya-preview.jpg)

Восемнадцать лет назад я [написал про пангалинк](/ru/blog/tech/integration/pangalink/) статью, в которой фигурировали эстонские кроны, банки Hanza и Sampo, и подключение за 750 крон. Тот текст сейчас читается как археология: половины банков нет, валюты нет, тестовый сервис закрылся, а рядом выросла целая индустрия, которая делает то же самое, но по-другому.

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

<!--truncate-->

## Проблема, которую решает пангалинк

Начну с базовой вещи, потому что она неочевидна, если вы не жили в этой области.

Когда вы платите картой, деньги идут по карточной сети: магазин -> эквайер -> Visa/Mastercard -> банк-эмитент. Это дорого (1-3% с транзакции), медленно в расчётах (деньги идут дни) и обратимо: клиент может через месяц сделать chargeback, и магазин останется без товара и без денег.

**Банковская ссылка (эст. pangalink) идёт другим путём.** Это не карта. Это обычный банковский перевод со счёта на счёт, только заполненный за клиента и подтверждённый им в его же интернет-банке. Магазин получает настоящий SEPA-перевод. Отсюда свойства:

- дёшево (сейчас это единицы центов за транзакцию, не проценты)
- деньги приходят сразу, если банк в системе мгновенных платежей
- **необратимо**: chargeback как понятия не существует, перевод есть перевод

Последний пункт объясняет, почему в Эстонии, Латвии, Литве, Финляндии и Польше локальные банковские ссылки победили карты в интернет-магазинах, а в США и Британии их практически нет. Там карточная инфраструктура пришла раньше и заняла место.

## Архитектура: браузер как транспорт

Вот главная идея, которую надо понять про iPizza. Она странная, и это осознанная странность 2000-х годов.

**Магазин никогда не разговаривает с банком напрямую.** Нет никакого API-вызова, нет исходящего HTTP-запроса из вашего сервера в банк, нет ключей API и токенов. Вместо этого:

1. Магазин рисует на странице обычную HTML-форму со скрытыми полями
2. Поля подписаны приватным RSA-ключом магазина
3. `action` формы указывает на URL банка
4. Клиент нажимает кнопку, **его браузер** отправляет форму в банк
5. Банк проверяет подпись, показывает клиенту предзаполненный платёж
6. Клиент подтверждает
7. Банк отправляет **браузер клиента** обратно в магазин с новой формой, подписанной уже ключом банка
8. Магазин проверяет подпись банка и засчитывает заказ

```mermaid
sequenceDiagram
    autonumber
    participant U as Браузер клиента
    participant S as Сервер магазина
    participant B as Банк

    U->>S: GET /checkout
    S-->>U: HTML с подписанной формой<br/>(VK_SERVICE=1012, VK_AMOUNT, VK_MAC)
    Note over S,B: между сервером магазина и банком<br/>прямого канала НЕТ

    U->>B: POST формы (браузер, не сервер)
    B->>B: проверка VK_MAC<br/>публичным ключом магазина
    B-->>U: логин и подтверждение платежа
    U->>B: подтверждает

    B-->>U: HTML-форма назад в магазин<br/>(VK_SERVICE=1111, VK_MAC ключом банка)
    U->>S: POST /return
    S->>S: проверка VK_MAC<br/>публичным ключом банка
    S-->>U: заказ оплачен
```

Модель безопасности здесь называется «подписанные сообщения через недоверенный транспорт». Браузер клиента - это почтальон, которому не доверяют, поэтому конверт запечатан криптографической подписью.

**Почему так, а не нормальный API?** Потому что спецификация родом из начала 2000-х. Тогда у среднего эстонского интернет-магазина не было ни статического IP, ни возможности принимать входящие соединения от банка, ни понятия про OAuth. Зато у всех был браузер и умение отрендерить `<form>`. Банкам это было удобно: не нужно держать API-шлюз, не нужно управлять сессиями магазинов, вся интеграция помещается в PDF на 10 страниц.

У этого дизайна есть неожиданное практическое следствие, которое я много раз наблюдал: **на странице оплаты формы для всех банков уже подписаны и лежат рядом**. Никакой JavaScript не нужен, никакого AJAX. Клик по кнопке «SEB» это и есть отправка платежа. Ваш сервер между кликом и банком не участвует вообще, и узнаёт о происходящем только когда клиент вернётся.

## Протокол iPizza по полочкам

Все поля начинаются с префикса `VK_`. Это наследие оригинальной спецификации Hansapank, и что именно означает сокращение, в текущих документах банков уже не пишут.

Каждое сообщение это набор полей плюс подпись. Тип сообщения задаётся номером сервиса:

| Сервис | Направление | Что означает |
|---|---|---|
| `1011` | магазин -> банк | Платёж, где магазин сам задаёт счёт и имя получателя |
| `1012` | магазин -> банк | Платёж, где счёт получателя берётся из договора с банком |
| `1111` | банк -> магазин | Платёж прошёл |
| `1911` | банк -> магазин | Платёж не прошёл |
| `4011` / `4012` | магазин -> банк | Запрос аутентификации клиента |
| `3012` / `3013` | банк -> магазин | Ответ с личными данными клиента |

На практике почти все используют `1012`: реквизиты магазина уже прошиты в договоре, и подделать получателя нельзя даже теоретически. `1011` нужен редко, например при агентских схемах.

Основные поля платёжного запроса:

| Поле | Смысл |
|---|---|
| `VK_SERVICE` | номер сервиса, `1012` |
| `VK_VERSION` | версия алгоритма подписи, `008` или `009` |
| `VK_SND_ID` | ID магазина, выданный банком |
| `VK_STAMP` | ваш идентификатор запроса, до 20 символов |
| `VK_AMOUNT` | сумма, точка как разделитель, без разделителя тысяч |
| `VK_CURR` | `EUR` |
| `VK_REF` | номер ссылки платежа (viitenumber) с контрольной цифрой 7-3-1 |
| `VK_MSG` | текст, который клиент увидит в банке |
| `VK_RETURN` / `VK_CANCEL` | куда вернуть браузер после успеха и неудачи |
| `VK_DATETIME` | время в ISO 8601 с таймзоной |
| `VK_LANG` | `EST`, `ENG` или `RUS` |
| `VK_ENCODING` | кодировка, по умолчанию UTF-8 |
| `VK_MAC` | сама подпись, base64 |

В ответе `1111` добавляются `VK_T_NO` (номер платёжного поручения в банке), `VK_SND_ACC` и `VK_SND_NAME` (счёт и имя плательщика) и важный флаг `VK_AUTO`.

### VK_AUTO: единственный намёк на server-to-server

`VK_AUTO=N` означает «это клиент вернулся к вам в браузере». `VK_AUTO=Y` означает «клиент к вам не дошёл, но платёж прошёл, и банк уведомляет вас сам».

Это существенно. Клиент может закрыть вкладку сразу после подтверждения платежа, и тогда единственное, что скажет вам об оплате, это автоматический ответ банка. Обработчик возврата **обязан** быть идемпотентным: он вполне может получить и `VK_AUTO=N`, и `VK_AUTO=Y` по одному заказу.

### Как считается VK_MAC

Тут спрятана деталь, на которой спотыкаются все, кто пишет свою реализацию.

Подпись считается не по «строке параметров как в GET-запросе». Значения полей склеиваются **в фиксированном порядке**, и перед каждым значением ставится его длина в символах, отформатированная как трёхзначное число:

```
p(x1) || x1 || p(x2) || x2 || ... || p(xn) || xn
```

где `p("EXAMPLE")` даёт `007`, а пустое поле даёт `000`. Полученная строка хешируется и подписывается приватным RSA-ключом.

Зачем такая экзотика? Это защита от подмены границ полей. Если бы поля просто склеивались, то сумма `10` с сообщением `0 EUR` дала бы ту же строку, что сумма `100` с сообщением ` EUR`. Префикс длины делает разбор однозначным. Ровно та же идея, что в length-prefixed encoding в бинарных протоколах.

Два варианта алгоритма:

- **`008`**: RSA + SHA-1. Историческая версия, до сих пор массово в проде
- **`009`**: RSA + SHA-512. Появилась позже, поддерживается банками сегодня

Если вы делаете интеграцию сейчас, берите `009`. SHA-1 в 2026 году в новом коде это плохой сигнал, даже если конкретно здесь атака на коллизии не даёт очевидного выигрыша.

**Порядок полей при подписи задаётся спецификацией, а не порядком в форме.** Для каждого сервиса свой список. Это самая частая причина «подпись не сходится, а всё вроде правильно».

### Аутентификация: пангалинк как логин

Помимо оплаты, банки продают аутентификацию: сервисы `4011`/`4012` уходят в банк, `3012`/`3013` возвращают имя, фамилию и личный код (isikukood) клиента. Это использовалось для входа в госсервисы и порталы, когда ID-карта была неудобна.

Здесь есть отдельная ловушка. При проверке ответа мало проверить подпись, надо ещё проверить:

- `VK_REC_ID` - что сообщение адресовано именно вам, а не другому магазину
- `VK_DATETIME` - что оно не старше плюс-минус 5 минут
- `VK_NONCE` в `3013` - что это ответ на ваш конкретный запрос

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

Забавно, что в списке кодов средств аутентификации (`VK_TOKEN`) видна вся история эстонской электронной идентичности: 1 - ID-карта, 2 - Mobiil-ID, 5 - бумажная карточка одноразовых кодов, 6 - PIN-калькулятор, 9 - Smart-ID, 12 - биометрия.

## Где здесь можно порезаться

Раз уж мы говорим про деньги, перечислю то, что ломается на практике.

**Не проверять подпись ответа.** Это фатально и это происходит регулярно. Обработчик возврата это публичный эндпоинт, к которому приходит POST от третьей стороны. У него нет вашей сессии и нет CSRF-токена, поэтому обе защиты приходится отключить. После этого **подпись остаётся единственным, что отделяет постороннего человека от бесплатного заказа.** Кто угодно может послать вам `VK_SERVICE=1111` с чужим номером заказа.

**Не сверять сумму.** Проверили подпись, но не сравнили `VK_AMOUNT` с суммой заказа у себя. Банк подписал ровно то, что клиент подтвердил, а клиент мог подтвердить платёж на другую сумму, если вы дали ему сервис `1011` или у вас есть другая дыра.

**Не проверять VK_REF или VK_STAMP против своего заказа.** Атака: взять валидный подписанный ответ по своему заказу на 1 евро и попробовать применить его к чужому заказу на 1000.

**Считать успехом сам факт возврата на success URL.** Реальный случай, который я видел: банк возвращает клиента на success-адрес, но с `VK_AMOUNT` равным нулю, потому что платёж на самом деле не прошёл. Верить надо содержимому сообщения, а не тому, на какой из двух URL вас привели.

**Не быть идемпотентным.** Из-за `VK_AUTO` вы получите два уведомления по одному платежу. Если каждое создаёт платёж в базе, у вас будет двойная оплата в отчётности.

Общее правило: **success URL и failure URL это не сигнал, это просто два роутинга.** Сигнал только внутри подписанного сообщения.

## Сертификаты: главный источник боли

Теперь про то, что интересовало отдельно: насколько автоматизирован выпуск ключей.

Ответ короткий: **никак не автоматизирован.** Вообще. В 2026 году.

Процесс выглядит так:

1. Заключить договор с банком.
2. Сгенерировать RSA-пару: `openssl genrsa 2048`.
3. Сделать CSR или self-signed сертификат: `openssl req -new`.
4. Отправить публичную часть в банк через интернет-банк или почтой.
5. Дождаться, пока человек в банке активирует сертификат. Это занимает от нескольких часов до нескольких дней.
6. Получить сертификат банка.
7. Положить оба файла на сервер.
8. Через несколько лет всё протухнет, и никто не напомнит.

Конкретика на примере требований LHV: RSA минимум 2048 бит, формат X.509 PEM, срок действия не больше 10 лет, self-signed сертификат принимается. Coop Pank в своей инструкции рекомендует 4096 бит и отдельную пару, не связанную с TLS-сертификатом сервера.

Две команды, которые составляют весь «выпуск»:

```bash
openssl genrsa 2048 > privkey.pem
openssl req -new -key privkey.pem -out cert-req.pem
```

Дальше `cert-req.pem` уезжает в банк, а вы ждёте письма.

Насколько это редкая операция, хорошо видно по тому, что Эстонский союз электронной коммерции в 2025 году рекомендовал своим членам [веб-генератор ключей от Zone.ee](https://www.zone.ee/blogi/pangalingid/): страница, которая генерирует пару прямо в браузере. Не потому что openssl сложный, а потому что этим занимаются раз в несколько лет и каждый раз заново вспоминают синтаксис.

Сравните с тем, как это выглядит у облачных провайдеров: заходите в личный кабинет, жмёте кнопку, получаете `access key` и `secret key`. Тридцать секунд, сами, в любое время суток, в двух окружениях (sandbox и production). Никакой криптографии на вашей стороне вообще.

**Отдельно про истечение срока.** Это то, на чём люди горят. Сертификат живёт до 10 лет, то есть его выдал человек, который давно уволился, документации нет, мониторинга срока нет, письма из банка приходят на почтовый ящик, которого больше не существует. В один прекрасный день оплата в магазине просто перестаёт работать. Если вы наследуете такую интеграцию, **первым делом посмотрите даты в сертификатах** и поставьте на них алерт.

## Что изменилось с 2007 года

Чтобы не переписывать старую статью, вот дельта.

| Тогда | Сейчас |
|---|---|
| Hanza / Hansapank | Swedbank (переименован в 2008) |
| Sampo Pank -> Danske | ушли из Эстонии, портфель у LHV |
| Nordea со своим протоколом SOLOPMT | слились с DNB в Luminor, SOLOPMT мёртв |
| Krediidipank | Coop Pank |
| Кроны, подключение за 750-1000 крон плюс абонплата | Евро, у LHV подключение бесплатно и порядка 0.05 евро за транзакцию |
| Только `008` (SHA-1) | Есть `009` (SHA-512) |
| Публичный эмулятор pangalink.net | Сервис закрыт, остался [исходник на GitHub](https://github.com/andris9/Pangalink.net) и [сторонние зеркала](https://pangalink.indoorsman.ee/) |
| Договор с каждым банком отдельно | Один договор с агрегатором на все банки |
| Никакой альтернативы | PSD2 и целый рынок провайдеров |

Отдельно отмечу экономику. Раньше банковская ссылка была услугой для тех, кому не жалко тысячи крон в год. Сейчас у LHV это 5 центов за транзакцию без абонентской платы. Барьер входа исчез, и вместе с ним исчезла причина писать интеграцию с каждым банком руками.

## Три способа принимать банковские платежи сегодня

Это, пожалуй, главный практический вывод статьи.

```mermaid
flowchart TB
    subgraph A["А. Прямой iPizza"]
        A1["Магазин"] -->|VK_MAC своим ключом| A2["Swedbank"]
        A1 -->|VK_MAC своим ключом| A3["SEB"]
        A1 -->|VK_MAC своим ключом| A4["LHV"]
    end

    style A fill:#f8d7da,stroke:#dc3545
```

```mermaid
flowchart TB
    subgraph B["Б. Агрегатор банклинков"]
        B1["Магазин"] -->|один iPizza-договор| B2["LHV / Maksekeskus / EveryPay"]
        B2 --> B3["все банки"]
    end

    style B fill:#fff3cd,stroke:#ffc107
```

```mermaid
flowchart TB
    subgraph C["В. PSD2-агрегатор"]
        C1["Магазин"] -->|REST + JWT| C2["Montonio"]
        C2 -->|Open Banking API| C3["все банки ЕС"]
    end

    style C fill:#d4edda,stroke:#28a745
```

### А. Прямой iPizza с каждым банком

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

Плюсы: минимальная комиссия, деньги приходят прямо на ваш счёт, никакого посредника в цепочке.

Минусы: N договоров, N сертификатов с N сроками истечения, ваш код отвечает за криптографию платежей, и всё это ради протокола, который никто не развивает.

Когда оправдано: большой оборот, где доли цента с транзакции превращаются в деньги, и есть команда, которая это сопровождает. Либо унаследованная интеграция, которая работает и её не трогают.

### Б. Агрегатор поверх банковских ссылок

Вы подписываете один договор, и получаете кнопки всех банков. LHV прямо продаёт это как «одно соглашение = все банклинки»: LHV, Swedbank, SEB, Luminor, Coop, Citadele, Artea, Revolut, причём по всей Балтии. Похожую роль играют Maksekeskus (бренд MakeCommerce) и EveryPay.

Технически часть из них внутри работает по тем же банковским ссылкам, но вам это не видно.

Ключевое отличие для разработчика: **у Maksekeskus и EveryPay аутентификация по паре «идентификатор плюс секрет», а не по сертификатам.** Вся история с openssl и письмами в банк исчезает.

### В. PSD2-агрегатор

Это архитектурно другая вещь, и на неё стоит смотреть отдельно.

Директива PSD2 обязала все европейские банки открыть API, через которые лицензированный провайдер может инициировать платёж от имени клиента. Такой провайдер называется PISP (Payment Initiation Service Provider). Банки обязаны его пускать, потому что это закон, а не коммерческая договорённость.

Montonio работает именно так. У них лицензия платёжного учреждения (Литва, №51 от 2020 года, право оказывать услуги в Эстонии трансгранично), они зарегистрированы как PISP, и метод оплаты у них в API так и называется: `paymentInitiation`.

Что это даёт по сравнению с iPizza:

- **Покрытие не ограничено эстонскими банками.** PSD2 работает по всему ЕС, поэтому в списке появляются Revolut, Wise, N26 и польские банки
- **Нет договора с банками вообще.** Ни с одним. Договор только с провайдером
- **Обычный REST API**, а не HTML-формы

Архитектура интеграции с Montonio выглядит принципиально иначе:

```mermaid
sequenceDiagram
    autonumber
    participant U as Браузер
    participant S as Сервер магазина
    participant M as Montonio
    participant B as Банк

    S->>M: POST /api/orders<br/>тело = JWT, подписанный HS256 общим секретом
    M-->>S: paymentUrl
    S-->>U: редирект на paymentUrl
    U->>M: страница выбора банка
    M->>B: инициация платежа по PSD2 API
    U->>B: подтверждение в банке
    B-->>M: результат

    par возврат клиента
        M-->>U: редирект на returnUrl?order-token=JWT
        U->>S: GET returnUrl
    and вебхук
        M->>S: POST notificationUrl<br/>{ orderToken: JWT }
    end

    S->>S: проверить подпись JWT<br/>и paymentStatus == PAID
```

Обратите внимание на симметрию с iPizza, несмотря на совершенно разный вид:

| | iPizza | Montonio |
|---|---|---|
| Инициация | HTML-форма через браузер | server-to-server POST |
| Формат сообщения | плоские `VK_*` поля | JWT |
| Подпись | RSA, асимметричная | HS256, симметричный общий секрет |
| Ключи | сертификаты из банка вручную | access key и secret в личном кабинете |
| Уведомление в обход клиента | `VK_AUTO=Y` на тот же URL | отдельный вебхук на `notificationUrl` |
| Что проверять | `VK_MAC`, сумму, `VK_REF` | подпись JWT, `paymentStatus`, `merchantReference` |

Главный смысловой сдвиг: **симметричная подпись вместо асимметричной.** В iPizza банк не знает вашего приватного ключа, поэтому подписанное вами сообщение доказывает авторство. В JWT с HS256 обе стороны знают один секрет, поэтому это доказывает только то, что сообщение пришло от кого-то, кто знает секрет. Для схемы «мы уже доверяем друг другу по договору» этого достаточно, но секрет надо беречь так же, как приватный ключ.

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

## Библиотеки по языкам

Здесь придётся сказать неприятную правду, но сначала уточнение по конкретным ссылкам, про которые меня спрашивали.

**`Shmarkus/Banklink` это PHP, а не Node.js.** Небольшая библиотека, около 5 звёзд, последняя активность в 2024. Если нужен PHP, лучше брать `renekorss/Banklink`: он живее, там 36 звёзд, обновлялся в 2025, поддерживает и старый, и новый iPizza, плюс шлюзы Nets Estonia и другие.

**`Voog/ipizza` это Ruby**, и это как раз хороший выбор. Обновлялся в 2025, это фактический стандарт для Rails-проектов в Эстонии.

Сводка:

| Язык | Что есть | Состояние | Вердикт |
|---|---|---|---|
| PHP | [renekorss/Banklink](https://github.com/renekorss/Banklink) | живая, обновлялась в 2025 | брать эту |
| PHP | [Shmarkus/Banklink](https://github.com/Shmarkus/Banklink) | 2024, маленькая | альтернатива |
| Ruby | [Voog/ipizza](https://github.com/Voog/ipizza) | живая, обновлялась в 2025 | брать |
| Java | [nortal/banklink](https://github.com/nortal/banklink) | последний коммит в 2021 | использовать как референс |
| Node.js | `tonistiigi/ipizza` (npm `ipizza`) | последняя публикация в 2014 | **мёртвая** |
| Go | ничего | - | **нет вообще** |

Для Node.js и Go живых библиотек под iPizza нет. Не «есть, но заброшенные», а именно нет. Единственное, что находится в npm по слову banklink, это либо неродственные проекты, либо пакет 2014 года.

**Что с этим делать.** Два варианта, и оба нормальные.

*Вариант первый: написать самому.* Это звучит страшнее, чем есть. Весь протокол это примерно 150 строк:

- собрать словарь `VK_*` полей
- склеить значения в порядке из спецификации с трёхзначным префиксом длины
- `crypto.sign` / `rsa.SignPKCS1v15` этой строки
- отрендерить форму
- на возврате повторить склейку и `crypto.verify` публичным ключом банка

Никаких HTTP-клиентов, никакого стейта, никаких зависимостей кроме стандартной криптографии. В Go это `crypto/rsa` и `crypto/sha512`, в Node это встроенный `crypto`. По-хорошему, для iPizza библиотека почти и не нужна: она экономит вам таблицу порядка полей, а не сложную логику.

Обязательно возьмите порядок полей из актуальной спецификации, а не из чужого кода. [LHV публикует её открыто](https://partners.lhv.ee/et/banklink/), это самый удобный источник.

*Вариант второй, и для новых проектов на Node или Go он честнее:* не писать iPizza вообще. Взять Montonio или другого агрегатора, где интеграция это `POST` с JSON и проверка JWT, для чего библиотеки есть на любом языке. Вы теряете несколько центов с транзакции и приобретаете отсутствие криптографии в своём коде и отсутствие сертификатов в своей жизни.

Мой практический совет: **если вы стоите перед выбором с нуля и у вас не миллионные обороты, не пишите iPizza.** Единственная причина сегодня иметь дело с `VK_MAC` это унаследованная интеграция, которую нельзя выключить.

## Как это тестировать

Раньше был публичный [pangalink.net](https://github.com/andris9/Pangalink.net) - эмулятор всех эстонских банков, где можно было прогнать полный цикл без договора. Сервис закрылся, но исходники остались и разворачиваются локально, а также [живут в сторонних зеркалах](https://pangalink.indoorsman.ee/). Для отладки своей реализации подписи это до сих пор лучший инструмент: он показывает, какую именно строку он ожидал получить перед хешированием, а это ровно то место, где всё ломается.

У облачных провайдеров с этим проще: у Montonio полноценный sandbox с отдельным набором ключей, доступный сразу после регистрации, до всякого одобрения бизнеса. Вебхуки локально тестируются через ngrok.

## Что выбирать

Коротко, по ситуациям.

**Новый магазин на готовой платформе** (WooCommerce, Magento, PrestaShop, Shopify): берите готовый плагин агрегатора. Montonio, LHV и Maksekeskus все дают плагины под популярные платформы. Кода вы не пишете вообще.

**Новый проект на своём коде, Node или Go**: Montonio или другой агрегатор с REST API. Писать iPizza при отсутствии живых библиотек это добровольно взять на себя поддержку криптографии ради экономии центов.

**Нужны не только эстонские банки** (Польша, Финляндия, международные необанки): только PSD2-провайдер. iPizza это локальный протокол, за пределами Балтии его нет.

**Большой оборот, есть команда, важна каждая доля процента**: прямой iPizza или договор с банком-агрегатором вроде LHV. Но заведите мониторинг сроков сертификатов до того, как он вам понадобится.

**Унаследованная работающая интеграция**: не трогайте, но проверьте три вещи. Что подпись ответа действительно проверяется. Что сумма сверяется с заказом. Что вы знаете, когда истекают сертификаты.

## Ссылки

- [Техническая спецификация пангалинка от LHV](https://partners.lhv.ee/et/banklink/) - самый доступный первоисточник, с таблицами всех сервисов и описанием MAC008/MAC009
- [Банковская ссылка LHV](https://www.lhv.ee/ru/bankovskaja-ssylka-lhv) - условия агрегатора
- [Bank Link SEB](https://www.seb.ee/en/business/daily-banking/bank-link)
- [Документация Montonio](https://docs.montonio.com/) - хороший пример того, как сегодня выглядит нормальный платёжный API
- [Pangalink.net на GitHub](https://github.com/andris9/Pangalink.net) - эмулятор для локальной отладки
- [Генератор ключей от Zone.ee](https://www.zone.ee/blogi/pangalingid/)
- [Моя старая статья 2007 года](/ru/blog/tech/integration/pangalink/) - как это выглядело во времена крон и Nordea
