Журнал событий

API-feed всего, что произошло в аккаунте — для аудита и реактивных интеграций

События — хронологическая лента всего важного, что случилось в вашем аккаунте: платежи, возвраты, доставка webhook, смена тарифа. Удобно для аудита, экспорта и асинхронной синхронизации.

Зачем feed, если есть webhooks

Webhooks — это push: Pay Bot шлёт вам событие как только оно случилось. Удобно, но возможны пропуски (упал ваш endpoint, истёк ретрай, не подписались на нужное событие).

Журнал событий — это pull: вы запрашиваете «дай мне всё с курсора N». Никогда ничего не пропускаете, можно retro-обработать историю.

Хорошая практика: использовать webhooks как основной механизм, журнал — как backup и для аудита.

Получение событий

bash
Скачать
curl "https://payapi.aibot.kz/v2/events?cursor=&limit=50" \
  -H "X-API-Key: kp_live_xxx"
python
Скачать
import requests

def fetch_events(cursor=None, kind=None):
    params = {"limit": 100}
    if cursor: params["cursor"] = cursor
    if kind:   params["type"]   = kind
    return requests.get(
        "https://payapi.aibot.kz/v2/events",
        headers={"X-API-Key": "kp_live_xxx"},
        params=params,
    ).json()

# Все события с начала
data = fetch_events()
while True:
    for e in data["data"]:
        process(e)
    if not data["has_more"]:
        break
    data = fetch_events(cursor=data["next_cursor"])
javascript
Скачать
async function* iterateEvents(type) {
  let cursor = null;
  do {
    const url = new URL("https://payapi.aibot.kz/v2/events");
    url.searchParams.set("limit", "100");
    if (cursor) url.searchParams.set("cursor", cursor);
    if (type)   url.searchParams.set("type", type);

    const res = await fetch(url, {
      headers: { "X-API-Key": "kp_live_xxx" },
    });
    const page = await res.json();
    for (const e of page.data) yield e;
    cursor = page.has_more ? page.next_cursor : null;
  } while (cursor);
}

for await (const event of iterateEvents("payment.completed")) {
  console.log(event);
}
php
Скачать
function fetchEvents($cursor = null, $type = null) {
    $params = ["limit" => 100];
    if ($cursor) $params["cursor"] = $cursor;
    if ($type)   $params["type"]   = $type;

    $url = "https://payapi.aibot.kz/v2/events?" . http_build_query($params);
    $ch  = curl_init($url);
    curl_setopt_array($ch, [
        CURLOPT_HTTPHEADER => ["X-API-Key: kp_live_xxx"],
        CURLOPT_RETURNTRANSFER => true,
    ]);
    return json_decode(curl_exec($ch), true);
}

Фильтрация

QueryЗначение
typeТип события (см. ниже). Можно несколько через запятую.
cursorCursor для следующей страницы
limit1–100, по умолчанию 25
sinceISO-дата, события не раньше этой
untilISO-дата, события не позже этой
bash
Скачать
# Только успешные платежи за май
GET /v2/events?type=payment.completed&since=2026-05-01&until=2026-06-01

Каталог событий

payment.completed

Платёж успешно прошёл через Kaspi.

json
Скачать
{
  "id": "evt_a1b2c3d4",
  "type": "payment.completed",
  "created_at": "2026-05-11T12:30:00Z",
  "data": {
    "operation_id": 14837690870,
    "amount": 5000,
    "phone": "77001234567",
    "sender_name": "Иван И.",
    "source": "payment_link",
    "metadata": {"order_id": "ord_1234"}
  }
}

payment.cancelled

Платёж отменён клиентом или Kaspi (например, недостаточно средств).

json
Скачать
{
  "id": "evt_x9y8z7",
  "type": "payment.cancelled",
  "created_at": "2026-05-11T12:35:00Z",
  "data": {
    "operation_id": 14837690870,
    "amount": 5000,
    "reason": "insufficient_funds"
  }
}

payment.expired

QR (5 мин) или счёт (24 ч) истёк без оплаты.

json
Скачать
{
  "id": "evt_e1x2p3",
  "type": "payment.expired",
  "created_at": "2026-05-11T12:35:00Z",
  "data": {
    "operation_id": 14837690870,
    "amount": 5000,
    "expired_at": "2026-05-11T12:35:00Z"
  }
}

payment.refunded

Возврат успешно проведён Kaspi.

json
Скачать
{
  "id": "evt_r1e2f3",
  "type": "payment.refunded",
  "created_at": "2026-05-11T15:05:00Z",
  "data": {
    "operation_id": 14837690870,
    "refund_id": "ref_a1b2c3d4",
    "amount": 5000,
    "refunded_total": 5000,
    "remaining_refundable": 0
  }
}

payment_link.created

Создана платёжная ссылка.

json
Скачать
{
  "id": "evt_pl1c2r3",
  "type": "payment_link.created",
  "created_at": "2026-05-11T12:00:00Z",
  "data": {
    "token": "pl_abc123def456",
    "amount": 5000,
    "description": "Заказ #1234"
  }
}

payment_link.paid

Платёжная ссылка получила оплату. Для allow_repeat: true может срабатывать многократно по одной ссылке.

json
Скачать
{
  "id": "evt_pl1p2a3",
  "type": "payment_link.paid",
  "created_at": "2026-05-11T12:30:00Z",
  "data": {
    "token": "pl_abc123def456",
    "operation_id": 14837690870,
    "amount": 5000
  }
}

webhook.delivery_failed

Webhook не доставлен после 5 попыток.

json
Скачать
{
  "id": "evt_wd1f2",
  "type": "webhook.delivery_failed",
  "created_at": "2026-05-11T15:00:00Z",
  "data": {
    "webhook_id": 42,
    "event_id": "wh_evt_abc123",
    "url": "https://yoursite.com/paybot",
    "last_status": 500,
    "attempts": 5
  }
}

plan.changed

Сменился тариф аккаунта.

json
Скачать
{
  "id": "evt_pc1",
  "type": "plan.changed",
  "created_at": "2026-05-11T10:00:00Z",
  "data": {
    "from": "starter",
    "to": "professional",
    "effective_at": "2026-05-11T10:00:00Z"
  }
}

Хранение

События хранятся 18 месяцев на тарифах ≥ Professional, 3 месяца на Starter, 30 дней на Trial. Для долгого хранения настройте экспорт через webhook → ваш warehouse.

Backup-обработка после downtime

Если ваш webhook-endpoint был недоступен:

python
Скачать
last_seen = db.get("paybot_last_event_id")
data = requests.get(
    "https://payapi.aibot.kz/v2/events",
    headers={"X-API-Key": "kp_live_xxx"},
    params={"since": last_seen_iso, "limit": 100},
).json()

for event in data["data"]:
    if event["id"] > last_seen:
        handle(event)
        db.set("paybot_last_event_id", event["id"])

Что дальше