Skip to content

Parse Unknown Payment Methods in Link#6248

Draft
jkelle-stripe wants to merge 3 commits intomasterfrom
jkelle/unknown-pms-link
Draft

Parse Unknown Payment Methods in Link#6248
jkelle-stripe wants to merge 3 commits intomasterfrom
jkelle/unknown-pms-link

Conversation

@jkelle-stripe
Copy link
Copy Markdown
Contributor

Summary

Enables forward compatible parsing of unknown payment method types in native Link.

  • Parses the responses of /v1/consumers/sessions/lookup and /v1/elements/sessions payment methods / funding sources and stores unknown types
  • These types can now be sent in the payment_details/list query param list as payment method types (although they are not in this PR to maintain existing functionality).

Motivation

We'd like forward compatibility for Link payment methods. When backend adds PMs, they should be able to be rendered and used for payment in prior versions of the SDK. This PR is a first step towards this goal. This proposal provides more context.

Testing

Included a few new tests here to ensure the parsing logic is accurate.

@jkelle-stripe jkelle-stripe requested review from a team as code owners March 24, 2026 16:27
@jkelle-stripe jkelle-stripe marked this pull request as draft March 24, 2026 16:28
///
/// Modeled after Android's `ApiEnum<E>`.
/// :nodoc:
@_spi(STP) public struct ParsedEnum<E: SafeParsedEnumCodable>: Hashable {
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.

I'd love feedback about the naming of this type and its usage shapes. Is it clear to the reader what it's goal is?

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.

There's already a SafeEnumDecodable. Could we extend that and add a rawValue there?

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.

I wanted to add a separate type here since existing conformers to SafeEnumDecodable don't have to deal with the wrapper type right now (see this file, where we have to add the generic wrapper and parse with .value). I think this adds overhead to types that currently conform to SafeEnumDecodable that don't need the knowledge of the unknown value.

return .bankAccount
}
extension ParsedEnum where E == LinkSettings.FundingSource {
var detailsType: ParsedEnum<ConsumerPaymentDetails.DetailsType> {
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.

We can map unknown funding sources to unknown payment detail types. Which is necessary for comparing them before calling payment_details/list

@github-actions
Copy link
Copy Markdown

github-actions bot commented Mar 24, 2026

🚨 New dead code detected in this PR:

PayWithLinkViewController-WalletViewModel.swift:37 warning: Unused property 'supportedPaymentMethodTypes'

Please remove the dead code before merging.

If this is intentional, you can bypass this check by adding the label skip dead code check to this PR.

ℹ️ If this comment appears to be left in error, double check that the flagged code is actually used and/or make sure your branch is up-to-date with master.

[find-dead-code]

@jkelle-stripe jkelle-stripe force-pushed the jkelle/unknown-pms-link branch from 226b5ba to eb9494c Compare March 24, 2026 16:49

// MARK: - Unknown payment method type filtering

func test_unknownPaymentMethodType_isNotInSupportedTypes() throws {
Copy link
Copy Markdown
Contributor Author

@jkelle-stripe jkelle-stripe Mar 24, 2026

Choose a reason for hiding this comment

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

This test exemplifies the inclusion of unknown funding sources in parsing without including them in rendering (and breaking existing functionality before we're ready to render and pay with them). Curious if folks have other ideas for contexts I'm missing coverage for in the tests in this PR.

mats-stripe
mats-stripe previously approved these changes Mar 26, 2026
Copy link
Copy Markdown
Collaborator

@mats-stripe mats-stripe left a comment

Choose a reason for hiding this comment

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

This seems like a good approach, nicely done with the documentation and testing 👍

Comment on lines +13 to +14
/// Known values: ``value`` is non-nil, ``rawValue`` matches the enum's raw value.
/// Unknown values: ``value`` is nil, ``rawValue`` contains the unrecognized API string.
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.

Not sure if this was intentional or not:

Suggested change
/// Known values: ``value`` is non-nil, ``rawValue`` matches the enum's raw value.
/// Unknown values: ``value`` is nil, ``rawValue`` contains the unrecognized API string.
/// Known values: `value` is non-nil, `rawValue` matches the enum's raw value.
/// Unknown values: `value` is nil, `rawValue` contains the unrecognized API string.


/// A protocol for enums whose raw API string values should be preserved
/// even when the value is unknown to the SDK.
/// Unlike SafeEnumCodable, the raw string is never lost — use with ``ParsedEnum``.
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.

Same here - maybe this is intentional syntax!

Suggested change
/// Unlike SafeEnumCodable, the raw string is never lost — use with ``ParsedEnum``.
/// Unlike SafeEnumCodable, the raw string is never lost — use with `ParsedEnum`.

@github-actions
Copy link
Copy Markdown

github-actions bot commented Mar 30, 2026

⚠️ 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.

@jkelle-stripe jkelle-stripe force-pushed the jkelle/unknown-pms-link branch from 7fdef06 to f6ecd89 Compare March 31, 2026 11:01
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.

3 participants