Интеграция Google Wallet для пропусков в мобильном приложении

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

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

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

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

Услуги, которые мы предлагаем
Показано 1 из 1Все 1735 услуг
Интеграция Google Wallet для пропусков в мобильном приложении
Средний
от 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

Интеграция Google Wallet для пропусков в мобильном приложении

Пропуск в Google Wallet — это GenericObject поверх GenericClass. Generic — универсальный тип для всего, что не является билетом, посадочным талоном или купоном: пропуск на парковку, членская карта, карта лояльности, абонемент, рабочий бейдж. В API это самый гибкий тип: структура полей задаётся произвольно через textModulesData, linksModuleData и imageModulesData.

Структура GenericObject

def create_access_pass(class_id: str, holder_name: str,
                        pass_id: str, access_level: str) -> dict:
    issuer_id = "YOUR_ISSUER_ID"

    return {
        "id": f"{issuer_id}.pass_{pass_id}",
        "classId": class_id,
        "state": "ACTIVE",
        "cardTitle": {
            "defaultValue": {"language": "ru", "value": "Пропуск сотрудника"}
        },
        "subheader": {
            "defaultValue": {"language": "ru", "value": "Уровень доступа"}
        },
        "header": {
            "defaultValue": {"language": "ru", "value": access_level}  # "A1 — все зоны"
        },
        "textModulesData": [
            {
                "header": "Владелец",
                "body": holder_name,
                "id": "holder"
            },
            {
                "header": "ID пропуска",
                "body": pass_id,
                "id": "pass_id"
            },
            {
                "header": "Действителен до",
                "body": "31.12.2024",
                "id": "valid_until"
            }
        ],
        "barcode": {
            "type": "QR_CODE",
            "value": pass_id,
            "alternateText": pass_id[:8].upper()
        },
        "heroImage": {
            "sourceUri": {
                "uri": "https://yourcompany.com/office-photo.jpg"
            }
        },
        "validTimeInterval": {
            "start": {"date": "2024-01-01T00:00:00Z"},
            "end": {"date": "2024-12-31T23:59:59Z"}
        },
        "notifications": {
            "expiryNotification": {
                "enableNotification": True
            }
        }
    }

notifications.expiryNotification — Google Wallet автоматически уведомит пользователя за 3 дня до истечения пропуска. Никакой дополнительной серверной логики не требуется.

GenericClass: минимальная конфигурация

def create_generic_class(class_suffix: str) -> dict:
    issuer_id = "YOUR_ISSUER_ID"

    return {
        "id": f"{issuer_id}.{class_suffix}",
        "issuerName": "Your Company",
        "reviewStatus": "UNDER_REVIEW",
        "enableSmartTap": False,  # True только если есть NFC-ридеры
        "multipleDevicesAndHoldersAllowedStatus": "ONE_USER_ONE_DEVICE"
    }

ONE_USER_ONE_DEVICE — пропуск нельзя передать другому пользователю или сохранить на нескольких устройствах одного аккаунта. Для корпоративных пропусков это правильное ограничение.

Создание класса через REST API перед первым JWT

Класс нужно создать один раз через API — в JWT можно только встраивать объект, класс через JWT не создаётся:

from googleapiclient.discovery import build
from google.oauth2 import service_account

def ensure_generic_class_exists(class_data: dict) -> bool:
    creds = service_account.Credentials.from_service_account_file(
        'service-account.json',
        scopes=['https://www.googleapis.com/auth/wallet_object.issuer']
    )
    service = build('walletobjects', 'v1', credentials=creds)

    try:
        service.genericclass().get(resourceId=class_data["id"]).execute()
        return True  # уже существует
    except HttpError as e:
        if e.resp.status == 404:
            service.genericclass().insert(body=class_data).execute()
            return True
    return False

Android: полный flow

class PassActivity : AppCompatActivity() {
    private val walletClient by lazy {
        Wallet.getWalletClient(this, WalletOptions.Builder()
            .setEnvironment(WalletConstants.ENVIRONMENT_PRODUCTION)
            .build())
    }

    private val savePassLauncher = registerForActivityResult(
        ActivityResultContracts.StartIntentSenderForResult()
    ) { result ->
        when (result.resultCode) {
            RESULT_OK -> {
                analytics.track("wallet_pass_added")
                binding.addToWalletBtn.text = "Уже в Wallet"
                binding.addToWalletBtn.isEnabled = false
            }
            RESULT_CANCELED -> Unit
        }
    }

    fun onAddToWalletClicked() {
        viewModel.generatePassJwt().observe(this) { jwt ->
            walletClient.savePassesViaIntent(
                SavePassesRequest.newBuilder().setJwt(jwt).build()
            ) { result ->
                result.intentSender?.let {
                    savePassLauncher.launch(IntentSenderRequest.Builder(it).build())
                } ?: run {
                    // Уже добавлен
                    binding.addToWalletBtn.isEnabled = false
                }
            }
        }
    }
}

Обновление пропуска (смена уровня доступа)

def update_pass_access_level(object_id: str, new_level: str):
    service = build('walletobjects', 'v1', credentials=creds)
    service.genericobject().patch(
        resourceId=object_id,
        body={
            "header": {
                "defaultValue": {"language": "ru", "value": new_level}
            }
        }
    ).execute()

Изменения отображаются в Wallet пользователя в течение нескольких минут — без переиздания пропуска.

Сроки

1–3 дня. Базовый пропуск с QR-кодом и автоуведомлением об истечении — 1,5 дня. Обновления через API + ограничения на перенос между устройствами — 2–3 дня. Стоимость рассчитывается индивидуально.