Получение уведомлений

Для получения уведомлений от сервисов «Наложка» необходимо реализовать доступный из интернета веб-хук, адрес которого нужно указать при запросе доступа к API.

Все запросы к веб-хуку отправляются методом POST и в теле содержат данные события в формате JSON. Набор полей события отличается в зависимости от типа события, но есть поля, которые присутствуют в данных любого события. К ним относятся:

  • id — уникальный строковой идентификатор события;
  • type — мнемонический строковой тип события;
  • occurred_at — момент возникновения события.

Для проверки подлинности полученного события в строке запроса вам придет параметр signature, значением которого является цифровая подпись события, кодированная в Base64, рассчитанная от всего тела запроса по алгоритму RSA с дайджестом SHA-256. Публичный ключ в PEM формате для проверки такой подписи вы можете взять по ссылке nalogka-rsa-public.pem для событий боевого сервера и nalogka-sandbox-rsa-public.pem для событий тестового сервера (при запросе этих ссылок ssl-сертификат должен быть действителен). Разные ключи для боевого и тестового сервера позволяют исключить ошибку обработки тестового события боевым сервером, если некорректно настроен вебхук.

Чтобы проверить подпись, воспользуйтесь готовыми библиотеками для работы с OpenSSL для вашего языка программирования. Если подпись не совпадает, опишите проблему в email-письме и отправьте его на адрес integration@nalogka.com, приложив полученное сообщение (желательно с HTTP-заголовками).

Отладить проверку подписи боевого сервера можно, взяв в качестве сообщения строку Проверка RSA-подписи Наложки и к ней подпись (base64) —

fvKGw3YBaG5S9pfj3qVmr81VVovCQPPEvTua6LcMnNswMlFxcyIyj8il59VS5YuIBXUoc1LiXLvw
f3BctBJrUHTgrTYpsgPBO6t2F5/vp8jSnIc06PSLy/sDQzunkn9v8vwJi6f1yvF6Y/NIGxTopDss
qfmnvIMnfLmqHXrwu6ToTMZZCrwx/p1kZAnUdd3LyPNc56aERL0vsYWbMKV7raWQhDUUD8BV+cKf
aawHLogBsI1BtYxkKV2kPVyIwzvUHL9XtkhGJLzHAHlxWc84rvTLeZ7cEsbZr3AG+teyq7nlXPRf
ruVJoOIg3z+a4IDOcYsWJI3b6+67pSQIYakBZFSTwH3HRiLS1Sw8dGGGDNtUckjkGbc1X8g+ovZB
SF8SUxEkdZGWOf9dAeJyePFLutZu7FvGvdXduNHYOq57TXYYsMVIQ9bFodaVse7bXx6O0gKLdEY/
OqK1dJa3J74LqgkEeh85mBv9hDQxvLk0LtYFh2JOMYEJ63d563LjcRls6WhxiDHe+EnkQ0ywNHxP
zLVm4CSyjdw7m1pawxffk2cgIyTgiH6tbVFA/iDz/9rPOb0z3oscxn+4wLYVb0Bgy8TXdEGaeBqv
1c03Rak/ZnOGM6W2Nlv6ghxa0KdNVWAw8MexpAQoyR2etmIn5NbSB+Qzgpoq/KEAQGPIspvkabI=

Примеры

Предположим, что вами указан вебхук https://your-server.example.com/nalogka-event.

При возникновении события, система отправляет HTTP-запрос вида:

POST /nalogka-event?signature=FWzrfYzsrGgNujIPZNQ%2BOuNwcjRDN7U0AkOJK9bHDCxmP6Mz3WQve3hw7AUGCMFQ8AzUmivuU4AmmczYaRUf%2Bu2PmwQr4CDfbwkxSYKYVo6NLoR0kUoWOJhoZkfdbOXf25W7wlBLd7OHPd61kunFMzXrcxMkF4PM%2Fk1f6p1FT5I6ifJm5OA51GCGUuU4Scm0xqC%2FDC%2BAR6VDdAwkaL4HL7VWBU8Z2Y%2F7TI7yp8fKRh0IQJKXa62TNveB4PgXbjNXS7zSWrUAbECw8n59iGXrGsfAM2KNfnMrfmvOVhVr5%2BgpnkmQL4rLTCorQQhCG9CIItiDmyS1fflhR%2Ba1tu0lJo42LqMP4rM6BfuOR%2FCMpjA%2Bpi5mPTiU%2BQks%2Fsvz8XxMJgsZ%2FcjRSiO4QF%2BLbkHGGBXgEcPRcujPV%2BHAb%2BaFasC32muRqxyKjX37W4SIryPXwxAmojzq6GNcXi4HdBmFLrUevnq1vFXwqPzLBshaLalaDWYgX3xpb2%2BId6L0q%2F1OhGivuhdbUaMtWZk4zYE8pkaZQksPK2FPk9d%2FmU8yeGfbD65pqQYywrU2%2FSCOKf2u8XGZboWJHzAzBHWZxm%2BtwAWET1Gbxz0UGJTo6tpxm33MnL95wDcGzYDTfMyYKtJO6kO8YCj1q0JMQCUAt77DaqEsLS8d7Cm4RBayjzPa2GI%3D%0A
Host: your-server.example.com
Content-Type: application/json; charset=utf-8
Connection: close

{
    "id": "bd98529d9e12f92844749cbac51f0661",
    "type": "deals.deal.changed_status",
    "occurred_at": "2018-10-23T10:37:22+03:00"
    "old_status": "draft",
    "new_status": "confirmed",
    "deal: {
        "~type": "Deal",
        "~id": "1106",
        "created_at": "2018-08-28T09:15:16+00:00",
        "updated_at": "2018-08-28T09:15:16+00:00",
        "marketplace_id": "nalogka",
        "status": "draft",
        "status_updated_at": "2018-08-28T09:15:16+00:00",
        "conditions": "Хрупкий, крупногабаритный груз",
        "buyer_profile_id": "41",
        "seller_profile_id": "17",
        "confirmed_by": "both",
        "deposit": null,
        "calculation_result": {
            "~type": "CalculationResult",
            "subject_items_sum": 6700.45,
            "seller_provided_sum": 200,
            "seller_consumed_sum": 200,
            "buyer_consumed_sum": 200,
            "commission_sum": 276.02,
            "commission_seller_sum": 138.01,
            "commission_buyer_sum": 138.01,
            "buyer_expenses": 7338.46,
            "seller_expenses": 338.01,
            "buyer_have_to_pay_online": 538.01,
            "buyer_have_to_pay_offline": 100,
            "seller_have_to_pay_online": 0,
            "payout": 6562.44,
            "seller_profit": 6362.44,
            "commission_payer": "50/50"
        },
        "token": "z8cvo9ushk1tnwe",
        "attachments": [
            {
                "~type": "Attachment",
                "id": "MF0mpOSy/cat.jpg",
                "description": "",
                "public_url": "http://filestorage/file/MF0mpOSy/cat.jpg",
                "mime_type": "image/jpeg",
                "size": "485377"
            }
        ],
        "commission_payer": "50/50",
        "buyer_have_to_pay_offline": "270",
        "subject_items": [
            {
                "~type": "SubjectItem",
                "sku": "AB0000001",
                "name": "Смартфон Apple iPhone 5s 16Gb Серебристый",
                "description": "Есть царапина на корпусе",
                "price": "23500",
                "quantity": "1"
            }
        ],
        "additional_services": [
            {
                "~type": "AdditionalService",
                "type": "delivery",
                "name": "Доставка СДЭК",
                "description": "Тариф Посылка Склад-Склад",
                "original_cost": 450,
                "final_cost": 400,
                "payer": "seller",
                "provided_by": "seller"
            }
        ],
        "dispute": null
    }
}

Пример проверки подписи события на PHP

// получаем подпись из параметра запроса
$signature = base64_decode($_GET['signature']);

// получаем тело запроса
$body = file_get_contents('php://input');

// читаем ключ из nalogka-rsa-public.pem, ранее полученный из https://api.nalogka.ru/nalogka-rsa-public.pem
$publicKey = openssl_get_publickey('file://path/to/nalogka-rsa-public.pem');

$result = openssl_verify($body, $signature, $publicKey, OPENSSL_ALGO_SHA256));

if (1 === $result) {
    // подпись верна
} elseif (0 === $result) {
    // подпись не соответствует данным
} else {
    // ошибка при проверке подписи
}

Подробнее - мануал PHP