Параметры запроса#
Детальное описание всех параметров для запроса /avia/pnr_reprice.
Обязательные параметры#
| Параметр | Тип | Описание |
|---|---|---|
bookingId | guid | Идентификатор бронирования для пересчета стоимости (формат UUID) |
Опциональные параметры#
| Параметр | Тип | Описание |
|---|---|---|
requestAdditions | RequestAdditions | Дополнительные параметры запроса |
Структура RequestAdditions#
| Поле | Тип | Обязательно | Описание |
|---|---|---|---|
corporateCode | CorporateCode | Нет | Корпоративный код скидки |
Структура CorporateCode#
| Поле | Тип | Обязательно | Описание |
|---|---|---|---|
code | string | Да | Код корпоративной скидки |
carrierCode | string | Да | Код авиакомпании (IATA, 2 символа) |
metadata | map<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: Выписка с проверкой цены#
- Пользователь готов оплатить
- Выполняете пересчет стоимости
- Сравниваете с исходной ценой
- Если изменилась — показываете новую цену
- Пользователь подтверждает
- Выписываете билет
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: Мониторинг цен#
- Система периодически проверяет неоплаченные бронирования
- Выполняет пересчет стоимости для каждого
- Обнаруживает изменения цен
- Отправляет уведомления пользователям
- Логирует изменения
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: Отображение деталей#
- Пользователь открывает детали бронирования
- Система запрашивает пересчет стоимости
- Отображает актуальную цену
- Показывает разницу с исходной ценой
- Предлагает оплатить или отменить
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 минут
- При изменении условий перевозчика результаты могут устареть
Не все бронирования поддерживают пересчет стоимости#
Некоторые типы тарифов или перевозчики могут не поддерживать пересчет стоимости. В этом случае используйте цену из бронирования.
Изменения могут быть значительными#
В периоды высокого спроса или при изменении топливных сборов цена может измениться существенно. Всегда информируйте пользователя.
Валюта ответа#
Валюта в ответе может отличаться от валюты исходного бронирования в зависимости от настроек офиса продаж.