Вибачте, ми оновлюємо протокол

Ще в 2011 році нас запитували, навіщо вводити номер телефону для виставлення рахунку на стороні партнера? Ми давно хотіли полегшити інтеграцію для наших партнерів, але раніше зробити це було досить складно. Що ж змінилося в QIWI в 2016? Зараз розповімо, а також поекспериментуємо з хабровским R&D голосуванням.



Узгодження, біль і сльози великих компаній
Якщо спростити, в роботі над будь-яким проектом компанії бере участь три групи:

  • Замовники. Відповідають за бізнес-ідею проекту, фінансову оцінку, продажу;
  • Проектні менеджери. Відповідають за технічну реалізацію, визначають, які групи вона торкнеться, контролюють загальні терміни та запуск проекту;
  • Розробники. Реалізують і запускають проект.
У кожного підрозділу були свої підгрупи з чергами і пріоритетами. Завдання на серйозне доопрацювання сайту зачіпала легіон колег:

  • Платіжний процесинг:

    • Java-розробники, відповідальні за платежі, API для великих партнерів і стандартні зовнішні API,
    • Oracle-розробники, відповідальні за проектування БД і процедури;


  • Веб-розробка:

    • Java back-end + API розробники для вебу,
    • JavaScript розробники, особливо для SPA,

    • Верстальники;

  • Q&A, дає добро на підсумковий випуск продукту.


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

Зараз в QIWI формуються команди під конкретні продукти. При цьому, наприклад, Java-розробник з команди продукту, якщо це потрібно, може вносити зміни в платіжний процесинг, які пройдуть перевірку і будуть прийняті. Раніше це повинні були робити тільки розробники процесингу, т. к. веб-розробники перемикалися на інші проекти своєї черги завдань. Новий підхід робить команду більш гнучкою, а час на реалізацію нової функціональності значно скорочується. Давайте подивимося, як ми вирішили змінюватися.

Вісім років потому ми зважилися
Переробка основного протоколу — відповідальний крок, але обов'язковий введення номера телефону на стороні партнера ускладнював інтеграцію і оплату. Ми дослідили два варіанти розвитку:

1. Зараз наш серверний REST-протокол зобов'язує вказувати номер телефону для виставляння рахунку. Розглядався варіант доопрацювання для виставлення рахунку на довільний ідентифікатор або email.

Плюси:

  • Гнучкий підхід, зручний для потенційного оновлення у існуючих партнерів,
  • Максимальна захист, т. к. протокол передбачає тільки межсерверное взаємодія.
Мінуси:

  • Ускладнена інтеграція для нових партнерів, оскільки потрібно виставляти рахунок перед переадресацією на сторінку оплати,
  • Дуже складно робити масові сервіси з оповіщенням про виставлених рахунках,
  • Потребує значної переробки архітектури рахунків у платіжному процессингу.
2. У компанії був http-протокол з введенням номера на стороні QIWI. Але в ньому ніяк не перевірялося, що рахунок виставляється саме партнером. Цей протокол ідеально підходив для збору пожертв, але для великих партнерів його не можна було застосовувати в такому вигляді. Вихід полягав у додаванні підпису або хешу і їх подальшій перевірці при переадресації на сторінку оплати рахунку.

Плюси:

  • Проста реалізація для нових партнерів,
  • Невеликі витрати на розробку з боку команди.
Мінуси:

  • Може з'явитися «обдаровані» партнери, які будуть зберігати секретний ключ і обчислювати підпис клієнта.
Після недовгих обговорень був обраний другий варіант. Спочатку служба безпеки та IT-підрозділу віддавали перевагу формуванню підпису на основі відкритого та закритого ключів. Однак, згадавши досвід інтеграції навіть з великими партнерами і число виникаючих питань і проблем при заміні сертифікатів, вирішили, що зупинимося на перевірці хеш sha512.

Спрощуйте.  Pavel Durov (@durov) January 18, 2011


Постало питання, які параметри хешировать? Найпростіший варіант — упорядкувати всі за алфавітом, додати секретний ключ і взяти хеш. Після аналізу стало зрозуміло, що можуть виникнути проблеми з коментарями і кодуваннями, тому скоротили список до мінімально необхідного числа параметрів.

Залишалося питання, як визначити секретний ключ. Для basic-авторизації в REST-протоколі використовується пара з API ID і API Password, яка дозволяє гнучко налаштовувати перевірки для партнера. Для одного сайту можна завести декілька авторизаційних пар і використовувати їх на різних серверах і версіях сайту.

Алгоритм і приклад
У підсумку прийшли до такого алгоритму:

  • Формуємо масив параметрів:

    • api_id — id для визначення секретного ключа,
    • currency — валюта,

    • from — id провайдера,
    • summ — сума,
    • to (при наявності) — номер телефону,
    • txn_id — унікальний ID транзакції на стороні провайдера;
  • Додаємо в масив секретний ключ, пов'язаний з api_id;
  • Об'єднуємо всі значення параметрів в рядок, використовуючи роздільник між параметрами;
  • Обчислюємо хеш sha512;
  • Додаємо в запит рядковий параметр signature в шістнадцятковому вигляді в нижньому регістрі.
Приклад реалізації на PHP.

//ID проекту, API_ID, API пароль виходять у налаштуваннях url: https://ishop.qiwi.com/options/rest.action
//ID проекту
$SHOP_ID = "260***";
$API_ID = "4683****";
//API пароль
$API_PWD = "1T1ea7****";
$CCY = "RUB";
$AMOUNT = 1.12;

//Телефон у форматі 71231234567. Необов'язковий параметр
$PHONE = "";
//ID транзакції
$TXN_ID = "habr".rand(1,90000);

$phoneParam = "";
if ($PHONE != ""){
$phoneParam='&to='.$PHONE;
//Формуємо масив параметрів з номером телефону, якщо ми його знаємо
$params = array($API_ID,$CCY,$SHOP_ID,$AMOUNT,$PHONE,$TXN_ID);
}else{
//Формуємо масив параметрів без номера телефону
$params = array($API_ID,$CCY,$SHOP_ID,$AMOUNT,$TXN_ID);
}
//Додаємо в параметри секретний ключ
array_push($params,md5($API_PWD));
//Формуємо рядок з параметрів з роздільником "|"
$paramsStr = implode("|", $params);
//Обчислюємо хеш
$signature = hash('sha512',$paramsStr);

//Збираємо підсумковий url для клієнта
$url = 'https://bill.qiwi.com/order/external/create.action?from='.$SHOP_ID.'&txn_id='.$TXN_ID.'&summ='.$AMOUNT.'&api_id='.$API_ID.'¤cy='.$CCY.'&signature='.$signature.$phoneParam;

Колективний R&D
Пропоную, в якості експерименту, разом вирішити, як розвивати протокол. Ми не вирішили кілька технічних питань і пропонуємо вам поміркувати разом з нами, як розвивати протокол. Для цього в кінці статті додано голосування.

Основною проблемою залишається параметр lifetime, відповідальний за час життя рахунку. В існуючому протоколі він передавався у хвилинах, а рахунок виставлявся відразу після переадресації. У новому — рахунок може виставлятися істотно пізніше, особливо якщо посилання була надіслана електронною поштою. Тому, швидше за все, потрібно додати новий параметр з абсолютною датою. Наприклад, в форматі ISO 8601 (2016-09-12T00:00:00), який використовується в REST. Але чи потрібні там секунди? І просити чи кодувати ':' в '%3A', або замінити його на '-', т. к. багато досі передають success_url без url кодування і стукають у підтримку з питаннями. Швидше за все, новий параметр варто також включати в вычисляемую підпис.

Оновлений протокол з працею, але дозволяє робити масові розсилки. Основна проблема в унікальному id транзакції, який необхідно буде генерувати при створенні посилання. Для масових розсилок з купівлею конкретного предмета це може бути важко. Рішенням могла б стати сукупність id покупки і акаунта користувача в магазині, але тоді користувач зможе купити що-то тільки один раз. Проблему можна було б вирішити зробивши нові параметри і прибравши обмеження унікальності. Правда, є сумніви, що це потрібно ринку. Проголосуємо?

На десерт
Новий протокол вже готовий для підключення партнерів, але поки активується тільки через службу підтримки. Якщо ви хочете взяти участь у тестуванні, пишіть на cms@qiwi.ru або звертайтеся на підтримку.

Оцінити поточний стан сторінки оплати ви можете здесь. З днем програміста!

p.s. Запрошую Java розробника з хорошим досвідом реалізації REST API приєднатися до нашої команди запуску нового ishop.qiwi.com і якісно перевернути світ для тисяч наших партнерів вже в цьому році.

Джерело: Хабрахабр

0 коментарів

Тільки зареєстровані та авторизовані користувачі можуть залишати коментарі.