Android Push Provisioning API
Невелика стаття про Android Push Provisioning API- яке необхідне для взаємодії банківського застосунку та Google Pay.
У мережі практично немає інформації у відкритому доступі, оскільки штука доволі специфічна, й інформація від Google відкрита лише для співробітників фінансових установ- емітентів карток
https://support.google.com/google-pay-and-wallet-console/answer/15157842?hl=en
Якщо ви вважаєте, що у вас має бути доступ до цієї інформації, ви можете його запросити
https://developers.google.com/pay/issuers/request-access
Встановлення та налаштування
Подробиці реалізації не можна згадувати, тому напишу в загальних рисах
Спочатку в gradle потрібно додати залежність tapAndPay, також завантажити за вказаним вище посиланням tapAndPay SDK і помістити його в папку
C:\Users\\AppData\Local\Android\Sdk\extras\googleДля налагодження в емуляторі потрібно увімкнути режим пісочниці, для цього додаємо файл android_pay_env_override_sandbox у папку завантажень на пристрої
$ adb shell touch /sdcard/Download/android_pay_env_override_sandbox$ adb rebootперед adb не забуваємо ставити шлях до нього, якщо папку не обрано
для MacOS ~/Library/Android/sdk/platform-tools/adbдля Windows C:\Users\\AppData\Local\Android\Sdk\platform-tools\adbвимкнути режим пісочниці можна, видаливши файл
$ adb shell rm /sdcard/Download/android_pay_env_override_sandbox$ adb rebootДодавання застосунку в whitelist
Потрібно додати застосунок до списку дозволених, оскільки Google дозволяє доступ до Push Provisioning API лише афілійованим фінансовим установам. Отже, щоб застосунок емітента картки міг викликати API, застосунку має бути наданий доступ до API. Зробити це можна тут
https://support.google.com/faqs/contact/pp_api_allowlist?hl=en
Якщо застосунок не додано до дозволених, API видаватиме помилку TAP_AND_PAY_UNAVAILABLE. Якщо використовуються суфікси applicationIdSuffix, потрібно додати пакет і з ними, щоб працювало.
Google Pay виконує перевірку автентифікації при виклику через API. Ця перевірка не вдасться, якщо пристрій має привілеї root.
Вимоги до UI
Для роботи потрібно додати UI, тут є особливість у тому, що кнопка для додавання картки та логотип Google Pay на зображенні картки й інших кнопках, пов'язаних з Google Pay, мають точно відповідати дизайну Google, інакше не пройде модерацію.
Напис Google Pay не має бути скорочений, має бути англійською, на сторінці мануалу наводяться правильні переклади для кнопки "Додати в Google Pay"
Усі кнопки налаштування Google Pay повинні мати ширину не менше 139 dp, завжди має бути не менше 8 dp вільного простору зверху, знизу, ліворуч і праворуч від кнопки Google Pay, не розміщуйте графіку або текст у вільному просторі.
Як загалом працює Google Pay можна почитати тут
https://developers.google.cn/android/guides/overview?hl=ru
Додавання картки в Google Pay
Картка додається через реквест у tapAndPay клієнті, в якому спочатку потрібно заповнити дані користувача- ім'я, країна, адреса, квартира, місто, область, поштовий індекс і телефон, якщо все це не задати в реквесті, користувач муситиме ввести це в застосунку Google Pay під час додавання.
Після цього в реквесті потрібно вказати Opaque Payment Card — це зашифровані об'єкти, створені емітентом картки та передані в Google Pay під час ініціалізації. Кожен постачальник послуг токенів (TSP) має власні специфікації для форматування OPC і методи шифрування для емітентів карток.
OPC можна згенерувати, виконавши такі дії.
Обміняйтеся ключами з TSP. Ці ключі використовуються для шифрування та дешифрування OPC.
Створіть і зашифруйте OPC відповідно до документації TSP.
Працюйте з TSP, щоб переконатися, що OPC дійсний і правильно зашифрований.
OPC, який передається в Google, має бути рядком у кодуванні Base64. Якщо TSP відхиляє OPC з будь-якої причини, Google Pay покаже користувачеві повідомлення про загальну помилку.
Також вказується тип банківської мережі- Visa, Mastercard або інша, усього їх 7, і також провайдера токена- Visa, Mastercard та інші, усього їх 10, усі вони знаходяться як константи в класі клієнта, також необхідні назва картки та останні 4 цифри номера картки. При натисканні “додати картку” реквест надсилатиметься в Google Pay, а користувач- перенаправлятиметься в застосунок Google Pay, якщо він встановлений, а якщо ні- потрібно додати відповідну логіку для встановлення з Play Market.
Робота з гаманцем та обробка помилок
Для операцій з гаманцем потрібен параметр TokenReferenceId і StableHardwareId- з назв у принципі зрозуміло, що це.
Щоб були зрозумілі статуси та помилки при роботі з api під час виведення в консоль, зручно зробити функцію з розшифруванням констант помилок і статусів, я зробив це так
private fun logResult(pair: Pair<Boolean, String>) { if (pair.first) { logd(pair.second, "GooglePay") } else { loge(pair.second, "GooglePay") }}
private fun walletStatus(statusCode: Int) = when (statusCode) { TapAndPayStatusCodes.TAP_AND_PAY_NO_ACTIVE_WALLET -> false to "No active wallet" TapAndPayStatusCodes.TAP_AND_PAY_TOKEN_NOT_FOUND -> false to "card issuer token ID presented does not match the token in the valid wallet" TapAndPayStatusCodes.TAP_AND_PAY_INVALID_TOKEN_STATE -> false to "Specified token was found but could not be processed because it was not in a valid state" TapAndPayStatusCodes.TAP_AND_PAY_ATTESTATION_ERROR -> false to "Tokenization failed because the device did not pass the compatibility check" TapAndPayStatusCodes.TAP_AND_PAY_UNAVAILABLE -> false to "TapAndPay API cannot be called in the current app" else -> false to "wallet status code $statusCode"}
private fun tokenStatus(statusCode: Int) = when (statusCode) { TapAndPay.TOKEN_STATE_NEEDS_IDENTITY_VERIFICATION -> false to "The token is in a valid wallet, but requires additional user authentication to use (step up authentication required)" TapAndPay.TOKEN_STATE_PENDING -> false to "Currently, tokens cannot be used for payment, but after a while they will be available" TapAndPay.TOKEN_STATE_SUSPENDED -> false to "The token has been temporarily suspended" TapAndPay.TOKEN_STATE_ACTIVE -> true to "The token is valid and can be used for payment" TapAndPay.TOKEN_STATE_FELICA_PENDING_PROVISIONING -> false to "The token is issued by TSP, but Felica has not been provisioned yet" TapAndPay.TOKEN_STATE_UNTOKENIZED -> false to "This state does not apply to push provisioning" else -> false to "token status code $statusCode"}loge і logd у цьому прикладі просто обробляють повідомлення та виводять, якщо BuildConfig.DEBUG, а “GooglePay” це таг для пошуку в logcat
Константи та додаткові методи
Для зручності можна додати класи для констант провайдера токена та мережі
enum class TokenProvider(val value: Int) { MASTERCARD(3), VISA(4), DISCOVER(5), EFTPOS(6), INTERAC(7), OBERTHUR(8), PAYPAL(9), JCB(13), ELO(14), GEMALTO(15)}
enum class CardNetwork(val value: Int) { AMEX(1), DISCOVER(2), MASTERCARD(3), VISA(4), INTERAC(5), PRIVATE_LABEL(6), EFTPOS(7), MAESTRO(8), ID(9), QUICPAY(10), JCB(11), ELO(12)}У версії API 17.1.0 додано метод listTokens, завдяки якому можна отримати деяку інформацію про додані картки, а саме
IssuerTokenIdFpanLastFourDpanLastFourTokenServiceProviderNetworkIsDefaultTokenPortfolioNameСхожим чином через tapAndPay клієнт здійснюються й інші дії з карткою- усього в його інтерфейсі 15 методів, трохи вище описав найскладніший з них.