Webhooks
Повний перелік подій, на які можна підписатися, і що містить кожна.
Підписуйтесь лише на те, що обробляєте: зайві події створюють шум і витрачають ліміти вашого обробника. Перелік подій вказується при реєстрації адреси й змінюється через PATCH.
| Тип | Коли надсилається |
|---|---|
order.paid | Квиток оплачено. Саме тут зʼявляється учасник події |
order.failed | Оплата не пройшла або сплив час на неї |
order.refunded | Кошти повернено, квиток анульовано |
event.cancelled | Подію скасовано — усі квитки на неї недійсні |
event.updated | Змінено час або місце проведення |
attendee.registered | Учасника підтверджено без оплати: безкоштовна реєстрація, схвалена заявка, гість від організатора |
attendee.checked_in | Гість пройшов check-in на вході |
Головна подія грошового шляху. Приходить після підтвердження банку — тобто тоді, коли гроші справді списані, а не коли покупець натиснув «Оплатити».
{
"id": "3d9f7c21-…",
"type": "order.paid",
"createdAt": "2026-07-30T12:02:31.000Z",
"data": {
"paymentId": "d3f1a2b4-…",
"eventId": "a1b2c3",
"status": "SUCCESS",
"amountMinor": 90000,
"currency": "UAH",
"attendeeId": "clx9attendee01"
}
}amountMinor — копійки цілим числом. attendeeId зʼявляється разом із успішною оплатою; за ним можна звірятися зі списком гостей.
Платіж уже не буде оплачено, квитка за ним не буде. Приходить один раз на платіж, з тим самим paymentId, що повертає створення замовлення через API.
{
"id": "5c1e8a47-…",
"type": "order.failed",
"createdAt": "2026-07-30T12:14:05.000Z",
"data": {
"paymentId": "e7a4c9d2-…",
"eventId": "a1b2c3",
"status": "EXPIRED",
"amountMinor": 90000,
"currency": "UAH"
}
}Причину показує status: FAILED, коли банк відхилив картку або рахунок, і EXPIRED, коли сплив час на оплату або покупець її покинув чи замінив новою (наприклад, змінив кількість квитків і отримав нове посилання). Поля attendeeId тут немає: учасник зʼявляється лише з успішною оплатою.
Подія, заради якої вебхуки й потрібні. Може прийти через тиждень після покупки — опитуванням статусу замовлення ви її не побачите.
{
"id": "7a2b9c14-…",
"type": "event.cancelled",
"createdAt": "2026-08-01T09:15:00.000Z",
"data": {
"eventId": "a1b2c3",
"title": "Джаз-вечір",
"startAt": "2026-08-15T18:00:00.000Z"
}
}Скасування не означає повернення
Це дві різні події. Скасування події позначає квитки недійсними, а кошти повертає організатор — кожен рефанд приходить окремимorder.refunded. Не вважайте гроші поверненими, доки не отримали саме його.{
"id": "b5e8d033-…",
"type": "order.refunded",
"createdAt": "2026-08-01T09:16:12.000Z",
"data": {
"paymentId": "d3f1a2b4-…",
"eventId": "a1b2c3",
"status": "REFUNDED",
"amountMinor": 90000
}
}amountMinor — сума, яку реально повернуто. Вона може бути меншою за первісний платіж: якщо сервісний збір лягав на покупця, він не повертається.
Причину повернення вебхук не передає: це внутрішня нотатка організатора, і в ній трапляються персональні дані.
В опублікованої події змінився час або місце. Правка назви, опису чи обкладинки цього вебхука не дає.
{
"id": "9e4f2b10-…",
"type": "event.updated",
"createdAt": "2026-08-02T10:20:00.000Z",
"data": {
"eventId": "a1b2c3",
"title": "Джаз-вечір",
"changed": ["time"],
"startAt": "2026-08-15T19:00:00.000Z",
"endAt": "2026-08-15T23:00:00.000Z",
"allDay": false,
"dates": [
{
"startAt": "2026-08-15T19:00:00.000Z",
"endAt": "2026-08-15T23:00:00.000Z"
}
],
"location": {
"name": "Coffee Lab",
"address": "вул. Хрещатик, 1",
"city": "Київ"
}
}
}changed каже, що саме змінилось: time, place або обидва. Решта полів несе поточні значення в тій самій формі, що й GET/api/v1/events/{eventId}: startAt, endAt, allDay і location (null, якщо місце не вказано), тож запис у себе можна просто перезаписати.
dates перелічує дні або часові слоти в хронологічному порядку, у звичайної події це один елемент. Він потрібен багатоденним подіям: коли зсувається середній день, загальні startAt і endAt лишаються тими самими. Скасування приходить окремим event.cancelled.
Учасника підтверджено без оплати: безкоштовна реєстрація, квиток за купоном на 100%, гість, якого додав організатор, або схвалена заявка. Платні реєстрації приходять як order.paid, тож сюди не потрапляють.
{
"id": "4b7d1e93-…",
"type": "attendee.registered",
"createdAt": "2026-08-03T15:40:12.000Z",
"data": {
"attendeeId": "clx9attendee01",
"eventId": "a1b2c3",
"status": "confirmed",
"tickets": [
{ "ticketTypeId": "clx9ticket001", "quantity": 1 }
]
}
}Якщо подія вимагає підтвердження заявок, вебхук приходить у момент схвалення, а не подачі заявки. Гість зі списку очікування потрапляє сюди тоді, коли його впускають. На одного учасника приходить один вебхук: скасування участі й повторна реєстрація другого не дають.
Імені, пошти й телефону в тілі немає, лише ідентифікатори. tickets показує, скільки місць якого типу отримав учасник; ticketTypeId збігається з id у переліку типів квитків події.
Квиток пройшов вхід: сканування QR, пошук у списку гостей чи впуск на дверях.
{
"id": "e2a9c6f4-…",
"type": "attendee.checked_in",
"createdAt": "2026-08-15T18:07:44.000Z",
"data": {
"attendeeId": "clx9attendee01",
"eventId": "a1b2c3",
"ticketTypeId": "clx9ticket001",
"quantity": 1,
"method": "qr",
"checkedInAt": "2026-08-15T18:07:43.000Z"
}
}Check-in стосується квитка, а не людини: у багатоденної події в учасника кілька квитків, і кожен приходить окремим вебхуком. quantity більше 1 означає груповий квиток, за яким пройшло кілька людей. method набуває значень qr, nfc або manual. Скасування check-in вебхука не дає, а повторний check-in того самого квитка другого не надсилає.
Події не гарантовано приходять у тому порядку, в якому сталися: кожна доставка ретраїться незалежно, тож подія з повтору може прийти після пізнішої. Орієнтуйтесь на createdAt у тілі, а не на час отримання.
Практичний висновок: обробник має бути стійким до подій «не за чергою». Наприклад, order.refunded, що прийшов раніше за order.paid, не має створювати запис із нуля — перевіряйте поточний стан у себе.