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

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

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

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

Опциональные параметры#

ПараметрТипОписание
requestAdditionsRequestAdditionsДополнительные параметры запроса

Структура RequestAdditions#

ПолеТипОбязательноОписание
corporateCodeCorporateCodeНетКорпоративный код скидки

Структура CorporateCode#

ПолеТипОбязательноОписание
codestringДаКод корпоративной скидки
carrierCodestringДаКод авиакомпании (IATA, 2 символа)
metadatamap<string, string>НетДополнительные системные метаданные (GDS/NDC)

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

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

1curl -X POST https://test.travel-api.ru/avia/pnr_reprice \
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 PnrRepriceRequest
 2{
 3    BookingId = "019a0b6e-47eb-7157-926e-80691497ebfc"
 4};
 5
 6var response = await httpClient.PostAsJsonAsync(
 7    "https://test.travel-api.ru/avia/pnr_reprice",
 8    request
 9);
10
11var result = await response.Content.ReadFromJsonAsync<PnrRepriceResponse>();

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

Перед выпиской билета#

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

 1var booking = await RetrieveBooking(bookingId);
 2var originalPrice = GetOriginalPrice(booking);
 3
 4// Получаем актуальную цену
 5var repricing = await RepriceBooking(bookingId);
 6var actualPrice = repricing.Pricings.Sum(p => p.Price.Total.Value);
 7
 8if (actualPrice != originalPrice)
 9{
10    Console.WriteLine($"Цена изменилась: {originalPrice} → {actualPrice}");
11
12    // Запрашиваем подтверждение пользователя
13    var confirmed = await AskUserConfirmation(
14        $"Цена изменилась с {originalPrice} на {actualPrice}. Продолжить?"
15    );
16
17    if (!confirmed)
18    {
19        return;
20    }
21}
22
23// Выписываем билет
24await IssueTicket(bookingId);

После длительного ожидания#

Если между бронированием и оплатой прошло много времени:

 1var booking = await RetrieveBooking(bookingId);
 2var createdAt = booking.CreatedAt;
 3var hoursSinceCreation = (DateTime.Now - createdAt).TotalHours;
 4
 5if (hoursSinceCreation > 4)
 6{
 7    // Проверяем актуальную цену
 8    var repricing = await RepriceBooking(bookingId);
 9    ShowPriceToUser(repricing);
10}

Периодическая проверка#

Для долго неоплаченных бронирований:

 1var pendingBookings = await GetPendingBookings();
 2
 3foreach (var booking in pendingBookings)
 4{
 5    try
 6    {
 7        var repricing = await RepriceBooking(booking.BookingId);
 8        var priceChanged = HasPriceChanged(booking, repricing);
 9
10        if (priceChanged)
11        {
12            await NotifyUser(booking.UserId,
13                "Цена вашего бронирования изменилась");
14        }
15    }
16    catch (Exception ex)
17    {
18        LogError($"Reprice failed for {booking.BookingId}: {ex.Message}");
19    }
20}

Отображение актуальной цены#

Когда пользователь просматривает детали бронирования:

 1public async Task<BookingDetailsViewModel> GetBookingDetails(string bookingId)
 2{
 3    var booking = await RetrieveBooking(bookingId);
 4    var repricing = await RepriceBooking(bookingId);
 5
 6    return new BookingDetailsViewModel
 7    {
 8        BookingId = bookingId,
 9        PnrLocator = booking.Pnr.PnrLocator,
10        OriginalPrice = GetOriginalPrice(booking),
11        CurrentPrice = repricing.Pricings.Sum(p => p.Price.Total.Value),
12        PriceChanged = HasPriceChanged(booking, repricing)
13    };
14}

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

Обязательная проверка перед выпиской#

Всегда выполняйте пересчет стоимости перед выпиской билета:

 1public async Task<TicketIssueResult> IssueTicketWithPriceCheck(string bookingId)
 2{
 3    // Шаг 1: Пересчитываем стоимость
 4    var repricing = await RepriceBooking(bookingId);
 5    var actualPrice = repricing.Pricings.Sum(p => p.Price.Total.Value);
 6
 7    // Шаг 2: Получаем исходную цену
 8    var booking = await RetrieveBooking(bookingId);
 9    var originalPrice = GetOriginalPrice(booking);
10
11    // Шаг 3: Сравниваем
12    if (actualPrice != originalPrice)
13    {
14        var difference = actualPrice - originalPrice;
15
16        if (difference > 0)
17        {
18            // Цена увеличилась - требуется подтверждение
19            var confirmed = await ConfirmPriceIncrease(actualPrice, difference);
20            if (!confirmed)
21            {
22                return TicketIssueResult.PriceChangedCancelled;
23            }
24        }
25        else
26        {
27            // Цена уменьшилась - информируем пользователя
28            await NotifyPriceDecrease(actualPrice, Math.Abs(difference));
29        }
30    }
31
32    // Шаг 4: Выписываем билет
33    return await IssueTicket(bookingId);
34}

Обработка изменения цены#

 1public async Task<PriceChangeResult> CheckPriceChange(string bookingId)
 2{
 3    var booking = await RetrieveBooking(bookingId);
 4    var repricing = await RepriceBooking(bookingId);
 5
 6    var originalTotal = GetOriginalPrice(booking);
 7    var actualTotal = repricing.Pricings.Sum(p => p.Price.Total.Value);
 8    var difference = actualTotal - originalTotal;
 9
10    if (difference == 0)
11    {
12        return new PriceChangeResult
13        {
14            Changed = false,
15            Message = "Цена не изменилась"
16        };
17    }
18
19    var percentChange = (difference / originalTotal) * 100;
20
21    return new PriceChangeResult
22    {
23        Changed = true,
24        OriginalPrice = originalTotal,
25        ActualPrice = actualTotal,
26        Difference = difference,
27        PercentChange = percentChange,
28        Message = difference > 0
29            ? $"Цена увеличилась на {difference:F2} ₽ ({percentChange:F1}%)"
30            : $"Цена уменьшилась на {Math.Abs(difference):F2} ₽ ({Math.Abs(percentChange):F1}%)"
31    };
32}

Кеширование результатов#

Кешируйте результаты пересчета стоимости на короткое время:

 1private readonly MemoryCache _repriceCache = new MemoryCache(
 2    new MemoryCacheOptions()
 3);
 4
 5public async Task<PnrRepriceResponse> RepriceBookingCached(string bookingId)
 6{
 7    var cacheKey = $"reprice_{bookingId}";
 8
 9    if (_repriceCache.TryGetValue(cacheKey, out PnrRepriceResponse cached))
10    {
11        return cached;
12    }
13
14    var result = await RepriceBooking(bookingId);
15
16    _repriceCache.Set(cacheKey, result, TimeSpan.FromMinutes(2));
17
18    return result;
19}

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

 1try
 2{
 3    var repricing = await RepriceBooking(bookingId);
 4    return repricing;
 5}
 6catch (ApiException ex) when (ex.Code == "BOOKING_NOT_FOUND")
 7{
 8    Console.WriteLine("Бронирование не найдено");
 9    return null;
10}
11catch (ApiException ex) when (ex.Code == "BOOKING_CANCELLED")
12{
13    Console.WriteLine("Бронирование отменено");
14    return null;
15}
16catch (ApiException ex) when (ex.Code == "REPRICING_NOT_AVAILABLE")
17{
18    Console.WriteLine("Пересчет стоимости недоступна, используйте текущую цену");
19    // Возвращаем цену из бронирования
20    var booking = await RetrieveBooking(bookingId);
21    return ConvertToRepricing(booking);
22}
23catch (Exception ex)
24{
25    Console.WriteLine($"Ошибка пересчета стоимости: {ex.Message}");
26    throw;
27}

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

Сценарий 1: Выписка с проверкой цены#

  1. Пользователь готов оплатить
  2. Выполняете пересчет стоимости
  3. Сравниваете с исходной ценой
  4. Если изменилась — показываете новую цену
  5. Пользователь подтверждает
  6. Выписываете билет
sequenceDiagram
    participant User
    participant Client
    participant API
    participant GDS

    User->>Client: Готов оплатить

    Client->>API: POST /avia/pnr_reprice<br/>{bookingId}
    API->>GDS: Пересчитать стоимость
    GDS-->>API: Актуальная цена
    API-->>Client: pricings[]

    Client->>Client: Сравнить с исходной ценой<br/>Исходная: 10000₽<br/>Актуальная: 12000₽

    alt Цена изменилась
        Client->>User: Цена увеличилась<br/>на 2000₽<br/>Продолжить?

        alt Пользователь согласен
            Client->>API: POST /avia/ticket_issue<br/>{bookingId, payment}
            API->>GDS: Выписать билеты
            GDS-->>API: Билеты выписаны
            API-->>Client: ticketDocuments[]
            Client->>User: Билеты выписаны<br/>Стоимость: 12000₽
        else Пользователь отказался
            Client->>User: Выписка отменена
        end
    else Цена не изменилась
        Client->>API: POST /avia/ticket_issue<br/>{bookingId, payment}
        API-->>Client: Билеты выписаны
    end

Сценарий 2: Мониторинг цен#

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

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

        loop Для каждого bookingId
            Scheduler->>API: POST /avia/pnr_reprice<br/>{bookingId}
            API->>GDS: Пересчитать стоимость
            GDS-->>API: Актуальная цена
            API-->>Scheduler: pricings[]

            Scheduler->>Database: Получить исходную цену
            Database-->>Scheduler: originalPrice

            alt Цена изменилась
                Scheduler->>Database: Логировать изменение<br/>цены
                Scheduler->>NotificationService: Отправить уведомление<br/>пользователю
                Note over NotificationService: Email/Push:<br/>"Цена изменилась<br/>с 10000₽ на 12000₽"
            end
        end
    end

Сценарий 3: Отображение деталей#

  1. Пользователь открывает детали бронирования
  2. Система запрашивает пересчет стоимости
  3. Отображает актуальную цену
  4. Показывает разницу с исходной ценой
  5. Предлагает оплатить или отменить
sequenceDiagram
    participant User
    participant Client
    participant API
    participant GDS
    participant Cache

    User->>Client: Открыть детали бронирования

    Client->>Cache: Проверить кеш<br/>пересчета стоимости
    Cache-->>Client: Нет данных или устарело

    Client->>API: POST /avia/pnr_reprice<br/>{bookingId}
    API->>GDS: Пересчитать стоимость
    GDS-->>API: Актуальная цена
    API-->>Client: pricings[]

    Client->>Cache: Сохранить результат<br/>на 2 минуты

    Client->>User: Показать детали:<br/>Исходная цена: 10000₽<br/>Актуальная цена: 10500₽<br/>Разница: +500₽

    alt Пользователь выбирает оплатить
        Client->>API: POST /avia/ticket_issue
        API-->>Client: Билеты выписаны
    else Пользователь выбирает отменить
        Client->>API: POST /avia/pnr_cancel
        API-->>Client: Бронирование отменено
    end

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

Время актуальности#

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

  • Рекомендуется повторять перед каждой выпиской
  • Кешировать не более 2-5 минут
  • При изменении условий перевозчика результаты могут устареть

Не все бронирования поддерживают пересчет стоимости#

Некоторые типы тарифов или перевозчики могут не поддерживать пересчет стоимости. В этом случае используйте цену из бронирования.

Изменения могут быть значительными#

В периоды высокого спроса или при изменении топливных сборов цена может измениться существенно. Всегда информируйте пользователя.

Валюта ответа#

Валюта в ответе может отличаться от валюты исходного бронирования в зависимости от настроек офиса продаж.