Skip to content

feat: pass optional primaryAccountIdentifier to Apple Wallet - #91

Open
Brunonascdev wants to merge 1 commit into
Expensify:mainfrom
Brunonascdev:feat/ios-primary-account-identifier
Open

Brunonascdev wants to merge 1 commit into
Expensify:mainfrom
Brunonascdev:feat/ios-primary-account-identifier

Conversation

@Brunonascdev

@Brunonascdev Brunonascdev commented Sep 21, 2026 •

Copy link
Copy Markdown

Details

IOSCardData cannot set PKAddPaymentPassRequestConfiguration.primaryAccountIdentifier. Issuers that reissue a card keep one opaque id while the PAN suffix changes, and PassKit uses that id to recognize the existing pass.

This adds an optional primaryAccountIdentifier. The native bridge forwards it only when it is non-empty, and WalletManager sets it on the PassKit configuration only when it is present. Callers that omit it keep the current behavior.

Related Issues

#56

Manual Tests

No automated coverage for the PassKit configuration. The field is omitted from the native dictionary when absent, and assigned on the configuration when present. Confirming PassKit recognizes a reissued card still needs a device and an issuer that supplies the id.

PassKit uses this id to recognize a reissued card after the PAN suffix changes.
@github-actions

github-actions Bot commented Sep 21, 2026 •

Copy link
Copy Markdown

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

@Brunonascdev

Copy link
Copy Markdown
Author

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

exfy-clabot Bot added a commit to Expensify/CLA that referenced this pull request Sep 21, 2026
@Brunonascdev

Copy link
Copy Markdown
Author

recheck

@JakubKorytko JakubKorytko left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

note: #56 also asks for the selected device in the issuer callback, so this covers only the first part of it and the issue should stay open after merge, unless you want to expand this PR

Comment thread src/NativeWallet.ts
lastDigits: string;
cardDescription: string;
/** Opaque issuer id. PassKit uses it to recognize a reissued card. */
primaryAccountIdentifier?: string;

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Could you also add primaryAccountIdentifier?: string to the IOSCardData row in the README data types table? People read that table to see which fields they can pass.

Comment thread ios/WalletManager.swift
configuration.primaryAccountSuffix = card.lastDigits
configuration.localizedDescription = String(card.cardDescription)
if let primaryAccountIdentifier = card.primaryAccountIdentifier {
configuration.primaryAccountIdentifier = primaryAccountIdentifier

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Not sure about this one: what happens when the pass with this id is already on every device (iPhone and Watch)? If PassKit has nowhere to add it, PKAddPaymentPassViewController(...) might return nil and the user gets "InApp enrollment controller configuration fails", which is confusing. Did you get a chance to check that case? If it is a real problem, PKPassLibrary().canAddSecureElementPass(primaryAccountIdentifier:) could be used to give a clearer error.

@JakubKorytko

Copy link
Copy Markdown
Member

Heads up: #93 just landed and adds an old arch branch to the cardDataDict block in IOSPresentAddPaymentPassView (ios/RNWallet.mm), so this needs a rebase/merge. When resolving it, please also read the field in the #else branch, e.g. cardData[@"primaryAccountIdentifier"], otherwise it gets silently dropped on the old arch. The same safeString + length > 0 check should apply there too.

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