* add mock methods * add TODOs * https://rbkmoney.atlassian.net/browse/HOOK-9 add internal Hook model clean webhook dao * refactor core entities * fix tests * cleaning * implement and refactor DAO methods * implement task creator * implement task creator * start develop retry policies * fix hook dao * refactor * refactor * reset stats for hook after success post * create worker tasks and put them to queue * add message sender + refactor * clean webhook dao * make POST * add readme * clean properties * add granularity * refactor * add post-request error logic * fixed http-code policy * improve performance * add data flow test: Draft * fix test * Added some logs * fix race condition * fix * removed log * fix exception error * add transactional * fix +-1 issue * Fixed after swag protocol changes * refactor * fixed some bugs * Fix some bugs v2 * fix test * up version of eventstock
6.4 KiB
webhooker (hooker)
Сервис вебхуков
- Сервис предоставляет интерфейс для CAPI для создания, удаления вебхуков, установки/редактирования опций вебхука (таких как url, public/private keys - они генерируются сервисом, типы событий).
- Сервис поллит bustermaze на появление событий, по которым должны отправляться сообщения на вебхуки
Интерфейс для capi доступен по пути /hook
Для более подробного ознакомления со структурой объектов можно воспользоваться ссылкой на сам объект webhooker.thrift
Типы событий, по которым отправляются сообщения на вебхуки
Сообщения отправляются на следующие события:
- Создание инвойса
- Изменение статуса инвойса
- Создание платежа
- Изменение статуса платежа
Формат сообщения, отправляемого мерчанту
Пример отправки запроса мерчанту
Отправка данных
Запрос в формате JSON отправляется методом POST на url, указанный при создании вебхука. Подпись идет в headers запроса.
Тело запроса содержит поля (все поля, кроме payment_id, обязательные):
Название | Описание | Пример |
---|---|---|
event_type | тип эвента (инвойс или платеж) | invoice (payment) |
invoice_id | номер инвойса | 2Dbs4d4Dw |
payment_id | номер платежа | fsee5562 |
shop_id | идентификатор магазина | 55 |
amount | сумма, в минорных единицах | 120000 |
currency | валюта (ISO 4217) | RUB |
created_at | дата и время создания инвойса в формате UTC (RFC 3339) | 2011-07-01T09:00:00Z |
metadata | данные, переданные мерчантом при создании инвойса | {"order_id":"my_order_id"} |
status | статус инвойса(платежа) | для инвойса (unpaid, paid, cancelled, fulfilled); для платежа (pending, processed, captured, cancelled, failed) |
Таймаут на соединение и на запрос составляет 10с.
[Cписок кодов состояния HTTP][3]
Пример формирования подписи
Тело запроса (JSON) подписывается и подпись добавляется как заголовок http-запроса. Имя заголовка - X-Signature. Тело запроса для события "Инвойс создан" будет выглядеть так:
{"event_type":"invoice","invoice_id":"45b69f6ab0","payment_id":null,"shop_id":1,"amount":6207,"currency":"RUB","created_at":"2017-04-10T21:53:09.271Z","metadata":{"type":"contentType","data":"dGVzdA==","fields":["TYPE","DATA"],"fieldMetaData":{"TYPE":{"fieldName":"type","requirementType":1,"valueMetaData":{"type":11,"typedefName":null,"binary":false,"container":false,"struct":false,"typedef":false}},"DATA":{"fieldName":"data","requirementType":1,"valueMetaData":{"type":11,"typedefName":null,"binary":true,"container":false,"struct":false,"typedef":false}}},"setType":true,"setData":true},"status":"unpaid"}
После чего строка подписывается приватным ключом RSA с алгоритмом хэширования SHA-256 и размером ключа 1024.
Пример запроса к мерчанту
curl -v -X POST
-H "Content-Type: application/json; charset=utf-8"
-H "cor2A+pQ9dOMwUq8U5xUeLwh9UQD3DtzHHxcC5pplChgwmRKH5LG9Wz/rnZ2GLwUzLelowisVre1aHUKGJSl/NSF0PWJSWfCbMVtKpMwA9ZRb4pcKVX/RBiczCUIX+gFVj/6G7qWXBCxbcBV/u/vn61rWFBYi1Knvmaov4kGvZo="
-d '{"event_type":"invoice","invoice_id":"45b69f6ab0","payment_id":null,"shop_id":1,"amount":6207,"currency":"RUB","created_at":"2017-04-10T21:53:09.271Z","metadata":{"type":"contentType","data":"dGVzdA==","fields":["TYPE","DATA"],"fieldMetaData":{"TYPE":{"fieldName":"type","requirementType":1,"valueMetaData":{"type":11,"typedefName":null,"binary":false,"container":false,"struct":false,"typedef":false}},"DATA":{"fieldName":"data","requirementType":1,"valueMetaData":{"type":11,"typedefName":null,"binary":true,"container":false,"struct":false,"typedef":false}}},"setType":true,"setData":true},"status":"unpaid"}
' https://{host}:{port}/{path}
Мерчант, используя публичный ключ и имея в распоряжении тело запроса, подпись, алгоритм подписи и хэширования, может произвести проверку подписи
Политика переотправки сообщений
Если хук не отвечает или отвечает с ошибкой, пробуем 4 раза с интервалами 30сек, 5мин, 15мин, 1час опять послать неотправленное сообщение в этот хук. При этом очередь сообщений для хука копится. Если и четвертая попытка отправить сообщение оканчивается неудачей, хук помечается как выключеный и очередь сообщений для него сбрасывается. Больше попыток отправить туда сообщения не предпринимается.
В текущей реализации хукера есть возможность устанавливать разные политики для разных хуков, но имплементирована только одна политика, которую легко изменить.