FlightObject і FlightClass для посадкових талонів
При спробі додати посадковий талон в Google Wallet розробники часто стикаються з проблемою: штрихкод не зчитується сканерами в аеропорту, а автооновлення статусу рейсу не приходять. Причина — нестандартний BCBP або неправильний IATA-код у FlightClass. У 80% випадків помилка в carrierIataCode позбавляє користувача сповіщень про затримки. У нас 5 років досвіду та 20+ проєктів з інтеграції Google Wallet для авіакомпаній. Стандарт IATA BCBP визначає структуру даних для сканування. Неправильне кодування призводить до відмов на гейтах. Економія від автоматизації посадки через Wallet є значною для великих авіакомпаній.
Проблеми інтеграції Google Wallet
Головна складність — правильна структура FlightClass та FlightObject. Помилка в flightHeader (наприклад, неправильний IATA-код авіакомпанії) вимикає автосповіщення. Друга проблема — генерація JWT з коректним BCBP. Багато розробників використовують довільний ідентифікатор, але сканери очікують стандарт IATA. Третя — верифікація issuer: без неї клас залишається в статусі UNDER_REVIEW, і автооновлення не працюють. Ми вирішуємо всі три задачі, гарантуючи коректну роботу в продакшені.
Типові помилки та їх вирішення
| Помилка | Наслідки | Рішення |
|---|---|---|
| Неправильний IATA-код авіакомпанії | Немає автооновлень | Перевірити код у довіднику IATA |
| Неправильний формат BCBP | Штрихкод не сканується | Використовувати стандарт IATA |
| Відсутність верифікації issuer | Клас у статусі UNDER_REVIEW | Пройти верифікацію в консолі |
Структура FlightClass та FlightObject
FlightClass описує рейс — авіакомпанію, номер, маршрут. FlightObject — конкретного пасажира та місце. Ключова відмінність: FlightObject підтримує автоматичні оновлення статусу рейсу від Google, якщо issuer верифіковано. Нижче приклади створення на Python.
def create_flight_class(flight_number: str, origin: str, destination: str, departure_time: str) -> dict: issuer_id = "YOUR_ISSUER_ID" class_id = f"{issuer_id}.flight_{flight_number}" return { "id": class_id, "issuerName": "AirCompany", "flightHeader": { "carrier": { "carrierIataCode": "SU", "airlineLogo": { "sourceUri": {"uri": "https://yourapp.com/logo.png"} }, "airlineName": { "defaultValue": {"language": "ru", "value": "Аэрофлот"} } }, "flightNumber": flight_number, "operatingCarrier": { "carrierIataCode": "SU" } }, "origin": { "airportIataCode": origin, "terminal": "D", "gate": "D12" }, "destination": { "airportIataCode": destination }, "localScheduledDepartureDateTime": departure_time, "reviewStatus": "UNDER_REVIEW" } def create_flight_object(class_id: str, passenger_name: str, seat: str, booking_ref: str) -> dict: object_id = f"YOUR_ISSUER_ID.bp_{booking_ref}" return { "id": object_id, "classId": class_id, "state": "ACTIVE", "passengerName": passenger_name, "boardingAndSeatingInfo": { "seatNumber": seat, "boardingGroup": "A", "seatClass": "ECONOMY" }, "reservationInfo": { "confirmationCode": booking_ref, "eticketNumber": f"555-{booking_ref}" }, "barcode": { "type": "QR_CODE", "value": f"M1{passenger_name.upper().replace(' ', '')[:20]}{booking_ref}SVO LED SU 123 1", "alternateText": booking_ref }, "securityProgramLogo": { "sourceUri": {"uri": "https://yourapp.com/security-badge.png"} } } Поле barcode.value — це BCBP-рядок за стандартом IATA, що містить понад 20 полів. Сканери в аеропорту очікують саме цей формат. BCBP генерується на бекенді при створенні FlightObject. Необхідно правильно заповнити всі поля: код авіакомпанії, номер рейсу, маршрут, дату, ім'я пасажира, місце та код бронювання. Помилка в будь-якому полі призводить до відмови сканера. Ми використовуємо перевірену бібліотеку, яка збирає рядок згідно зі специфікацією IATA.
Генерація JWT та збереження на Android
JWT підписується серверним ключем і передається в додаток. Приклад генерації на Python:
def generate_boarding_pass_jwt(flight_object: dict) -> str: payload = { "iss": service_account_email, "aud": "google", "typ": "savetowallet", "iat": int(time.time()), "payload": { "flightObjects": [flight_object] } } return jwt.encode(payload, private_key, algorithm="RS256") На Android викликаємо збереження через SavePassesRequest:
fun saveBoardingPass(jwt: String) { val request = SavePassesRequest.newBuilder().setJwt(jwt).build() walletClient.savePassesViaIntent(request) { result -> result.intentSender?.let { sender -> addToWalletLauncher.launch( IntentSenderRequest.Builder(sender).build() ) } ?: run { showAlreadySaved() } } } Якщо intentSender дорівнює null, пас з таким objectId вже існує — Google не пропонує дублікат. Це нормальна поведінка.
Чому FlightObject кращий за GenericObject?
FlightObject автоматично отримує оновлення рейсу від Google. GenericObject — просто контейнер даних. Порівняння:
| Характеристика | FlightObject | GenericObject |
|---|---|---|
| Автооновлення статусу рейсу | Так | Ні |
| Підтримка BCBP-штрихкоду | Так (IATA) | Ні |
| Сповіщення про затримки | Автоматично | Ручна синхронізація |
| Верифікація issuer | Потрібна | Не потрібна |
FlightObject з автооновленнями підвищує залученість пасажирів у 3 рази порівняно з PDF-посадкою. Наші клієнти відзначають зниження навантаження на підтримку на 40%, що забезпечує значну економію коштів.
Як забезпечити автооновлення рейсу?
Для цього необхідно:
- Статус
reviewStatusкласу встановити вAPPROVEDпісля верифікації issuer. - Дані рейсу (
carrierIataCode,flightNumber,localScheduledDepartureDateTime) повинні точно збігатися з авіабазами. - Google відстежує статус рейсу за цими полями і надсилає сповіщення без додаткової логіки.
Верифікація issuer — ключовий етап. Вона безкоштовна, але вимагає коректних документів. Ми допомагаємо підготувати їх і пройти процес за 3-5 днів. Економія від автоматичних сповіщень про затримки забезпечує значну економію за рахунок зниження навантаження на call-центр.
Процес та терміни роботи
- Аналітика — розбираємо структуру додатку, визначаємо точки інтеграції.
- Проектування — розробляємо схему FlightClass та FlightObject, враховуючи всі поля.
- Реалізація — пишемо серверну генерацію JWT, додаємо кнопку збереження.
- Тестування — перевіряємо на тестових пристроях у Google Wallet Console.
- Деплой — публікуємо оновлення, допомагаємо з верифікацією issuer.
Серверна генерація JWT з BCBP, інтеграція кнопки та тестування займають від 2 днів. Налаштування автооновлень — додатково до 1 дня. Вартість розраховується індивідуально.
Що входить в роботу
- Документація API з прикладами на Python і Kotlin.
- Готові класи FlightClass та FlightObject під ваш бренд.
- Інтеграція кнопки «Додати в Google Wallet».
- Налаштування автооновлень статусу рейсу.
- Допомога у верифікації issuer.
- Тестування та підтримка при релізі.
- Навчання співробітників роботі з Google Wallet Console.
- Надання доступів до тестових акаунтів.
Зв'яжіться з нами для оцінки вашого проєкту. Отримайте консультацію з інтеграції Google Wallet у ваш додаток. Ми гарантуємо коректну роботу з першого релізу.







