Розробка мобільного застосунку для транспорту: вузькі місця
Розклад і оплата в застосунку для транспорту живуть в одному зв'язку, і ламається він найчастіше на стику. Перевізники віддають дані про рейси з різною періодичністю і у своїх форматах: один оновлює вивантаження раз на добу, інший надсилає зміни лише за фактом скасування.
Пасажир бачить автобус на карті, приходить на зупинку, а рейсу немає — і це вже не помилка даних, а підірвана довіра до мобільного застосунку перевізника.
Окрема категорія — збої оплати проїзду. Запит іде в платіжний шлюз, відповідь не повертається: зв'язок зник у тунелі, в оператора зависла транзакція.
Поки момент списання і момент підтвердження не розділені, пасажир або платить двічі, або їде без квитка, а перевізник отримує розбіжність у звітності та чергу розглядів у підтримці.
Пікові години добивають картину. На посадці десятки пристроїв одночасно намагаються перевірити квиток онлайн, канал на зупинці перевантажений, валідація займає секунди — черга зростає, водій втрачає час на маршруті.
Вирішує тут не потужність сервера, а те, що перевірка має проходити локально, а синхронізація — уже потім, коли зв'язок повернеться.
Розбираємо, як це закривається: де ставимо локальний кеш і чергу відкладених операцій, як робимо повтор платежу безпечним і як віддаємо перевізнику актуальний розклад без ручних правок.
Що змінюється після впровадження: ефект у цифрах і строках
Ефект упровадження застосунку вимірюється чотирма величинами: частка успішних оплат, розбіжність факту з розкладом, кількість звернень до підтримки, час реакції на збій. До запуску їх якщо й рахували, то вручну за журналами диспетчера, і оцінка залишалася розмовною.
Ми підключаємо метрики до того самого збору даних, що й застосунок, — цифри перевіряються і після здачі.
Частка успішних оплат перестає залежати від якості зв'язку: транзакція спочатку фіксується на пристрої, а потім досилається після відновлення каналу, тому списання не губляться на перегонах і в підземних переходах.
Проїзд підтверджується заздалегідь збереженим квитком, а звіряння з білінгом іде тлом — пасажир не чекає відповіді сервера біля турнікета. На маршрутах із щільним потоком це прибирає основну причину повторних проходів і спірних ситуацій із контролером.
Стабільність розкладу тримається на даних бортових систем, які надходять автоматично, а ручний ввід диспетчера залишається лише резервом. Розбіжність факту з планом скорочується до десятків секунд, прогноз прибуття перераховується кожні кілька зупинок, а не раз за зміну. Пасажир бачить актуальний час, перевізник — відхилення за конкретними рейсами.
Зниження звернень до підтримки відбувається завдяки тому, що типові питання закриваються всередині застосунку: статус оплати, місцезнаходження транспорту, історія поїздок, повернення. Оператори займаються складними випадками замість повторення одного й того ж телефоном.
Час реакції на збій скорочується, бо сигнал надходить зсередини системи: падіння частки успішних оплат або зростання розбіжності видно раніше, ніж почнуть телефонувати пасажири.
Заміри знімаються до запуску і через місяць роботи на тих самих маршрутах — на прийманні видно, що саме змінилося, а що потребує доопрацювання.
Способи реалізації: готове рішення, платформа, замовне складання
Вибір підходу визначається одним питанням: наскільки логіка перевезення відрізняється від типової.
Якщо розклад надходить із наявної диспетчерської системи, тариф один, а маршрути стабільні, писати все з нуля немає сенсу — готове рішення для транспорту закриває такі сценарії відразу.
Щойно з'являються зональні тарифи, пересадкові квитки, пільгові категорії або оплата за фактичним пробігом, шаблон починає заважати: кожна зміна впирається в обмеження чужої моделі даних.
Тут працює платформна розробка — типове ядро з картами, оплатою, особистими кабінетами й повідомленнями плюс налаштування процесів під перевізника. Замовна розробка застосунку виправдана, коли правила перевезення і є продуктом.
Порівняння підходів
| Варіант | Коли підходить | Обмеження |
|---|---|---|
| Готове галузеве рішення | Типові маршрути, один тариф, розклад із наявної системи | Нестандартну логіку доводиться обходити, доопрацювання залежать від постачальника |
| Платформне складання | Свої тарифи, зони, пільги, але без унікальної логіки перевезення | Межі налаштування скінченні, глибока переробка ядра недоступна |
| Замовна розробка | Логіка перевезення — конкурентна перевага: динамічні тарифи, мультимодальність, свої правила | Довше перша версія, підтримка силами своєї команди |
На практиці підхід рідко буває чистим: стартують на платформі, а унікальні вузли дописують окремо. Ми дивимося на тарифну модель, поточну диспетчерську систему й плани на два-три роки: якщо правила змінюються частіше ніж раз на квартал, закладаємо запас на доопрацювання.
Етапи роботи: від аудиту даних до передачі в підтримку
Починаємо не з макетів, а з даних: розклад, тарифи й правила оплати в кожного перевізника живуть у своєму вигляді — таблиці, вивантаження з диспетчерської системи, іноді регламенти на папері.
Поки джерела не розібрані, будь-який екран будується на здогадках і розходиться з реальністю вже на першій зміні. Нижче — етапи, які проходить проєкт.
- Аудит даних перевізника. Зводимо розклад, зупинки, тарифи й пільги в одну модель, позначаємо, де дані запізнюються, дублюються або надходять лише від диспетчера. На виході — карта джерел із частотою оновлення та відповідальним за кожен.
- Схема інтеграцій. Вирішуємо, що застосунок забирає напряму, а що — через проміжний шар із локальною копією даних. Шар закриває недоступність системи перевізника: розклад і статуси рейсів залишаються в застосунку, навіть коли зовнішній сервіс мовчить.
- Налаштування оплати. Розводимо сценарії: разовий квиток, проїзний, пільговий проїзд, повернення в разі скасування рейсу. Окремо описуємо обрив зв'язку в момент списання і те, як операція доводиться до кінця під час наступного запуску.
- Перевірка під навантаженням. Прогоняємо ранковий пік і годину масових скасувань: одночасні оновлення розкладу, покупки на одному маршруті, сплеск звернень до підтримки.
- Пілот на одному маршруті або парку. Звіряємо дані застосунку з фактичним виходом машин і ловимо розбіжності до релізу на все місто.
- Передача в підтримку. Конфігурації, схеми інтеграцій, регламент оновлення розкладу, порядок відкату й ескалації, черговий доступ до систем спостереження за сервісом.
Що передаємо на руки: схеми, доступи й регламенти
Передача проєкту — це не архів із вихідними кодами, а пакет, за яким ваша команда або інший підрядник випускає реліз без нас. Склад фіксуємо в чек-лісті приймання: за кожним пунктом на підсумковій зустрічі запускаємо демонстрацію на чистому середовищі, а не показуємо слайди. Нижче — що саме залишається в замовника.
- Схеми інтеграцій — як застосунок обмінюється даними із системою розкладу (включно з форматом GTFS), платіжним шлюзом і валідаторами: послідовність викликів, черги, повтор при збої, обмеження за частотою запитів.
- Опис моделей даних — словник сутностей маршрут, рейс, зупинка, поїздка, платіж, їхні зв'язки, правила зберігання історії та порядок міграцій у разі зміни структури.
- Політики доступу й ролі — хто і що може в панелі адміністратора та в сховищах, де лежать ключі, строк їх ротації, розділення середовищ розробки, тестування й промислового.
- Регламент оновлень — порядок випуску версії: які перевірки обов'язкові, як формується збірка, як публікується в магазинах застосунків, що відбувається під час відкату до попередньої.
- Регламент чергування й реакції — рівні збоїв, час реакції на кожен, канали оповіщення, хто ухвалює рішення про відкат і за якими ознаками.
- Документація застосунку — архітектурна схема, інструкція з локального запуску, перелік змінних середовища, відомі обмеження й технічний борг із пріоритетами.
- Інструкція із супроводу — як оновлювати розклад, додавати маршрути, змінювати тексти й тарифні правила без випуску нової версії застосунку.
Кожен пункт вважається переданим лише після того, як ваші фахівці відтворили його самі. Спільно проходимо приймання, відповідаємо на запитання й залишаємося на зв'язку в період супроводу.
Розбір упровадження: розклад і оплата в сервісі транспорту
Сервіс пасажирських перевезень прийшов із двома пов'язаними проблемами: розклад у застосунку розходився з фактичним рухом, а частина оплат не доходила до підтвердження.
Пасажир чекав транспорт «за розкладом», платив і залишався без проїзного документа — кожне таке звернення підтримка розбирала вручну.
Що було до переробки
Розклад оновлювався одним пакетом раз на добу: у разі затримки або скасування рейсу даних про зміну не надходило, і застосунок показував план замість факту.
Платіж списувався на стороні провайдера, але відповідь до застосунку не доходила — операція залишалася в невизначеному стані, а звіряння робили вивантаженням раз на день, тому завислі оплати знаходили постфактум.
Що змінили і що вийшло
Розклад перевели на точкові оновлення з локальним кешем: застосунок зберігає актуальний зріз і працює без мережі.
Платежі зробили повторюваними — повторний запит не створює друге списання, стан операції відновлюється під час повернення в застосунок, а автоматичне звіряння закриває розбіжності в межах короткого інтервалу.
- розбіжність розкладу: 18% звернень → 3%
- завислі платежі: 6% операцій → 0,4%
- строк закриття спірної оплати: доба → хвилини
- навантаження на першу лінію підтримки: −42%
Метрики підтверджені двома джерелами: звітом із навантаження на підтримку Оператора міських перевезень і технічним аудитом інтегратора платіжного шлюзу.
Що робити, якщо розклад і оплата вже в іншому сервісі?
Якщо розклад і оплата вже живуть в іншому сервісі, переносити потрібно не «застосунок», а весь контур: збірки й підписи, облікові записи в магазинах, платіжний шлюз, потоки даних про маршрути. Починаємо з інвентаризації: що за що відповідає, де ключі й у кого доступи. Без цього кроку міграція перетворюється на роботу навпомацки.
Дані переносимо окремо, бо природа в них різна. Розклади й геометрія маршрутів вивантажуються у відкритому форматі GTFS — його читає будь-яка система планування, тому втрат під час перенесення немає.
Токени банківських карток не переносяться: вони залишаються в платіжного провайдера, ми переносимо ідентифікатори транзакцій і звіряємо реєстр — платежі, повернення, незакриті сесії оплати.
Простій для зупинки продажів не потрібен.
Обидва контури якийсь час працюють паралельно: новий приймає дзеркальний потік, звіряння йде за кожною операцією, а перемикання робиться частками через керований перемикач у збірці — спочатку частина користувачів, потім половина, потім усі. Відкат — повернути частку на нуль, старий сервіс на цей момент ще повністю працездатний.
Зміна підрядника підтримки — окремий ризик. Передаємо проєкт цілком: репозиторій з історією, ключі підпису збірок через захищений канал, облікові записи розробника на власника, документацію за контрактами обміну.
Приймання технічне: збираємо реліз із переданих вихідних кодів, він проходить перевірки магазину, а тестова оплата закривається.
На практиці це означає: розклад і оплата переїжджають без зупинки продажів, а у власника залишаються ключі, доступи й зрозумілий регламент випуску.
Технічні сумніви: офлайн, навантаження, оновлення
Нижче — питання, які найчастіше виникають, коли застосунок для транспорту вже несе розклад і оплату. Відповідаємо по суті: що саме відбувається за слабкого зв'язку, як поводиться система в пік і що можна змінювати без нової збірки.
Що відбувається з оплатою за нестабільного зв'язку?
Оплата не впирається в екран «немає мережі». Операція лягає в локальну чергу з ідентифікатором поїздки, а пасажир бачить статус «в обробці». Коли зв'язок повертається, черга йде на сервер, повторні надсилання гасяться за тим самим ідентифікатором — подвійного списання не виникає.
Офлайн-режим застосунку зберігає розклад і останні проїзні, тому валідатор і екран поїздки працюють без мережі.
Чи витримає застосунок різке зростання кількості поїздок?
Навантаження на застосунок розведене: розклад і тарифи віддаються з локального кеша, до сервера йдуть лише платежі та статуси. Пік ранкових годин і масовий вхід після збою обробляються однаково — спочатку фіксуємо операцію, потім звіряємо її з провайдером.
Ємність перевіряємо навантажувальними прогонами за профілем ваших маршрутів, а не за середніми цифрами.
Чи можна оновити тарифи без випуску нової версії?
Так — правила оплати, зони й знижки живуть у серверній конфігурації, застосунок підтягує й кешує її під час запуску. Оновлення без випуску версії займає хвилини, відкат — це повернення попереднього набору правил.
Схему конфігурації версіонуємо: старі збірки не ламаються, бо продовжують читати сумісний набір полів.
Обговоримо задачу: що потрібно для старту робіт
Старт робіт починається не з договору, а з розбору задачі: що точніші вхідні дані замовника, то менше допущень в оцінці проєкту і то рідше план упровадження переписується на середині. Нижче — що достатньо підготувати, щоб обговорення йшло по суті, а не загальними словами.
- Транспортна модель: види транспорту, кількість маршрутів, зупинок і рейсів, сезонні та вихідні варіанти розкладу.
- Джерело розкладу: диспетчерська система, регулярне вивантаження або ручні правки — і хто відповідає за актуальність даних.
- Тарифи й квитки: зони, пільги, проїзні, разові поїздки, правила пересадок і повернень.
- Платіжні сценарії: оплата карткою, гаманцем, кодом на валідаторі або в салоні; як оформлюються повернення й скасування.
- Стан інтеграцій: еквайринг, квиткова система, постачальник валідаторів — чи є документація й тестовий контур для перевірки оплат.
- Робота без мережі: що має відкриватися офлайн — збережений квиток, історія поїздок, відкладене підтвердження оплати.
- Обмеження й орієнтири: платформи, географія, мови, вимоги до персональних даних і точки, де потрібен пілотний запуск на одному маршруті.
За підсумками розбору ми повертаємося з оцінкою й планом етапів: межі першої версії, порядок підключення інтеграцій, ролі на стороні замовника й точки контролю. Далі ви вирішуєте, чи починати роботи — обговорення задачі ні до чого не зобов'язує щодо строків.







