Параметры запроса#

Детальное описание всех параметров для запроса /avia/pnr_cancel.

Обязательные параметры#

ПараметрТипОписание
bookingIdguidИдентификатор бронирования для отмены (формат UUID)

Примеры запросов#

Минимальный запрос#

1curl -X POST https://test.travel-api.ru/avia/pnr_cancel \
2  -H "Authorization: Bearer YOUR_TOKEN" \
3  -H "Content-Type: application/json" \
4  -d '{
5    "bookingId": "019a0b6e-47eb-7157-926e-80691497ebfc"
6  }'
 1var request = new PnrCancelRequest
 2{
 3    BookingId = "019a0b6e-47eb-7157-926e-80691497ebfc"
 4};
 5
 6var response = await httpClient.PostAsJsonAsync(
 7    "https://test.travel-api.ru/avia/pnr_cancel",
 8    request
 9);
10
11if (response.IsSuccessStatusCode)
12{
13    Console.WriteLine("Бронирование успешно отменено");
14}

Когда использовать#

Истечение срока оплаты#

Автоматически отменяйте бронирования, если пассажир не оплатил в срок:

1var booking = await RetrieveBooking(bookingId);
2
3// Проверяем timeLimit из данных создания бронирования
4if (DateTime.Now > timeLimit && booking.Pnr.Tickets.Count == 0)
5{
6    await CancelBooking(bookingId);
7    Console.WriteLine("Бронирование отменено по истечении срока оплаты");
8}

Отказ пассажира#

Когда пассажир явно отказывается от бронирования:

1var userConfirmed = await AskUserConfirmation(
2    "Вы действительно хотите отменить бронирование?"
3);
4
5if (userConfirmed)
6{
7    await CancelBooking(bookingId);
8    Console.WriteLine("Бронирование отменено по запросу пассажира");
9}

Ошибочное бронирование#

Если при создании бронирования были допущены критические ошибки:

 1try
 2{
 3    var booking = await CreateBooking(request);
 4    var details = await RetrieveBooking(booking.BookingId);
 5
 6    if (HasCriticalErrors(details))
 7    {
 8        await CancelBooking(booking.BookingId);
 9        return await CreateBooking(correctedRequest);
10    }
11}
12catch (Exception ex)
13{
14    // Обработка ошибки
15}

Освобождение мест#

Периодическая очистка неоплаченных бронирований:

 1var expiredBookings = await GetExpiredBookings();
 2
 3foreach (var bookingId in expiredBookings)
 4{
 5    try
 6    {
 7        await CancelBooking(bookingId);
 8        Console.WriteLine($"Отменено бронирование: {bookingId}");
 9    }
10    catch (ApiException ex)
11    {
12        LogError($"Ошибка отмены {bookingId}: {ex.Message}");
13    }
14}

Рекомендации#

Проверка перед отменой#

Всегда проверяйте статус бронирования перед отменой:

 1var booking = await RetrieveBooking(bookingId);
 2
 3if (booking.Pnr.Cancelled)
 4{
 5    Console.WriteLine("Бронирование уже отменено");
 6    return;
 7}
 8
 9if (booking.Pnr.Tickets.Any())
10{
11    Console.WriteLine("Билеты выписаны, используйте процедуру возврата");
12    return;
13}
14
15// Можно отменять
16await CancelBooking(bookingId);

Информирование пользователя#

Предупреждайте пользователя о последствиях отмены:

Внимание!
После отмены бронирования:
- Места будут освобождены
- Восстановление может быть невозможно
- Для нового бронирования потребуется повторный поиск

Продолжить отмену?
[Да] [Нет]

Обработка ошибок#

 1try
 2{
 3    await CancelBooking(bookingId);
 4    Console.WriteLine("Бронирование успешно отменено");
 5}
 6catch (ApiException ex) when (ex.Code == "BOOKING_NOT_FOUND")
 7{
 8    Console.WriteLine("Бронирование не найдено");
 9}
10catch (ApiException ex) when (ex.Code == "BOOKING_ALREADY_CANCELLED")
11{
12    Console.WriteLine("Бронирование уже отменено");
13}
14catch (ApiException ex) when (ex.Code == "TICKETS_ISSUED")
15{
16    Console.WriteLine("Билеты выписаны. Используйте процедуру возврата билетов");
17}
18catch (ApiException ex) when (ex.Code == "CANCELLATION_NOT_ALLOWED")
19{
20    Console.WriteLine("Отмена запрещена перевозчиком");
21}
22catch (ApiException ex)
23{
24    Console.WriteLine($"Ошибка отмены: {ex.Message}");
25}

Логирование#

Всегда логируйте операции отмены для аудита:

1await LogCancellation(new
2{
3    BookingId = bookingId,
4    CancelledAt = DateTime.UtcNow,
5    CancelledBy = currentUser.Id,
6    Reason = cancellationReason
7});
8
9await CancelBooking(bookingId);

Уведомления#

Отправляйте уведомления пассажиру об отмене:

1await CancelBooking(bookingId);
2
3await SendCancellationNotification(
4    email: passengerEmail,
5    bookingId: bookingId,
6    pnrLocator: pnrLocator
7);

Типичные сценарии#

Сценарий 1: Отказ пассажира#

  1. Пассажир нажимает “Отменить бронирование”
  2. Показываете предупреждение
  3. Пассажир подтверждает
  4. Отменяете бронирование
  5. Показываете подтверждение отмены
sequenceDiagram
    participant User
    participant Client
    participant API
    participant GDS

    User->>Client: Нажать "Отменить бронирование"

    Client->>User: Показать предупреждение:<br/>"Места будут освобождены.<br/>Восстановление невозможно.<br/>Продолжить?"

    User->>Client: Подтвердить отмену

    Client->>API: POST /avia/pnr_cancel<br/>{bookingId}
    API->>GDS: Отменить бронирование
    GDS-->>API: Бронирование отменено
    API-->>Client: HTTP 200

    Client->>User: Показать:<br/>"Бронирование отменено.<br/>Места освобождены."

Сценарий 2: Истечение срока#

  1. Система проверяет неоплаченные бронирования
  2. Находит просроченные
  3. Автоматически отменяет
  4. Отправляет уведомление пассажиру
  5. Логирует операцию
sequenceDiagram
    participant Scheduler
    participant Client
    participant API
    participant GDS
    participant Database
    participant NotificationService

    loop Каждые 1 час
        Scheduler->>Database: Получить неоплаченные<br/>бронирования
        Database-->>Scheduler: bookingIds[]

        loop Для каждого bookingId
            Scheduler->>API: POST /avia/pnr_retrieve<br/>{bookingId}
            API-->>Scheduler: booking (timeLimit, status)

            Scheduler->>Scheduler: Проверить timeLimit

            alt timeLimit истек
                Scheduler->>API: POST /avia/pnr_cancel<br/>{bookingId}
                API->>GDS: Отменить бронирование
                GDS-->>API: Отменено
                API-->>Scheduler: HTTP 200

                Scheduler->>Database: Логировать:<br/>bookingId, cancelledAt,<br/>reason: "EXPIRED"

                Scheduler->>NotificationService: Отправить email:<br/>"Бронирование отменено<br/>по истечении срока"

                Note over Scheduler: Места освобождены
            end
        end
    end

Сценарий 3: Исправление ошибки#

  1. Пользователь заметил ошибку в данных
  2. Отменяете текущее бронирование
  3. Создаете новое с правильными данными
  4. Информируете пользователя о замене
sequenceDiagram
    participant User
    participant Client
    participant API
    participant GDS

    Note over User: Обнаружена ошибка<br/>в данных бронирования

    User->>Client: Заметил ошибку в имени

    Client->>API: POST /avia/pnr_cancel<br/>{bookingId: старое_бронирование}
    API->>GDS: Отменить ошибочное<br/>бронирование
    GDS-->>API: Отменено
    API-->>Client: Старое бронирование отменено

    Client->>API: POST /avia/pnr_create<br/>{исправленные данные}
    API->>GDS: Создать новое бронирование
    GDS-->>API: newBookingId
    API-->>Client: Новое бронирование создано

    Client->>User: Информировать:<br/>"Бронирование пересоздано<br/>с правильными данными.<br/>Новый PNR: ABC123"

    Note over Client: Цена может измениться!<br/>Проверить через pnr_reprice

Важные замечания#

Необратимость операции#

Отмена бронирования обычно необнеобратима. После отмены:

  • Восстановить бронирование нельзя
  • Нужно создавать новое бронирование
  • Цена может измениться
  • Места могут быть заняты

Разница между отменой и возвратом#

  • Отмена бронирования — для невыписанных билетов
  • Возврат билета — для уже оформленных билетов

Сроки отмены#

Некоторые перевозчики могут иметь ограничения:

  • Нельзя отменить за N часов до вылета
  • Нельзя отменить после начала регистрации
  • Нельзя отменить после вылета первого сегмента

Групповые бронирования#

Для групповых бронирований могут быть особые правила отмены.