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За дебъгване в емулатор трябва да се включи режимът на пясъчник (sandbox); за целта добавяме файла 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
Картата се добавя чрез заявка (request) в 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 или друга, общо 12, както и доставчикът на токена – 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 метода, малко по-горе описах най-сложния от тях.