Структура ответа#

Детальное описание структуры ответа от /avia/pnr_reprice.

Основная структура#

Ответ содержит актуальную тарификацию бронирования.

ПолеТипОписание
pricingsarrayМассив тарификаций по типам пассажиров

Структура Pricing#

ПолеТипОписание
paxTypestringТип пассажира (adt, chd, inf)
priceobjectЦеновая информация
segmentsarrayДетали по сегментам
fareTypestringТип тарифа (public, private, etc.)
validatingCarrierstringВалидирующий перевозчик

Структура Price#

ПолеТипОписание
totalobjectПолная стоимость
baseFareobjectБазовый тариф
taxesobjectТаксы и сборы

Структура Amount#

ПолеТипОписание
currencyCodestringКод валюты (ISO 4217)
valuenumberСумма

Структура Taxes#

ПолеТипОписание
totalobjectОбщая сумма такс
breakdownarrayДетализация по кодам такс

Структура TaxBreakdown#

ПолеТипОписание
codestringКод таксы/сбора
amountobjectСумма

Структура Segment#

ПолеТипОписание
segRefIdstringИдентификатор сегмента из бронирования
flightobjectИнформация о рейсе
originobjectПункт отправления
destinationobjectПункт прибытия
fareBasisstringКод базового тарифа
cabinstringКласс обслуживания
classstringКод бронирования (RBD)
baggageAllowanceobjectНорма багажа

Структура Flight#

ПолеТипОписание
carrierCodestringКод перевозчика
flightNumberstringНомер рейса

Структура Location (Origin/Destination)#

ПолеТипОписание
locationobjectИнформация о локации
dateTimestringДата и время (ISO 8601)

Структура Location.location#

ПолеТипОписание
codestringКод аэропорта
codeTypestringТип кода (iata, icao)
typestringТип локации (airport, city)

Структура BaggageAllowance#

ПолеТипОписание
typestringТип багажа (carryOn, checked)
pieceAllowanceobjectНорма по количеству мест
weightAllowanceobjectНорма по весу

Примеры ответов#

Успешный ответ#

 1{
 2  "pricings": [
 3    {
 4      "paxType": "adt",
 5      "price": {
 6        "baseFare": {
 7          "currencyCode": "RUB",
 8          "value": 8950
 9        },
10        "taxes": {
11          "total": {
12            "currencyCode": "RUB",
13            "value": 537
14          },
15          "breakdown": [
16            {
17              "code": "YR",
18              "amount": {
19                "currencyCode": "RUB",
20                "value": 120
21              }
22            },
23            {
24              "code": "RI",
25              "amount": {
26                "currencyCode": "RUB",
27                "value": 417
28              }
29            }
30          ]
31        },
32        "total": {
33          "currencyCode": "RUB",
34          "value": 9487
35        }
36      },
37      "segments": [
38        {
39          "baggageAllowance": {
40            "type": "carryOn",
41            "pieceAllowance": {
42              "totalPieces": 1
43            }
44          },
45          "cabin": "economy",
46          "class": "R",
47          "destination": {
48            "location": {
49              "code": "KZN",
50              "codeType": "iata",
51              "type": "airport"
52            },
53            "dateTime": "2025-11-21T23:40:00"
54          },
55          "fareBasis": "RCOR",
56          "flight": {
57            "carrierCode": "SU",
58            "flightNumber": "1278"
59          },
60          "origin": {
61            "location": {
62              "code": "SVO",
63              "codeType": "iata",
64              "type": "airport"
65            },
66            "dateTime": "2025-11-21T21:55:00"
67          },
68          "segRefId": "2c2dbf78-da30-46bd-9e18-a1f9f8e7fec7"
69        }
70      ],
71      "fareType": "public",
72      "validatingCarrier": "SU"
73    }
74  ]
75}

Бронирование с несколькими пассажирами#

 1{
 2  "pricings": [
 3    {
 4      "paxType": "adt",
 5      "price": {
 6        "total": {
 7          "currencyCode": "RUB",
 8          "value": 9487
 9        }
10      }
11    },
12    {
13      "paxType": "chd",
14      "price": {
15        "total": {
16          "currencyCode": "RUB",
17          "value": 7115
18        }
19      }
20    },
21    {
22      "paxType": "inf",
23      "price": {
24        "total": {
25          "currencyCode": "RUB",
26          "value": 949
27        }
28      }
29    }
30  ]
31}

Ответ с ошибкой#

1{
2  "error": {
3    "code": "BOOKING_NOT_FOUND",
4    "message": "Бронирование не найдено",
5    "description": "Бронирование с указанным ID не существует",
6    "errorId": "018c5f2e-9b3a-7f4d-8e2c-1a2b3c4d5e6f"
7  }
8}

Использование данных#

Расчет общей стоимости#

 1var repricing = await RepriceBooking(bookingId);
 2var booking = await RetrieveBooking(bookingId);
 3
 4var totalPrice = 0m;
 5
 6foreach (var pricing in repricing.Pricings)
 7{
 8    // Подсчитываем количество пассажиров этого типа
 9    var passengerCount = booking.Pnr.Passengers
10        .Count(p => p.Type == pricing.PaxType);
11
12    // Добавляем к общей сумме
13    totalPrice += pricing.Price.Total.Value * passengerCount;
14}
15
16Console.WriteLine($"Общая стоимость: {totalPrice} RUB");

Сравнение с исходной ценой#

 1var repricing = await RepriceBooking(bookingId);
 2var booking = await RetrieveBooking(bookingId);
 3
 4var originalPrice = booking.Pnr.FareInfo.Fares
 5    .Sum(f => f.Price.Total.Value);
 6
 7var actualPrice = repricing.Pricings
 8    .Sum(p => p.Price.Total.Value);
 9
10if (actualPrice > originalPrice)
11{
12    var increase = actualPrice - originalPrice;
13    Console.WriteLine($"Цена увеличилась на {increase} RUB");
14}
15else if (actualPrice < originalPrice)
16{
17    var decrease = originalPrice - actualPrice;
18    Console.WriteLine($"Цена уменьшилась на {decrease} RUB");
19}
20else
21{
22    Console.WriteLine("Цена не изменилась");
23}

детализация по таксам#

 1var pricing = repricing.Pricings[0];
 2
 3Console.WriteLine($"Базовый тариф: {pricing.Price.BaseFare.Value} {pricing.Price.BaseFare.CurrencyCode}");
 4Console.WriteLine("Таксы и сборы:");
 5
 6foreach (var tax in pricing.Price.Taxes.Breakdown)
 7{
 8    Console.WriteLine($"  {tax.Code}: {tax.Amount.Value} {tax.Amount.CurrencyCode}");
 9}
10
11Console.WriteLine($"Итого таксы: {pricing.Price.Taxes.Total.Value} {pricing.Price.Taxes.Total.CurrencyCode}");
12Console.WriteLine($"ВСЕГО: {pricing.Price.Total.Value} {pricing.Price.Total.CurrencyCode}");

Проверка изменения тарифа#

 1var repricing = await RepriceBooking(bookingId);
 2var booking = await RetrieveBooking(bookingId);
 3
 4foreach (var pricing in repricing.Pricings)
 5{
 6    var originalFare = booking.Pnr.FareInfo.Fares
 7        .FirstOrDefault(f => f.PaxType == pricing.PaxType);
 8
 9    if (originalFare == null) continue;
10
11    foreach (var segment in pricing.Segments)
12    {
13        var originalSegment = originalFare.Itinerary
14            .FirstOrDefault(s => s.SegRefId == segment.SegRefId);
15
16        if (originalSegment?.FareBasis != segment.FareBasis)
17        {
18            Console.WriteLine($"Изменился код тарифа для сегмента {segment.SegRefId}:");
19            Console.WriteLine($"  Было: {originalSegment?.FareBasis}");
20            Console.WriteLine($"  Стало: {segment.FareBasis}");
21        }
22    }
23}

Формирование отчета об изменениях#

 1public class PriceChangeReport
 2{
 3    public string BookingId { get; set; }
 4    public decimal OriginalPrice { get; set; }
 5    public decimal ActualPrice { get; set; }
 6    public decimal Difference { get; set; }
 7    public List<PriceChangeDetail> Details { get; set; }
 8}
 9
10public async Task<PriceChangeReport> GeneratePriceChangeReport(string bookingId)
11{
12    var repricing = await RepriceBooking(bookingId);
13    var booking = await RetrieveBooking(bookingId);
14
15    var report = new PriceChangeReport
16    {
17        BookingId = bookingId,
18        Details = new List<PriceChangeDetail>()
19    };
20
21    foreach (var pricing in repricing.Pricings)
22    {
23        var originalFare = booking.Pnr.FareInfo.Fares
24            .FirstOrDefault(f => f.PaxType == pricing.PaxType);
25
26        if (originalFare != null)
27        {
28            var originalPrice = originalFare.Price.Total.Value;
29            var actualPrice = pricing.Price.Total.Value;
30
31            report.Details.Add(new PriceChangeDetail
32            {
33                PassengerType = pricing.PaxType,
34                OriginalPrice = originalPrice,
35                ActualPrice = actualPrice,
36                Difference = actualPrice - originalPrice
37            });
38
39            report.OriginalPrice += originalPrice;
40            report.ActualPrice += actualPrice;
41        }
42    }
43
44    report.Difference = report.ActualPrice - report.OriginalPrice;
45
46    return report;
47}

Уведомление пользователя об изменении#

 1public async Task NotifyPriceChangeIfNeeded(string bookingId)
 2{
 3    var repricing = await RepriceBooking(bookingId);
 4    var booking = await RetrieveBooking(bookingId);
 5
 6    var originalPrice = GetTotalPrice(booking);
 7    var actualPrice = GetTotalPrice(repricing);
 8
 9    if (actualPrice != originalPrice)
10    {
11        var difference = actualPrice - originalPrice;
12        var percentChange = (difference / originalPrice) * 100;
13
14        var message = difference > 0
15            ? $"Цена вашего бронирования {booking.Pnr.PnrLocator} увеличилась на {difference:F2} ₽ ({percentChange:F1}%)"
16            : $"Цена вашего бронирования {booking.Pnr.PnrLocator} уменьшилась на {Math.Abs(difference):F2} ₽ ({Math.Abs(percentChange):F1}%)";
17
18        await SendNotification(booking.UserId, message);
19    }
20}

Типичные ошибки#

Код ошибкиПричинаРешение
BOOKING_NOT_FOUNDБронирование не найденоПроверьте bookingId
BOOKING_CANCELLEDБронирование отмененоСоздайте новое
REPRICING_NOT_AVAILABLEПересчет стоимости недоступенИспользуйте текущую цену
INVALID_BOOKING_IDНекорректный IDПроверьте формат

Связанные операции#