Repository navigation
Conversation
|
Any update on when this could potentially be implemented? Thanks! |
Skalakid
marked this pull request as ready for review
August 21, 2026 06:47
|
+1 |
Contributor
Author
…e-UAPP # Conflicts: # android/src/main/java/com/expensify/wallet/WalletModule.kt
This was referenced Sep 29, 2026
# Conflicts: # android/src/main/java/com/expensify/wallet/WalletModule.kt # src/index.tsx
mountiny
self-requested a review
October 12, 2026 12:45
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Important
Per Google docs, all apps using TSP-only integration must upgrade by the end of 2026.
Details
Upgrades the Android integration to Google's Unified Android Push Provisioning (UAPP), following the official guide. Google requires apps with a TSP-only integration to upgrade by the end of 2026.
addCardToGoogleWalletuses the Task-basedpushTokenize(request)with aPaymentCredentialsGenerator. Google only calls the generator when it needs credentials. If Google doesn't request a Google OPC, the TSP OPC fromcardDatais returned immediately. Otherwise the library emitsonPaymentCredentialsRequest, and the JS handler fetches the credentials from the issuer backend.requestId,serverSessionId,walletId,tokenRequestorIdand the TSP OPC, and must return both the TSP OPC and the Google OPC.tokenRequestorIdidentifies the tokenization target; for Visa on Fitbit the TSP OPC has to include it.AndroidRejectPaymentCredentials. A 60s native timeout fails requests that never get an answer, andinvalidate()fails anything still pending, so Google is never left waiting. Every failure reaches Google asGeneratePaymentCredentialsException(UNKNOWN_ERROR), the only documented way to report it. Google doesn't guarantee a TSP-only fallback, so a failed request means the card is not added.PushTokenizeResult. A card counts as added whencardResultis true or anyTokenizationOutcome.tokenResultis true. The token ID comes from the successful outcome, otherwisenull. Google's guide also documents the result as separate extras (EXTRA_TOKEN_RESULT,EXTRA_CARD_RESULT,EXTRA_ISSUER_TOKEN_ID), so those are read when the object is missing. When there is neither, the outcome matches Fix push tokenization promise never settling in onActivityResult #70:RESULT_OKresolvessuccess, any other code resolveserror.resumeAddCardToGoogleWalletusestokenize(activity, TokenizeRequest, code)(the documented way to resume a yellow path token) with its own request code, so its legacy result format (EXTRA_ISSUER_TOKEN_ID) is handled separately.listTokensandgetTokenStatusmove to their request variants (ListTokensRequest,GetTokenStatusRequest). The only deprecated calls left areenvironmentandstableHardwareId, which have no documented replacement.hasEligibleTokenizationTarget(last4Digits, network, issuerName)(Android only). Google recommends it for the "Add to Google Wallet" button when wearables are supported, because a card already on the phone can still be added to a watch.AndroidCardDatagets optionalisVirtualCardandisBounceProvisioned.Breaking changes (should ship as a minor release, see the note below):
PaymentCredentialsGenerator,PushTokenizeResult). Tested with 18.10.1. Older SDKs such as 17.1.0 will not compile.addCardToGoogleWallet(cardData, handlePaymentCredentials)now requires the handler.onCardActivatedtokenIdis typedtokenId?: string | null. It can benullwhen Google saves the card without a token ID, and it is missing from the iOScanceledevent.Release note: the publish workflow always runs
npm version patch, so this PR sets the version to0.2.0-0, which publishes as0.2.0instead of0.1.x.Related Issues
#58
Manual Tests
Tested on a physical Android device against the real Google Wallet flow, plus a harness covering every result and credentials path.
Physical Android (moto g84 5G, Android 15, Google Wallet, GMS 26.37.37, debug build, TapAndPay SDK 18.10.1):
addCardToGoogleWalletwith the example's dummy card data. Verify that Google Wallet opens "Add payment card".canceledandonCardActivatedfires withstatus: "canceled".addCardToGoogleWalletagain. Verify that Google Wallet opens again (no "A tokenization request is already in progress").success, andonCardActivatedfires withstatus: "activated"and the issuer token ID. If Google asks for a Google OPC, verify that the payment credentials handler is called and its result is used.canceledand nothing hangs.Simulated on the same device (temporary harness calling
onActivityResultand the generator directly):successwith that token IDsuccess,tokenId: nullRESULT_OKwith no data or no result: resolvessuccesserrorcanceledEXTRA_ISSUER_TOKEN_IDresolvessuccesswith that token ID. No data resolvessuccess, an unknown code resolveserror.After the device run: the Google exception reporting, the required Google OPC, the separate result extras, the request-variant migration and
hasEligibleTokenizationTargetwere verified with typecheck, lint and a Kotlin compile against SDK 18.10.1. These paths can only be exercised end to end from an allowlisted app with a real Google OPC.iOS: the example app builds on both new and old arch with the stubs for the payment credentials methods. The
hasEligibleTokenizationTargetstub follows the same pattern but hasn't been rebuilt.Linked PRs
The Expensify/App bump (TapAndPay SDK 18.10.1 + payment credentials handler) will follow in a separate PR.