Skip to content

Render Unknown Payment Methods in Link#6342

Open
jkelle-stripe wants to merge 7 commits intomasterfrom
jkelle/display-metadata-rendering
Open

Render Unknown Payment Methods in Link#6342
jkelle-stripe wants to merge 7 commits intomasterfrom
jkelle/display-metadata-rendering

Conversation

@jkelle-stripe
Copy link
Copy Markdown
Contributor

@jkelle-stripe jkelle-stripe commented Apr 15, 2026

Summary

Display unknown payment methods in native Link by parsing the display metadata included in each redacted_payment_details entry. Expected structure includes looks like:

display: {
  label: 'Card nickname',
  icon: {
    default: 'cdn.stripe.com/.../amex.png'
  },
  sublabel: '**** 1234'
}

Demos

Connecting a New PM

Note: The payment method previously existed (from creation on web), but is being used on a different device, so reconnection is needed.

New.Wallet.mp4

Using an Existing PM

Existing.Wallet.mp4

@github-actions
Copy link
Copy Markdown

⚠️ Public API changes detected:

StripeCore

Public API

+public protocol SafeParsedEnumCodable : Swift.CaseIterable, Swift.Hashable, Swift.RawRepresentable where Self.RawValue == Swift.String {
+}

If you are adding a new public API consider the following:

  • Do these APIs need to be public or can they be protected with @_spi(STP)?
  • If these APIs need to be public, assess whether they require an API review.

If you are modifying or removing a public API:

  • Does this require a breaking version change?
  • Do these changes require API review?

If you confirm these APIs need to be added/updated and have undergone necessary review, add the label modifies public API to this PR to acknowledge the interface change.
Additionally, if you modified or removed an existing API, ensure you update the changelog to reflect the necessary version bump for your changes. Regular public API changes require a MAJOR version bump, and SPI API changes (other than @_spi(STP)-only declarations) require a MINOR or MAJOR version bump.

ℹ️ If this comment appears to be left in error, make sure your branch is up-to-date with master.

@github-actions
Copy link
Copy Markdown

github-actions Bot commented Apr 15, 2026

✅ Dead code has been resolved in this PR.

[find-dead-code]

@jkelle-stripe jkelle-stripe force-pushed the jkelle/unknown-pms-link branch from c62b96c to 56c02b2 Compare April 15, 2026 13:20
@jkelle-stripe jkelle-stripe force-pushed the jkelle/display-metadata-rendering branch from a6e009b to 075af8d Compare April 15, 2026 15:25
@jkelle-stripe jkelle-stripe force-pushed the jkelle/unknown-pms-link branch from e11e1e1 to 8923c66 Compare April 15, 2026 17:32
@jkelle-stripe jkelle-stripe force-pushed the jkelle/display-metadata-rendering branch 2 times, most recently from 367b991 to 98e36be Compare April 15, 2026 19:26
@jkelle-stripe jkelle-stripe force-pushed the jkelle/unknown-pms-link branch from 8923c66 to a75478f Compare April 15, 2026 19:28
@jkelle-stripe jkelle-stripe force-pushed the jkelle/display-metadata-rendering branch from 98e36be to edd1d5e Compare April 15, 2026 19:29
@emerge-tools
Copy link
Copy Markdown

emerge-tools Bot commented Apr 15, 2026

1 build increased size, 8 builds had no size change

Name Version Download Change Install Change Approval
StripeSize
com.stripe.StripeSize
1.0 (1) 2.1 MB ⬆️ 38 B 7.0 MB - N/A
StripePaymentsSize
com.stripe.StripePaymentsSize
1.0 (1) 1.2 MB ⬆️ 1 B 4.3 MB - N/A
StripePaymentsUISize
com.stripe.StripePaymentsUISize
1.0 (1) 2.0 MB ⬇️ 7 B 6.4 MB - N/A
StripePaymentSheetSize
com.stripe.StripePaymentSheetSize
1.0 (1) 4.5 MB ⬆️ 5.5 kB (0.12%) 12.9 MB ⬆️ 15.9 kB (0.12%) N/A
StripeIdentitySize
com.stripe.StripeIdentitySize
1.0 (1) 1.4 MB ⬇️ 9 B 4.4 MB - N/A
StripeIssuingSize
com.stripe.StripeIssuingSize
1.0 (1) 2.0 MB ⬆️ 1 B 6.6 MB - N/A
StripeApplePaySize
com.stripe.StripeApplePaySize
1.0 (1) 507.5 kB - 1.7 MB - N/A
StripeFinancialConnectionsSize
com.stripe.StripeFinancialConnectionsSize
1.0 (1) 1.6 MB ⬇️ 5 B 4.9 MB - N/A
StripeConnectSize
com.stripe.StripeConnectSize
1.0 (1) 1.8 MB ⬆️ 7 B 6.0 MB - N/A

StripeSize 1.0 (1)
com.stripe.StripeSize

No changes to report

StripePaymentsSize 1.0 (1)
com.stripe.StripePaymentsSize

No changes to report

StripePaymentsUISize 1.0 (1)
com.stripe.StripePaymentsUISize

No changes to report

StripePaymentSheetSize 1.0 (1)
com.stripe.StripePaymentSheetSize

⚖️ Compare build
⏱️ Analyze build performance

Total install size change: ⬆️ 15.9 kB (0.12%)
Total download size change: ⬆️ 5.5 kB (0.12%)

Largest size changes

Item Install Size Change
📝 StripePaymentSheet.ConsumerPaymentDetails.DisplayMetadata.value w... ⬆️ 2.2 kB
StripePaymentSheet.LinkPaymentMethodPicker.CellContentView.paymen... ⬆️ 1.5 kB
📝 StripePaymentSheet.ConsumerPaymentDetails.DisplayMetadata.Icon.va... ⬆️ 1.0 kB
StripePaymentSheet.LinkPaymentMethodPicker.CellContentView.iconCo... ⬆️ 996 B
🗑 StripePaymentSheet.LinkPaymentMethodPicker.CellContentView.create... ⬇️ -872 B
View Treemap

Image of diff

StripeIdentitySize 1.0 (1)
com.stripe.StripeIdentitySize

No changes to report

StripeIssuingSize 1.0 (1)
com.stripe.StripeIssuingSize

No changes to report

StripeApplePaySize 1.0 (1)
com.stripe.StripeApplePaySize

No changes to report

StripeFinancialConnectionsSize 1.0 (1)
com.stripe.StripeFinancialConnectionsSize

No changes to report

StripeConnectSize 1.0 (1)
com.stripe.StripeConnectSize

No changes to report


🛸 Powered by Emerge Tools

@jkelle-stripe jkelle-stripe changed the title Render Future Payment Methods in Native Link Render Unknown Payment Methods in Link Apr 15, 2026
@jkelle-stripe jkelle-stripe force-pushed the jkelle/unknown-pms-link branch 2 times, most recently from ab62edc to b64f9c3 Compare April 16, 2026 13:38
@jkelle-stripe jkelle-stripe force-pushed the jkelle/display-metadata-rendering branch from e6791f1 to bb95070 Compare April 16, 2026 13:56
@jkelle-stripe jkelle-stripe force-pushed the jkelle/unknown-pms-link branch from b64f9c3 to 5fc3cf3 Compare April 16, 2026 14:02
@jkelle-stripe jkelle-stripe force-pushed the jkelle/display-metadata-rendering branch from bb95070 to 7fcad72 Compare April 16, 2026 14:03
@jkelle-stripe jkelle-stripe force-pushed the jkelle/unknown-pms-link branch from 5fc3cf3 to cf24967 Compare April 16, 2026 14:13
@jkelle-stripe jkelle-stripe force-pushed the jkelle/display-metadata-rendering branch from 7fcad72 to 819ab2d Compare April 16, 2026 14:15
case .unparsable:
return false
// Unknown types don't have country info; allow them if display metadata is present.
return display != nil
Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

My thought process here is that if they're not allowed, they would have been filtered by the backend (eg. for brl currencies, Pix is presented and not Crypto).

@jkelle-stripe jkelle-stripe force-pushed the jkelle/unknown-pms-link branch from cf24967 to e2a4dbb Compare April 16, 2026 14:20
@jkelle-stripe jkelle-stripe force-pushed the jkelle/display-metadata-rendering branch 5 times, most recently from b352511 to dd51024 Compare April 16, 2026 20:27
jkelle-stripe added a commit that referenced this pull request Apr 22, 2026
## Summary
  Modifies the default value of `supportedPaymentMethodTypes`

## Motivation
In #5309, we introduced parametric filtering of supported payment
methods. We used a default value of `allCases`, which works for our
current feature set. However, in #6342, we'll want to remove the
`intersection` on these filtered payment methods if none are provided to
allow for unknown PMs to be included in the list. In this PR, we'll keep
the same intersection functionality of all cases, but modify the piping
of these values to use `nil` instead of `allCases` as the default value.
In #6342, we [remove the allCases
intersection](https://github.com/stripe/stripe-ios/pull/6342/changes#diff-7d5339851903df687dc841f3deb388ba566a2f0b319c57c38671cb529b80e7a4R119)
entirely if `nil` filtered payment methods are passed in.

## Demos
| Test Harness  | MPE |
| ------------- | ------------- |
| <video
src="https://github.com/user-attachments/assets/3a09ccb5-59c1-4cfb-aa7f-273776a8e6f8"
/> | <video
src="https://github.com/user-attachments/assets/8f798fe5-ecc1-4ee9-9d7a-ba532421d354"
/> |
@jkelle-stripe jkelle-stripe force-pushed the jkelle/unknown-pms-link branch from e2a4dbb to cae01f1 Compare April 22, 2026 15:18
Base automatically changed from jkelle/unknown-pms-link to master April 24, 2026 13:37
@jkelle-stripe jkelle-stripe force-pushed the jkelle/display-metadata-rendering branch from cd317f0 to 40bffda Compare April 24, 2026 13:38
@jkelle-stripe jkelle-stripe force-pushed the jkelle/display-metadata-rendering branch 3 times, most recently from d4b11e8 to 9f53197 Compare April 28, 2026 16:06
@jkelle-stripe jkelle-stripe marked this pull request as ready for review April 28, 2026 16:16
@jkelle-stripe jkelle-stripe requested review from a team as code owners April 28, 2026 16:16
@jkelle-stripe jkelle-stripe force-pushed the jkelle/display-metadata-rendering branch from 9f53197 to c2fbdba Compare April 28, 2026 16:18
Copy link
Copy Markdown
Collaborator

@tillh-stripe tillh-stripe left a comment

Choose a reason for hiding this comment

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

I haven't yet had the time to take a look myself, but a few things that Codex has been flagging:

  1. Billing details recollection (when a merchant requests full billing details) might be triggered for an unknown type, but createUpdateDetails would fail for unknown types.
  2. The setLinkPaymentDetails method in ElementsCustomer.swift wouldn't be able to render non-card and non-bank payment methods.
  3. Do we need to update the logic in getSupportedPaymentDetailsTypes now?
  4. The delete dialogs in removePaymentMethod uses an empty title for unknown types, which we don't want.

A quick scan of the codebase suggests to me that these are true — can you confirm that?

@jkelle-stripe jkelle-stripe force-pushed the jkelle/display-metadata-rendering branch from c2fbdba to c071b93 Compare April 30, 2026 14:32
@jkelle-stripe
Copy link
Copy Markdown
Contributor Author

jkelle-stripe commented Apr 30, 2026

@tillh-stripe Thanks for flagging these!

  1. Addressed in a0ccac0
  2. Working on this now.
  3. This function was updated before your comment. Do we think it needs more work?
  4. Addressed in 57b8b5a
Card Bank Crypto

@github-actions
Copy link
Copy Markdown

github-actions Bot commented Apr 30, 2026

⚠️ Missing Translations
The following strings have been uploaded to Lokalise but are not yet translated.

%@ will no longer be saved to your wallet., Remove bank?

If it's okay for these strings to be unlocalized in master (e.g. this is for an unshipped feature), add the label ship without translations to acknowledge that there are missing translations. Otherwise, wait until translations are available in Lokalise and re-run this job.

New strings are localized on a weekly basis and are downloaded as part of the release process. For more details on how to localize a string, you can refer to this link.

@jkelle-stripe jkelle-stripe force-pushed the jkelle/display-metadata-rendering branch from b7c94fa to cf827ea Compare May 2, 2026 14:36

/* Title for a button that when tapped removes a payment method.
Title for confirmation prompt when removing a saved payment method without a display label. */
"Remove payment method" = "Remove payment method";
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

I wonder if we should just show Remove in the buttons, as the available space is limited. Not immediately required, but let's follow up with that?

let billingAddress: BillingAddress?
let billingEmailAddress: String?
let nickname: String?
let display: DisplayMetadata?
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

If I remember correctly, we talked about this becoming non-nullable? Is that still the plan for later on?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

@tillh-stripe Yep! The backend FF is still there so want to make sure that is removed before we remove nullability here.

Comment on lines +120 to +121
// Unknown types don't have country info; allow them if display metadata is present.
return display != nil
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

I'm not sure what the right logic is here, but I don't think this one is it. Maybe it needs to be similar to the card case and just look at billing address?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

@tillh-stripe Resolved in cce6779. Really good catch!

Before After
before.mov
after.mov

@@ -375,7 +394,9 @@ extension ConsumerPaymentDetails {
case .bankAccount(let bankAccount):
return bankAccount.displayName(with: nickname)
case .unparsable:
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

We should rename unparsable, but that's for a later pull request.

Comment thread CHANGELOG.md Outdated
Comment on lines +6 to +7
### PaymentSheet
* [Added] Added forward-compatiblity for backend-provided payment methods in the native Link payment sheet.
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

We should change this by either writing something that feels more relevant to the merchant (“Added support for new and upcoming payment methods in Link, such as UPI and Pix“) or by removing it entirely. I find that this is an implementation detail, so in favor of the latter.

@jkelle-stripe jkelle-stripe force-pushed the jkelle/display-metadata-rendering branch from cf827ea to cce6779 Compare May 4, 2026 16:22
@jkelle-stripe
Copy link
Copy Markdown
Contributor Author

@tillh-stripe found a bug with billing address collection not include name for non-cards. Resolved in 7de1bce See in the before that the billing address for a Pix PD created on web has a name and when we pay on MPE with billing address collection, we wipe the name and replace with the provided address. See in the after video, this is resolved.

Before After
before-converted.mp4
after-converted.mp4

@jkelle-stripe jkelle-stripe force-pushed the jkelle/display-metadata-rendering branch from 7de1bce to ddc59e3 Compare May 5, 2026 19:47
@jkelle-stripe jkelle-stripe requested a review from tillh-stripe May 5, 2026 19:47
@jkelle-stripe
Copy link
Copy Markdown
Contributor Author

@tillh-stripe This is ready for review! Added back the changelog entry for this upcoming release to flag that a release is needed.

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