Skip to content

Conversation

dbracamonte
Copy link

@dbracamonte dbracamonte commented Aug 29, 2025

This PR introduces new features to integrate the Google Pay yellow path flow, allowing users to resume adding cards to Google Wallet and managing existing tokens. This is essential to comply with Google Pay requirements.

Summary

  • Add resumeAddCardToGoogleWallet() method for resuming card provisioning using existing token reference ID
  • Add listTokens() method to retrieve all tokens stored in Google Wallet
  • Add new TypeScript types: AndroidResumeCardData and TokenInfo
  • Update README.md with comprehensive documentation for the new methods

Changes Made

Android Native (Kotlin)

  • WalletModule.kt: Added resumeAddCardToGoogleWallet and listTokens methods with proper error handling
  • NativeWalletSpec.java: Added method signatures for the new functionality

TypeScript/React Native

  • NativeWallet.ts: Added new types and method signatures to the TurboModule spec
  • index.tsx: Implemented JavaScript wrapper functions with proper platform checks and error handling

Documentation

  • README.md: Updated API reference table, data types section, and function count

Features

resumeAddCardToGoogleWallet(cardData: AndroidResumeCardData)

  • Resumes card provisioning flow using an existing tokenReferenceId
  • Simplified data structure compared to full card provisioning
  • Supports optional cardholder name and last digits for display purposes
  • Returns TokenizationStatus to track the operation result

listTokens()

  • Retrieves all tokens currently stored in Google Wallet
  • Returns array of TokenInfo objects containing:
    • tokenReferenceId: Unique token identifier
    • fpanLastFour: Last four digits of the tokenized card
    • tokenState: Current state of the token (numeric value)
  • Handles empty results gracefully

- add resumeAddCardToGoogleWallet() method for resuming card provisioning using existing token reference ID
- add listTokens() method to retrieve all tokens stored in Google Wallet
- add AndroidResumeCardData and TokenInfo types for new functionality
- update README.md with documentation for new methods

These methods provide better token lifecycle management and support for existing card tokens in Google Wallet integration.

🤖 Generated with [Claude Code](https://claude.ai/code)

Co-Authored-By: Claude <[email protected]>
Copy link

github-actions bot commented Aug 29, 2025

All contributors have signed the CLA ✍️ ✅
Posted by the CLA Assistant Lite bot.

@dbracamonte
Copy link
Author

I have read the CLA Document and I hereby sign the CLA

CLABotify added a commit to Expensify/CLA that referenced this pull request Aug 29, 2025
@dbracamonte dbracamonte changed the title feat: add Google Wallet token management methods feat: add Google Pay yellow path Aug 29, 2025
@Skalakid Skalakid requested review from Skalakid and zfurtak September 1, 2025 06:25
Copy link
Collaborator

@Skalakid Skalakid left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Overall, it looks good. I've left some comments. Additionally, could you please add a video to the PR description that demonstrates how your solution works in our example app?

@dbracamonte
Copy link
Author

Overall, it looks good. I've left some comments. Additionally, could you please add a video to the PR description that demonstrates how your solution works in our example app?

Thanks for the review!

Regarding the demo video, I need to clarify the testing constraints:

To demonstrate the Google Pay tokenization flow, I would need:

  • Production certificates from Google Pay (which I don't currently have access to)
  • Google-authorized test cards for the sandbox environment

The testing I performed was done using my work environment, but I cannot share that footage publicly as it contains
proprietary information from an unreleased application.

@dbracamonte
Copy link
Author

Greetings @Skalakid, I'm looking forward to continuing the approval process. If there's any way I can proceed, please let me know.

@Skalakid
Copy link
Collaborator

Skalakid commented Sep 5, 2025

Hello, had to finish some other tasks. We need to check if it actually works before merging. Since you've tested it in your unreleased app and can't attach a video here, I think we can try testing it in the Expensify app. I will try to add this flow there and will come back to you with more information

Copy link
Collaborator

@Skalakid Skalakid left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@dbracamonte Finally got some time to test this PR. Everything works fine. Left some last comments, and I think we can merge it ;)

yellow-path.mp4


val cardNetwork = getCardNetwork(network)
val tokenServiceProvider = getTokenServiceProvider(network)
val displayName = getDisplayName(data, network)
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why can't we use just cardHolderName as a display name, like in the addCardToGoogleWallet function? Is the getDisplayName function necessary?

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The getDisplayName function is necessary because of the different data requirements between the two methods:

  • In addCardToGoogleWallet: cardHolderName is a required field in AndroidCardData, so we can use it directly as the display name.
  • In resumeAddCardToGoogleWallet: Both cardHolderName and lastDigits are optional fields in AndroidResumeCardData.

This ensures we always have a meaningful display name for the Google Wallet UI, even when optional fields are missing.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

So let's also add getDisplayName to addCardToGoogleWallet()

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Added 🫡

}

return "${network.uppercase(Locale.getDefault())} Card"
}
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

According to the above comment, why do we need this?

@dbracamonte
Copy link
Author

Greetings @Skalakid, I look forward to your comments so we can continue with the integration.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants