# Мероприятия и продажа билетов

> Предпродажа через ссылку на оплату или форму на сайте, оплата на входе по QR или счётом на телефон, массовое выставление, номер места в metadata и возвраты при отмене.

## Коротко

У мероприятия два разных момента оплаты, и делаются они разными инструментами. **Предпродажа** — ссылка на оплату (без кода) или форма на сайте (через форма-хук). **На входе** — QR на экране или счёт прямо на телефон гостя, потому что там счёт идёт на секунды. Номер места, сектор, тип билета — всё это кладётся в поле `metadata` и возвращается обратно в вебхуке. Если мероприятие отменяется, возвраты делаются по каждому счёту.

## Предпродажа

### Без кода: ссылка на оплату

Самое простое. Делаете по одной ссылке на каждый тип билета:

| Билет | Сумма | Ссылка |
|---|---|---|
| Стандарт | 8 000 ₸ | `qut.kz/p/standart` |
| VIP | 20 000 ₸ | `qut.kz/p/vip` |
| Студенческий | 4 000 ₸ | `qut.kz/p/student` |

Ссылки размещаете в Instagram, на афише, в Telegram-канале. Кто оплатил — видно в кабинете. Подробнее: [Ссылки на оплату](/kb/ru/payment-links).

Если собираете спонсорские или добровольные взносы, сделайте ссылку, где сумму вводит сам плательщик: [Ссылки с открытой суммой](/kb/ru/open-amount-links).

### Форма на сайте

Если у вас есть форма регистрации (имя, телефон, тип билета), привяжите её к оплате. Tilda и любые формы подключаются через форма-хук, писать код не нужно: [Tilda и любые формы](/kb/ru/tilda-forms).

Для собственного сайта хватит одного метода API.

## Схема работы по шагам

Продажа билета с сайта:

| Шаг | Кто | Что происходит |
|---|---|---|
| 1 | Участник | Заполняет форму, выбирает тип билета |
| 2 | Ваш сервер | `POST /api/v1/invoices` — создаёт счёт, кладёт место и тип билета в `metadata` |
| 3 | Участник | Открывает ссылку и подтверждает в Kaspi |
| 4 | Qut Pay | Отправляет на ваш адрес событие `invoice.paid` |
| 5 | Ваш сервер | Выпускает билет и отправляет его QR участнику |
| 6 | На входе | Сканируете QR билета и пропускаете гостя |

QR, который сканируют на входе, — это QR **вашего билета**, а не платежа. Не путайте их.

## Какой метод API используется

```
POST https://api.qut.kz/api/v1/invoices
X-API-Key: qp_live_…
Idempotency-Key: reg-2026-0417-A14

{
  "amount": 8000,
  "kind": "qr",
  "description": "Concert 17.04, стандарт",
  "externalOrderId": "reg-2026-0417-A14",
  "customer": { "name": "Дархан", "phone": "77011234567" },
  "metadata": {
    "event": "concert-2026-04-17",
    "ticketType": "standard",
    "sector": "A",
    "seat": 14
  }
}
```

`description` видит клиент: в QR-счёте ограничение 100 символов, в счёте по телефону — 60. Уместите туда название мероприятия и дату.

Стройте `Idempotency-Key` из номера регистрации — тогда двойное нажатие кнопки «Оплатить» не создаст второй счёт.

## Оплата на входе

На входе стоит очередь, поэтому важна скорость. Два пути:

| Путь | Как | Когда лучше |
|---|---|---|
| QR на экране | Открываете QR счёта на планшете, гость сканирует | Хорошее освещение, обычная очередь |
| Счёт на телефон | Спрашиваете номер и отправляете счёт с `kind: "phone"` | Темно, улица, экран не видно |

При счёте на телефон гостю приходит push в приложение Kaspi, он подтверждает сразу. Номер в формате `7XXXXXXXXXX`. Сравнение: [QR-счёт или счёт по телефону](/kb/ru/qr-vs-phone).

**Окно сканирования QR — около трёх минут.** Не создавайте счёт человеку заранее, пока он стоит в очереди: создавайте, когда подошла его очередь, иначе счёт истечёт.

Вариант без кода: выставляйте счёт из кабинета или командой `/invoice` в Telegram-боте. На входе с телефона бот удобнее.

## Массовое выставление счетов

Если продаёте билеты организациям, группам, школьным классам, счета можно выставить одним запросом: `POST /api/v1/invoices/bulk`, от 1 до 100 счетов за раз.

Каждый элемент **проверяется отдельно**: если один ошибочный, остальные всё равно создадутся. В ответе видно, какие прошли, а какие упали. Не считайте ответ единым целым — читайте результат по каждому элементу. Подробнее: [Массовое создание счетов](/kb/ru/bulk-invoices).

При массовом выставлении давайте каждому элементу свой `externalOrderId` и свой `metadata`, иначе не разберётесь, кто оплатил.

## Metadata: номер места

На мероприятии `metadata` — самое полезное поле. Что туда класть:

```
"metadata": {
  "event": "concert-2026-04-17",
  "ticketType": "vip",
  "sector": "B",
  "row": 3,
  "seat": 12,
  "promoter": "insta",
  "guestName": "Дархан"
}
```

Что это даёт:

- Всё возвращается в вебхуке `invoice.paid` — билет выпускаете прямо там
- В выгрузке CSV можно фильтровать: сколько продано по секторам
- Отчёт по промоутерам: какой канал привёл сколько билетов

`externalOrderId` — отдельное поле, это ваш номер регистрации. Используйте оба: [Metadata и номер заказа](/kb/ru/metadata-and-orders).

## Мероприятие отменилось: массовые возвраты

Если мероприятие не состоялось, возврат делается по каждому счёту:

```
POST https://api.qut.kz/api/v1/invoices/{id}/refund
{ "reason": "мероприятие отменено" }
```

Порядок:

1. **Соберите список.** Через `GET /api/v1/invoices` или выгрузкой CSV из кабинета. Отберите счета в статусе `paid`.
2. **Сначала объявите.** Напишите участникам до начала возвратов, иначе поддержку завалит сообщениями.
3. **Делайте по одному.** Метода массового возврата нет, на каждый счёт отдельный запрос. Ставьте паузы, чтобы не упереться в ограничение частоты.
4. **Ведите протокол.** Записывайте, какие возвраты прошли, а какие упали.
5. **Пришёл `refund_unknown` — не повторяйте.** Сначала прочитайте состояние счёта, иначе можно вернуть дважды. Подробнее: [API возвратов](/kb/ru/refunds-api).

Если мероприятие переносится, чаще и проще объявить билеты действительными на новую дату, а не возвращать деньги.

## На что обратить внимание

- **Поздние оплаты.** Если деньги пришли после того, как счёт стал `expired`, событие придёт с признаком `late: true`. На входе это живой человек — пропустите его или сразу верните деньги.
- **Учтите суточную защиту.** В день старта продаж количество счетов резко подскакивает. Суточное число — не бизнес-лимит, а защита от зациклившейся интеграции, но упёршись в него вы получите ошибку `tariff_daily_burst`. Проверьте тариф заранее: [Какой тариф выбрать](/kb/ru/tariff-choose).
- **На входе нужен интернет.** Без сети счёт не создастся. Если Wi-Fi на площадке слабый, держите наготове второй телефон с мобильным интернетом.
- **Протестируйте заранее.** Не за день до мероприятия, а за неделю прогоните полный цикл в песочнице: [Как протестировать интеграцию](/kb/ru/testing-integration).
- **Деньги приходят напрямую на ваш счёт Kaspi**, у нас не задерживаются.

## Вопросы и ответы

**Кто выпускает сам билет?** Вы. Мы обрабатываем только оплату. Билет, его QR и проверку на входе делаете вы сами или через билетную систему.

**Если человек берёт два билета?** Выставьте один счёт: в `amount` общую сумму, в `metadata` список мест. Либо отдельный счёт на каждое место — так удобнее, если придётся возвращать деньги.

**Есть ли срок на возврат проданного билета?** Да, у возвратов свой срок. Билет, проданный давно, вернуть может не получиться: [API возвратов](/kb/ru/refunds-api).

**Нужен ли на входе сканер QR?** Для оплаты не нужен — гость сканирует своим телефоном. Для проверки билетов он может понадобиться вашей системе.

**Регистрация бесплатная, но много неявок. Что делать?** Берите символическую сумму (1 000-2 000 ₸) или используйте схему с залогом — возвращаете его при явке. Похожая схема: [Салон красоты и барбершоп](/kb/ru/for-beauty-salon).
