DonateXdev.

ВойтиСоздать приложение

События

Вебхуки

Подписки на вебхуки DonateX, формат доставки, подпись HMAC-SHA256 и повторы.

Как работают вебхуки

  1. Создайте подписку с HTTPS-адресом и своим секретом — не больше 3 на пользователя.
  2. На каждый донат DonateX отправит POST с JSON и подписью в заголовке.
  3. Ответьте любым 2xx в течение 10 секунд. Иначе доставка повторится до 3 раз.
  4. После 5 неудачных попыток подряд (повторы тоже считаются) подписка отключается — включите её методом активации.

Заголовки запроса

X-DonateX-Eventstring

Тип события, сейчас DonationCreated

X-DonateX-Subscription-Iduuid

ID подписки, которая получила событие

X-DonateX-Signaturehex

HMAC-SHA256 от сырого тела запроса с вашим секретом, в нижнем регистре

X-DonateX-Client-Idstring

Ваш clientId, если он указан в подписке

Тело запроса

{
  "eventType": "DonationCreated",
  "data": {
    "id": "4fd9677b-8b17-4c9d-9a9f-c2a7a3f9960b",
    "username": "NeDrugLegenda1377",
    "message": "",
    "withAIResponse": false,
    "musicLink": "",
    "currency": "RUB",
    "amount": 500.00,
    "amountInRub": 500.00,
    "timestamp": "2026-10-12T18:42:07Z",
    "aiResponse": null,
    "aiResponseVoiceFilePath": null,
    "wasShown": true,
    "isTest": false,
    "isPotentiallyUnsafe": false,
    "isFeePaidByUser": true,
    "voiceFilePath": "https://cdn.donatex.gg/default-donation-voices/4fd9677b-8b17-4c9d-9a9f-c2a7a3f9960b.mp3",
    "paidVoice": "",
    "voiceMessagePath": null,
    "voiceMessageDurationMs": null,
    "videoMessagePath": "https://cdn.donatex.gg/donation-video-messages/4fd9677b-8b17-4c9d-9a9f-c2a7a3f9960b.mp4",
    "videoMessagePosterPath": "https://cdn.donatex.gg/donation-video-messages/4fd9677b-8b17-4c9d-9a9f-c2a7a3f9960b.jpg",
    "videoMessageDurationMs": 14250,
    "aiCharacterId": null
  },
  "timestamp": "2026-10-12T18:42:08.1145678+00:00"
}

Проверка подписи

Считайте HMAC от тела ровно в том виде, в каком оно пришло, и сравнивайте за постоянное время. Повторная сериализация JSON меняет байты, и подпись не сойдётся.

Node.js · Express

import crypto from 'node:crypto';
import express from 'express';

const app = express();

// Подпись считается от сырого тела — не парсите JSON до проверки
app.post('/webhooks/donatex', express.raw({ type: 'application/json' }), (req, res) => {
  const expected = crypto
    .createHmac('sha256', process.env.DONATEX_WEBHOOK_SECRET)
    .update(req.body)
    .digest('hex');
  const received = req.get('X-DonateX-Signature') ?? '';

  const isValid = expected.length === received.length
    && crypto.timingSafeEqual(Buffer.from(expected), Buffer.from(received));
  if (!isValid) return res.sendStatus(401);

  const event = JSON.parse(req.body.toString('utf8'));
  handleDonation(event.data);
  res.sendStatus(200); // ответ 2xx останавливает повторы
});

Python · Flask

import hashlib
import hmac
import os

from flask import Flask, abort, request

app = Flask(__name__)

@app.post("/webhooks/donatex")
def donatex_webhook():
    expected = hmac.new(
        os.environ["DONATEX_WEBHOOK_SECRET"].encode(),
        request.get_data(),
        hashlib.sha256,
    ).hexdigest()
    if not hmac.compare_digest(expected, request.headers.get("X-DonateX-Signature", "")):
        abort(401)

    handle_donation(request.get_json()["data"])
    return "", 200

Список подписок

GEThttps://donatex.gg/api/v1/webhooks/subscriptions

Все подписки на вебхуки владельца токена, включая отключённые.

OAuth-токену нужен scope donations.subscribe. External token работает без scopes.

Ответы

iduuid

ID подписки

urlstring

HTTPS-адрес доставки

clientIdstring | null

Идентификатор вашей интеграции; null, если не задан

eventTypestring

Тип события, сейчас DonationCreated

isActiveboolean

Активна ли подписка

failureCountinteger

Ошибок доставки подряд; после 5 подписка отключается

Не удалось получить список подписок пользователя

Общие для всех методов: 401 — нет токена или он недействителен, 403 — у OAuth-токена нет нужного scope, 429 — превышен лимит запросов. Подробнее об ошибках

GET/v1/webhooks/subscriptions
curl "https://donatex.gg/api/v1/webhooks/subscriptions" \
  -H "Authorization: Bearer $DONATEX_TOKEN"
[
  {
    "id": "ef3c9b44-1bd6-4f8e-8f47-4c7b6f50a0e8",
    "url": "https://example.com/webhooks/donatex",
    "clientId": "my-overlay",
    "eventType": "DonationCreated",
    "isActive": true,
    "failureCount": 0
  }
]

Создать подписку

POSThttps://donatex.gg/api/v1/webhooks/subscriptions

Регистрирует адрес, на который DonateX будет отправлять события. Нужен HTTPS и секрет для подписи. Не больше 3 подписок на пользователя.

OAuth-токену нужен scope donations.subscribe. External token работает без scopes.

Тело запроса

urlstringобязательный

HTTPS-адрес доставки, до 1024 символов

secretstringобязательный

Секрет для подписи HMAC-SHA256, до 128 символов

eventTypestringобязательный

Тип события; сейчас только DonationCreated

clientIdstringнеобязательный

Идентификатор вашей интеграции, до 100 символов. Придёт в заголовке X-DonateX-Client-Id

Ответы

iduuid

ID подписки

urlstring

HTTPS-адрес доставки

clientIdstring | null

Идентификатор вашей интеграции; null, если не задан

eventTypestring

Тип события, сейчас DonationCreated

isActiveboolean

Активна ли подписка

failureCountinteger

Ошибок доставки подряд; после 5 подписка отключается

Неверный URL
Webhook URL должен использовать HTTPS
Некорректный секрет
Неверный тип события
ClientId слишком длинный
Достигнут лимит подписок (3 на пользователя)
Повторите попытку позже
{
  "type": "https://tools.ietf.org/html/rfc9110#section-15.5.1",
  "title": "One or more validation errors occurred.",
  "status": 400,
  "errors": {
    "url": [
      "'url' must not be empty."
    ]
  },
  "traceId": "00-4bf92f3577b34da6a3ce929d0e0e4736-00f067aa0ba902b7-00"
}

Общие для всех методов: 401 — нет токена или он недействителен, 403 — у OAuth-токена нет нужного scope, 429 — превышен лимит запросов. Подробнее об ошибках

POST/v1/webhooks/subscriptions
curl -X POST "https://donatex.gg/api/v1/webhooks/subscriptions" \
  -H "Authorization: Bearer $DONATEX_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "url": "https://example.com/webhooks/donatex",
    "secret": "YOUR_WEBHOOK_SECRET",
    "eventType": "DonationCreated",
    "clientId": "my-overlay"
  }'
{
  "id": "ef3c9b44-1bd6-4f8e-8f47-4c7b6f50a0e8",
  "url": "https://example.com/webhooks/donatex",
  "clientId": "my-overlay",
  "eventType": "DonationCreated",
  "isActive": true,
  "failureCount": 0
}

Отключить подписку

DELhttps://donatex.gg/api/v1/webhooks/subscriptions/{subscriptionId}

Останавливает доставку событий. Подписку можно включить обратно методом активации.

OAuth-токену нужен scope donations.subscribe. External token работает без scopes.

Path-параметры

subscriptionIduuidобязательный

ID подписки

Ответы

Тело ответа пустое — проверяйте только статус.

Подписка не найдена

Общие для всех методов: 401 — нет токена или он недействителен, 403 — у OAuth-токена нет нужного scope, 429 — превышен лимит запросов. Подробнее об ошибках

DEL/v1/webhooks/subscriptions/{subscriptionId}
curl -X DELETE "https://donatex.gg/api/v1/webhooks/subscriptions/ef3c9b44-1bd6-4f8e-8f47-4c7b6f50a0e8" \
  -H "Authorization: Bearer $DONATEX_TOKEN"
// Пустое тело ответа

Включить подписку

POSThttps://donatex.gg/api/v1/webhooks/subscriptions/{subscriptionId}/activate

Включает отключённую подписку и обнуляет счётчик ошибок доставки.

OAuth-токену нужен scope donations.subscribe. External token работает без scopes.

Path-параметры

subscriptionIduuidобязательный

ID подписки

Ответы

Тело ответа пустое — проверяйте только статус.

Подписка не найдена

Общие для всех методов: 401 — нет токена или он недействителен, 403 — у OAuth-токена нет нужного scope, 429 — превышен лимит запросов. Подробнее об ошибках

POST/v1/webhooks/subscriptions/{subscriptionId}/activate
curl -X POST "https://donatex.gg/api/v1/webhooks/subscriptions/ef3c9b44-1bd6-4f8e-8f47-4c7b6f50a0e8/activate" \
  -H "Authorization: Bearer $DONATEX_TOKEN"
// Пустое тело ответа