☰ Меню · Вебхуки
Посібники

Вебхуки

Отримуйте HTTPS POST-запит, коли щось відбувається: проведено чек, відкрито нагороду, надійшло замовлення зі столу.

Події охоплюють усе, що робиться через API в цьому закладі: як вашою інтеграцією, так і будь-якою іншою (інша каса, кіоск, конектор системи запису). Підписуйтеся лише на ті події, які використовуєте.

Додайте ендпоінт

У розділі Розробникам → Вебхуки або через API. URL має бути публічним і працювати через HTTPS. Секрет підпису повертається один раз, під час створення ендпоінта.

curl
curl https://loyaltyfy.io/api/v1/webhook_endpoints \
  -H "Authorization: Bearer sk_test_..." \
  -H "Content-Type: application/json" \
  -d '{
    "url": "https://pos.example.com/loyaltyfy/webhooks",
    "events": ["transaction.completed", "order.created"]
  }'
Відповідь · 201
{
  "object": "webhook_endpoint",
  "id": "01c2a784-4bcf-43b9-8ac9-ddbad7a25341",
  "url": "https://pos.example.com/loyaltyfy/webhooks",
  "description": null,
  "events": ["transaction.completed", "order.created"],
  "status": "enabled",
  "disabled_reason": null,
  "livemode": false,
  "created_at": "2026-10-06T18:17:32.381+00:00",
  "secret": "whsec_UvjHvXfPk80ITYl_xPeAtskI0WjR8-PS"
}

Що ви отримуєте

curl
POST /loyaltyfy/webhooks HTTP/1.1
Content-Type: application/json
User-Agent: Loyaltyfy-Webhooks/1.0
Loyaltyfy-Signature: t=1791310488,v1=5257a869e7ecebeda32affa62cdca3fa51cad7e77a0e56ff536d0ce8e108d8bd
JSON
{
  "id": "evt_5a1f0c9e2b7d4e3f81a0c6d2",
  "object": "event",
  "type": "order.created",
  "created": 1791310488,
  "livemode": true,
  "data": {
    "object": {
      "object": "order",
      "id": "0c69a81c-0fbc-4333-b26c-789566b9bea4",
      "number": 10,
      "status": "new",
      "table": "7",
      ...
    }
  }
}

data.object є тим самим об’єктом, який повертає API (транзакція, учасник, замовлення), у стані на момент події. Відповідайте будь-яким 2xx протягом 10 секунд. Повільну обробку виконуйте вже після відповіді.

Перевірте підпис

Loyaltyfy-Signature містить мітку часу t і підпис v1: HMAC-SHA256 від t, крапки та сирого тіла запиту, обчислений із секретом вашого ендпоінта, у шістнадцятковому вигляді. Обчислюйте його по точних байтах, які отримали, до будь-якого розбору JSON, порівнюйте за сталий час і відхиляйте мітки часу, старші за п’ять хвилин.

Node.js
import crypto from "node:crypto";

// rawBody: the request body exactly as received (a string or Buffer, not parsed JSON)
export function verifyLoyaltyfy(rawBody, header, secret, toleranceSec = 300) {
  const parts = Object.fromEntries(header.split(",").map((p) => p.split("=")));
  const t = Number(parts.t);
  if (!t || Math.abs(Date.now() / 1000 - t) > toleranceSec) return false;
  const expected = crypto.createHmac("sha256", secret).update(`${t}.${rawBody}`).digest("hex");
  const a = Buffer.from(expected);
  const b = Buffer.from(parts.v1 ?? "");
  return a.length === b.length && crypto.timingSafeEqual(a, b);
}
Python
import hmac, hashlib, time

def verify_loyaltyfy(raw_body: bytes, header: str, secret: str, tolerance: int = 300) -> bool:
    parts = dict(p.split("=", 1) for p in header.split(","))
    t = int(parts.get("t", "0"))
    if abs(time.time() - t) > tolerance:
        return False
    signed = f"{t}.".encode() + raw_body
    expected = hmac.new(secret.encode(), signed, hashlib.sha256).hexdigest()
    return hmac.compare_digest(expected, parts.get("v1", ""))

Повторні доставки

Якщо ваш ендпоінт не відповів 2xx вчасно, ми повторюємо доставку через 1 хвилину, 5 хвилин, 30 хвилин, 2 години, 6 годин, 12 годин і 24 години. Після 20 невдалих доставок поспіль ендпоінт вимикається, а заклад бачить причину в кабінеті. Увімкнути його знову можна через PATCH /v1/webhook_endpoints/{id} з enabled: true.

Через повтори подія може надійти більше одного разу, а події можуть приходити не по порядку. Відкидайте дублікати за id події, а що новіше, визначайте за мітками часу самого об’єкта.

Перевірте ендпоінт

curl
curl -X POST https://loyaltyfy.io/api/v1/webhook_endpoints/01c2a784-4bcf-43b9-8ac9-ddbad7a25341/test \
  -H "Authorization: Bearer sk_test_..."

# { "object": "webhook_test", "delivered": true, "status_code": 200, "error": null }

Повний перелік подій наведено в довіднику подій.

Питання щодо інтеграції: api@loyaltyfy.io. Відповідаємо протягом одного робочого дня.