Webhooks
Получайте события в реальном времени вместо polling'а. Регистрируете URL, подписываетесь на события — мы шлём POST с HMAC-подписью и ретраями.
1. Зарегистрируйте endpoint
POST /api/v1/pub/webhooks с тем же gg_live_-ключом. Секрет вернётся в ответе один раз — сохраните его, им проверяется подпись.
curl -s -X POST https://gaming-goods.ru/api/v1/pub/webhooks \
-H "Authorization: Bearer $GG_KEY" \
-H "Content-Type: application/json" \
-d '{
"url": "https://you.example.com/gg-webhook",
"events": ["order.paid", "order.delivered"]
}'
# → { "data": { "id": "...", "secret": "whsec_…", "events": [...] } } Управление: GET /pub/webhooks (список), PATCH /pub/webhooks/{id}, DELETE /pub/webhooks/{id}, POST /pub/webhooks/{id}/ping (тест-доставка), GET /pub/webhooks/{id}/deliveries (история).
2. События
order.createdзаказ созданorder.paidзаказ оплаченorder.deliveredзаказ выдан (payload содержит массив ключей)order.cancelledзаказ отменёнorder.refundedвозврат по заказуproduct.updatedтовар изменён (инкрементальное обновление каталога)balance.creditedбаланс пополнен (seller-канал)
3. Заголовки доставки
X-GG-Event— имя событияX-GG-Delivery-Id— UUID доставки; дедуплицируйте по нему ретраиX-GG-Timestamp— Unix-время подписи; отвергайте старше 5 минут (replay-protection)X-GG-Signature—sha256=<hex>, HMAC-SHA256
4. Проверка подписи
Подпись считается над строкой <timestamp>.<raw-body> ключом-секретом. Сравнивайте константно и проверяйте свежесть timestamp.
import crypto from "node:crypto"
function verify(req, secret) {
const ts = req.headers["x-gg-timestamp"]
const sig = req.headers["x-gg-signature"] // "sha256=<hex>"
if (Math.abs(Date.now() / 1000 - Number(ts)) > 300) return false // >5 мин
const mac = crypto.createHmac("sha256", secret)
.update(ts + "." + req.rawBody) // сырое тело!
.digest("hex")
const expected = "sha256=" + mac
return crypto.timingSafeEqual(Buffer.from(sig), Buffer.from(expected))
}import hmac, hashlib, time
def verify(headers, raw_body: bytes, secret: str) -> bool:
ts = headers["X-GG-Timestamp"]
sig = headers["X-GG-Signature"] # "sha256=<hex>"
if abs(time.time() - int(ts)) > 300: # >5 мин
return False
mac = hmac.new(secret.encode(), f"{ts}.".encode() + raw_body, hashlib.sha256)
return hmac.compare_digest(sig, "sha256=" + mac.hexdigest())5. Ретраи
Ответьте 2xx в течение 10 секунд. Иначе — до 7 попыток с экспоненциальной задержкой: 1s → 5s → 30s → 5m → 30m → 6h → 24h. После этого доставка помечается exhausted. Обрабатывайте идемпотентно по X-GG-Delivery-Id.