Тестовая отправка вебхука
Скачать OpenAPIОтправляет тестовое событие tracking.test на ваш callback_url.
Авторизация
api_key Передаётся в: query
Параметры пути
ID вебхука
uuidТело ответа
application/json
curl -X POST "https://example.com/v2/webhooks/aaaaaaaa-bbbb-cccc-dddd-eeeeeeeeeeee/test"{ "success": true, "data": { "success": true, "http_status": 200 }, "status": "OK", "status_description": "Запрос выполнен успешно"}{ "success": true, "data": { "success": false, "http_status": 500, "error_message": "fetch failed" }, "status": "OK", "status_description": "Запрос выполнен успешно"}Удаление вебхука DELETE
Предыдущая страница
Получить событие отслеживания Webhook
Когда происходит событие отслеживания, на которое вы подписаны, Cargotime отправляет `POST`-запрос на ваш `callback_url`. После получения события как можно скорее верните `200 OK`. Если обработка занимает время, сначала поставьте событие в очередь, отправьте ответ, а затем обработайте его асинхронно. Cargotime ждёт ответ 10 секунд. Доставка считается успешной при любом статусе `2xx`. Cargotime повторяет доставку после статусов `408`, `409`, `425`, `429` и `5xx`, а также при таймаутах и ошибках DNS или сети. После статусов `400`, `401`, `403`, `404` и `422` повторной попытки не будет. При статусе `429` Cargotime учитывает заголовок `Retry-After`, если он передан. Всего может быть не более пяти попыток. Чтобы проверить источник запроса, используйте секрет вебхука и заголовки `x-cargotime-timestamp` и `x-cargotime-signature`. Значение подписи — HMAC SHA-256 от строки `timestamp + '.' + rawBody` с префиксом `sha256=`. В `rawBody` должно попасть исходное тело запроса без изменений. Проверять подпись необязательно, но мы рекомендуем это делать. ### Node.js / Express ```ts import crypto from 'node:crypto'; import express from 'express'; const app = express(); const secret = process.env.CARGOTIME_WEBHOOK_SECRET; if (!secret) { throw new Error('CARGOTIME_WEBHOOK_SECRET is not set'); } function queueWebhook(payload: unknown): void { // Здесь можно поставить событие в очередь, // сохранить его в базе данных или передать внутреннему сервису. console.log('Cargotime прислал вебхук:', payload); } app.post('/webhooks/cargotime', express.raw({ type: 'application/json' }), (req, res) => { const timestamp = req.header('x-cargotime-timestamp'); const signature = req.header('x-cargotime-signature'); if (!timestamp || !signature) { return res.sendStatus(401); } const expected = 'sha256=' + crypto.createHmac('sha256', secret).update(timestamp).update('.').update(req.body).digest('hex'); const signatureBuffer = Buffer.from(signature); const expectedBuffer = Buffer.from(expected); if (signatureBuffer.length !== expectedBuffer.length || !crypto.timingSafeEqual(signatureBuffer, expectedBuffer)) { return res.sendStatus(401); } const payload = JSON.parse(req.body.toString('utf8')); queueWebhook(payload); return res.sendStatus(200); }); app.listen(3000, () => { console.log('Сервер вебхуков запущен на порту 3000'); }); ``` ### Python / FastAPI ```python import hmac import hashlib import os from fastapi import FastAPI, Request, HTTPException app = FastAPI() secret = os.environ["CARGOTIME_WEBHOOK_SECRET"].encode() def enqueue_webhook(payload: dict) -> None: # Здесь можно поставить событие в очередь, # сохранить его в базе данных или передать внутреннему сервису. print("Cargotime прислал вебхук:", payload) @app.post("/webhooks/cargotime") async def cargotime_webhook(request: Request): body = await request.body() timestamp = request.headers.get("x-cargotime-timestamp") signature = request.headers.get("x-cargotime-signature") if not timestamp or not signature: raise HTTPException(status_code=401) digest = hmac.new( secret, timestamp.encode() + b"." + body, hashlib.sha256, ).hexdigest() expected = f"sha256={digest}" if not hmac.compare_digest(signature, expected): raise HTTPException(status_code=401) payload = await request.json() enqueue_webhook(payload) return {"ok": True} ```