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 у ваш додаток. Ми гарантуємо коректну роботу з першого релізу.







