Уведомления¶
Чтобы партнёр мог отслеживать состояние операций, QWIK использует уведомления — HTTPS POST-запросы, отправляемые на URL-адрес партнёра.
Структура¶
Каждый запрос состоит из заголовков и тела.
Заголовок запроса Signature содержит цифровую подпись. Цифровая подпись используется для защиты от подмены запросов: по её значению можно понять, что уведомление поступило от QWIK, а не от мошенников.
Тело запроса содержит строковое представление JSON-объекта с данными уведомления (data). Набор данных зависит от типа операции, для которого сформировано уведомление.
Актуальный формат и описание параметров уведомлений см. в документации API.
Сценарий¶
Каждый раз при получении уведомления сервер партнёра должен:
- вычислить подпись;
- сравнить полученный результат со значением из заголовка
Signature.
В случае расхождения уведомление следует игнорировать.
Обратите внимание
Ответственность за возможные финансовые потери, произошедшие из-за отсутствия валидации подписи, лежит на партнёре.
При получении и обработке уведомления сервер партнёра должен вернуть HTTP-код 200 OK. До этого момента уведомления будут отправляться каждую минуту в течение недели до получения успешного статуса.
Если по какой-то причине сервер партнёра успешно получил и обработал уведомление, но не вернул 200 OK, при повторной попытке доставки не нужно обрабатывать такое уведомление, как уведомление о новом событии.
Пример успешного сценария получения уведомления изображён на диаграмме ниже.
%%{init: {
"sequence" : {
"wrap":true,
"messageFontSize":14,
"noteFontSize":14,
"actorMargin":90 }}}%%
sequenceDiagram
participant B as QWIK
participant P as Партнёр
B->>P: Уведомление о событии (Signature, data)
P->>P: Вычисление подписи
P->>P: Сравнение с Signature
Note over P: Результат вычисления равен значению из Signature
P->>B: HTTP Status: 200 OK
B->>B: Результат получения — успешный
Обратите внимание
Если уведомление не поступило в течение 10 минут с момента совершения операции, необходимо выполнить запрос статуса операции.
Вычисление цифровой подписи¶
Для вычисления подписи необходимы байтовые представления ключа (key) и подписываемых данных, т.е. тела уведомления (data).
Обратите внимание
Необходимо обеспечить надежное хранение key и не допускать несанкционированный доступ к нему.
Алгоритм вычисления подписи
- Преобразуйте тело уведомления в байты UTF-8.
- Вычислите подпись, используя шифрование RSA с хэшом SHA512:
signature = RSA(SHA512, key, parameters).
Полученное в п.2 значение сравнивается с байтовым представлением Base64-декодированного значения заголовка Signature в уведомлении.
// signatureValue — значение подписи из заголовка
// requestBody — тело запроса в строковом виде
// key — ключ для проверки подписи
val sign: Signature = Signature.getInstance("SHA512withRSA")
val publicKey: PublicKey = KeyFactory
.getInstance("RSA")
.generatePublic(X509EncodedKeySpec(Base64.getDecoder().decode(key)))
sign.initVerify(publicKey)
sign.update(requestBody.toByteArray())
val signatureBytes: ByteArray = Base64.getDecoder().decode(signatureValue)
val isSignatureValid = sign.verify(signatureBytes)