Разработка мобильного приложения для электронного билета (Digital Ticket)

TRUETECH занимается разработкой, поддержкой и обслуживанием мобильных приложений iOS, Android, PWA. Имеем большой опыт и экспертизу для публикации мобильных приложений в популярные маркеты Google Play, App Store, Amazon, AppGallery и другие.

Разработка и поддержка любых видов мобильных приложений:

Информационные и развлекательные мобильные приложения
Новостные приложения, игры, справочники, онлайн-каталоги, погодные, фитнес и здоровье, туристические, образовательные, социальные сети и мессенджеры, квиз, блоги и подкасты, форумы, агрегаторы
Мобильные приложения электронной коммерции
Интернет-магазины, B2B-приложения, маркетплейсы, онлайн-обменники, кэшбэк-сервисы, биржи, дропшиппинг-платформы, программы лояльности, доставка еды и товаров, платежные системы
Мобильные приложения для управления бизнес-процессами
CRM-системы, ERP-системы, управление проектами, инструменты для команды продаж, учет финансов, управление производством, логистика и доставка, управление персоналом, системы мониторинга данных
Мобильные приложения электронных услуг
Доски объявлений, онлайн-школы, онлайн-кинотеатры, платформы предоставления электронных услуг, платформы кешбека, видеохостинги, тематические порталы, платформы онлайн-бронирования и записи, платформы онлайн-торговли

Это лишь некоторые из типы мобильных приложений, с которыми мы работаем, и каждый из них может иметь свои специфические особенности и функциональность, а также быть адаптированным под конкретные потребности и цели клиента.

Услуги, которые мы предлагаем
Показано 1 из 1Все 1735 услуг
Разработка мобильного приложения для электронного билета (Digital Ticket)
Средний
от 1 недели до 3 месяцев
Часто задаваемые вопросы

Наши компетенции:

Этапы разработки

Последние работы

  • image_mobile-applications_feedme_467_0.webp
    Разработка мобильного приложения для компании FEEDME
    792
  • image_mobile-applications_xoomer_471_0.webp
    Разработка мобильного приложения для компании XOOMER
    671
  • image_mobile-applications_rhl_428_0.webp
    Разработка мобильного приложения для компании RHL
    1097
  • image_mobile-applications_zippy_411_0.webp
    Разработка мобильного приложения для компании ZIPPY
    969
  • image_mobile-applications_affhome_429_0.webp
    Разработка мобильного приложения для компании Affhome
    914
  • image_mobile-applications_flavors_409_0.webp
    Разработка мобильного приложения для компании FLAVORS
    495

Разработка мобильного приложения для электронного билета (Digital Ticket)

Электронный билет — это не просто PDF с QR-кодом в виде файла. Современный Digital Ticket — это живой объект: он обновляется при переносе мероприятия, показывает схему зала, позволяет зайти через NFC или Wallet, и валидируется сканером без интернета на стороне контролёра.

Форматы хранения и передачи билета

Приложение должно поддерживать несколько каналов хранения:

In-app storage — билет хранится в приложении как объект в базе (Core Data / Room), QR генерируется на лету из ticketToken. Требует интернета для первой загрузки.

Apple Wallet / Google Wallet — добавляется через PKAddPassesViewController или Google Pay SDK. Доступен без интернета, обновляется через push. Покрывается отдельной интеграцией.

PDF — генерируется на сервере (PDFKit/wkhtmltopdf), скачивается пользователем. Используется как резервный вариант.

Для большинства приложений делаем все три — пользователь сам выбирает удобный вариант.

Генерация и валидация QR

QR-код должен содержать не просто номер заказа, а подписанный токен — иначе его можно подделать, скопировав изображение экрана.

Схема: сервер генерирует ticketToken = HMAC-SHA256(ticketId + userId + expiresAt, secret). Контролёр сканирует QR → приложение контролёра отправляет токен на POST /tickets/validate → сервер проверяет HMAC и статус использования.

import hmac, hashlib, time

def generate_ticket_token(ticket_id: str, user_id: str, secret: str) -> str:
    expires_at = int(time.time()) + 86400 * 30  # действителен 30 дней
    message = f"{ticket_id}:{user_id}:{expires_at}"
    signature = hmac.new(
        secret.encode(), message.encode(), hashlib.sha256
    ).hexdigest()
    return f"{message}:{signature}"

def validate_ticket_token(token: str, secret: str) -> dict:
    parts = token.split(":")
    if len(parts) != 4:
        return {"valid": False, "reason": "malformed_token"}

    ticket_id, user_id, expires_at, signature = parts
    expected = hmac.new(
        secret.encode(),
        f"{ticket_id}:{user_id}:{expires_at}".encode(),
        hashlib.sha256
    ).hexdigest()

    if not hmac.compare_digest(signature, expected):
        return {"valid": False, "reason": "invalid_signature"}

    if int(expires_at) < int(time.time()):
        return {"valid": False, "reason": "expired"}

    return {"valid": True, "ticketId": ticket_id, "userId": user_id}

Для событий с высоким риском перепродажи используют rotating QR — токен меняется каждые 30–60 секунд (TOTP-логика). Скриншот немедленно устаревает.

Оффлайн-валидация

Контролёр на входе может быть без интернета. Два подхода:

Оффлайн-список — приложение контролёра загружает список валидных ticketId заранее (например, за час до начала). Сканирует QR, проверяет по локальному списку. Риск: нельзя пометить билет как использованный до синхронизации.

Цифровая подпись без сервера — контролёр верифицирует HMAC с публичным ключом, встроенным в приложение. При этом PAN не хранится, а только публичный ключ. Отозвать отдельный билет оффлайн нельзя — только черный список, загружаемый заранее.

Схема зала и выбор мест

Если мероприятие предполагает нумерованные места — нужна интерактивная схема зала. Реализуется через SVG или кастомный Canvas. На React Native удобен react-native-svg, на Flutter — CustomPainter.

// Flutter: кастомный painter для рядов кресел
class SeatMapPainter extends CustomPainter {
  final List<Seat> seats;
  final Set<String> selectedSeats;

  @override
  void paint(Canvas canvas, Size size) {
    for (final seat in seats) {
      final paint = Paint()
        ..color = selectedSeats.contains(seat.id)
            ? Colors.blue
            : seat.isAvailable ? Colors.green : Colors.grey;

      canvas.drawRRect(
        RRect.fromRectAndRadius(
          Rect.fromLTWH(seat.x, seat.y, 28, 24),
          const Radius.circular(4),
        ),
        paint,
      );
    }
  }

  @override
  bool shouldRepaint(SeatMapPainter oldDelegate) =>
      oldDelegate.selectedSeats != selectedSeats;
}

Схема загружается как JSON с координатами каждого кресла. При масштабировании зала используем InteractiveViewer (Flutter) или UIPinchGestureRecognizer + CATransform3D (iOS).

Возврат и перенос

Логика возврата билета — на сервере. Приложение отображает статус: ACTIVE, USED, REFUNDED, TRANSFERRED. При переносе мероприятия сервер отправляет push → приложение обновляет данные билета.

Важный edge case: билет должен оставаться видимым даже после USED — пользователь хочет видеть историю посещений.

Ориентиры по срокам

Базовая версия (in-app QR, покупка, история): 4–6 недель. Добавление схемы зала с выбором мест — ещё 2–3 недели. Wallet-интеграция (Apple / Google) — ещё 3–5 дней. Стоимость рассчитывается индивидуально.