Skip to content

Parse Unknown Payment Methods in Link#6248

Merged
jkelle-stripe merged 1 commit intomasterfrom
jkelle/unknown-pms-link
Apr 24, 2026
Merged

Parse Unknown Payment Methods in Link#6248
jkelle-stripe merged 1 commit intomasterfrom
jkelle/unknown-pms-link

Conversation

@jkelle-stripe
Copy link
Copy Markdown
Contributor

@jkelle-stripe jkelle-stripe commented Mar 24, 2026

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 the 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.

Below is a demo illustrating how we'll parse unknown payment methods, but continue not to display them as of this PR.

Demo

CleanShot.2026-04-16.at.11.37.01.mp4

@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

✅ Dead code has been resolved in this PR.

[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 thread StripeCore/StripeCore/Source/Coder/ParsedEnum.swift Outdated
Comment thread StripeCore/StripeCore/Source/Coder/StripeCodable.swift Outdated
@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
@jkelle-stripe jkelle-stripe force-pushed the jkelle/unknown-pms-link branch 2 times, most recently from c62b96c to 56c02b2 Compare April 15, 2026 13:20
@emerge-tools
Copy link
Copy Markdown

emerge-tools Bot commented Apr 15, 2026

⚠️ 4 new unused protocols, 9 builds increased size

Name Version Download Change Install Change Approval
StripeSize
com.stripe.StripeSize
1.0 (1) 2.1 MB ⬆️ 2.0 kB (0.09%) 7.0 MB ⬆️ 7.4 kB (0.11%) N/A
StripePaymentsSize
com.stripe.StripePaymentsSize
1.0 (1) 1.2 MB ⬆️ 3.1 kB (0.26%) 4.3 MB ⬆️ 7.5 kB (0.18%) N/A
StripePaymentsUISize
com.stripe.StripePaymentsUISize
1.0 (1) 2.0 MB ⬆️ 3.6 kB (0.18%) 6.4 MB ⬆️ 7.4 kB (0.12%) N/A
StripePaymentSheetSize
com.stripe.StripePaymentSheetSize
1.0 (1) 4.5 MB ⬆️ 1.5 kB (0.03%) 12.9 MB ⬆️ 4.6 kB (0.04%) N/A
StripeIdentitySize
com.stripe.StripeIdentitySize
1.0 (1) 1.3 MB ⬆️ 2.9 kB (0.22%) 4.3 MB ⬆️ 7.1 kB (0.17%) N/A
StripeIssuingSize
com.stripe.StripeIssuingSize
1.0 (1) 2.0 MB ⬆️ 2.4 kB (0.12%) 6.6 MB ⬆️ 12.0 kB (0.18%) N/A
StripeApplePaySize
com.stripe.StripeApplePaySize
1.0 (1) 506.7 kB ⬆️ 2.9 kB (0.58%) 1.7 MB ⬆️ 11.0 kB (0.66%) N/A
StripeFinancialConnectionsSize
com.stripe.StripeFinancialConnectionsSize
1.0 (1) 1.6 MB ⬆️ 2.9 kB (0.18%) 5.0 MB ⬆️ 10.5 kB (0.21%) N/A
StripeConnectSize
com.stripe.StripeConnectSize
1.0 (1) 1.8 MB ⬆️ 2.3 kB (0.13%) 6.0 MB ⬆️ 10.4 kB (0.17%) N/A

StripeSize 1.0 (1)
com.stripe.StripeSize

⚠️ Found new unused protocol: SafeParsedEnumCodable
⚖️ Compare build
⏱️ Analyze build performance

Total install size change: ⬆️ 7.4 kB (0.11%)
Total download size change: ⬆️ 2.0 kB (0.09%)

Largest size changes

Item Install Size Change
📝 StripeCore.ParsedEnum.value witness ⬆️ 2.1 kB
DYLD.Exports ⬆️ 992 B
📝 StripeCore.ParsedEnum.ParsedEnum ⬆️ 960 B
StripePayments.LinkSettings.decodedObject(fromAPIResponse) ⬆️ 808 B
📝 StripeCore._NativeSet.copyAndResize(capacity) ⬆️ 668 B
View Treemap

Image of diff

StripePaymentsSize 1.0 (1)
com.stripe.StripePaymentsSize

⚠️ Found new unused protocol: SafeParsedEnumCodable
⚖️ Compare build
⏱️ Analyze build performance

Total install size change: ⬆️ 7.5 kB (0.18%)
Total download size change: ⬆️ 3.1 kB (0.26%)

Largest size changes

Item Install Size Change
📝 StripeCore.ParsedEnum.value witness ⬆️ 2.1 kB
📝 StripeCore.ParsedEnum.ParsedEnum ⬆️ 984 B
StripePayments.LinkSettings.decodedObject(fromAPIResponse) ⬆️ 808 B
📝 StripeCore._NativeSet.copyAndResize(capacity) ⬆️ 668 B
📝 StripeCore._NativeSet.resize(capacity) ⬆️ 652 B
View Treemap

Image of diff

StripePaymentsUISize 1.0 (1)
com.stripe.StripePaymentsUISize

⚠️ Found new unused protocol: SafeParsedEnumCodable
⚖️ Compare build
⏱️ Analyze build performance

Total install size change: ⬆️ 7.4 kB (0.12%)
Total download size change: ⬆️ 3.6 kB (0.18%)

Largest size changes

Item Install Size Change
📝 StripeCore.ParsedEnum.value witness ⬆️ 2.1 kB
DYLD.Exports ⬆️ 984 B
📝 StripeCore.ParsedEnum.ParsedEnum ⬆️ 960 B
StripePayments.LinkSettings.decodedObject(fromAPIResponse) ⬆️ 808 B
📝 StripeCore._NativeSet.copyAndResize(capacity) ⬆️ 668 B
View Treemap

Image of diff

StripePaymentSheetSize 1.0 (1)
com.stripe.StripePaymentSheetSize

⚠️ Found new unused protocol: SafeParsedEnumCodable
⚖️ Compare build
⏱️ Analyze build performance

Total install size change: ⬆️ 4.6 kB (0.04%)
Total download size change: ⬆️ 1.5 kB (0.03%)

Largest size changes

Item Install Size Change
🗑 StripePaymentSheet.UnsafeMutableBufferPointer ⬇️ -3.0 kB
📝 StripeCore.ParsedEnum.value witness ⬆️ 2.1 kB
🗑 StripePaymentSheet._NativeSet.intersection ⬇️ -2.0 kB
📝 StripeCore.UnsafeMutableBufferPointer._stableSortImpl(by) ⬆️ 1.7 kB
StripePayments.UnsafeMutableBufferPointer._stableSortImpl(by) ⬇️ -1.7 kB
View Treemap

Image of diff

StripeIdentitySize 1.0 (1)
com.stripe.StripeIdentitySize

⚖️ Compare build
⏱️ Analyze build performance

Total install size change: ⬆️ 7.1 kB (0.17%)
Total download size change: ⬆️ 2.9 kB (0.22%)

Largest size changes

Item Install Size Change
📝 StripeCore.ParsedEnum.value witness ⬆️ 2.1 kB
📝 StripeCore.ParsedEnum.ParsedEnum ⬆️ 864 B
Code Signature ⬆️ 832 B
DYLD.Exports ⬆️ 824 B
Other ⬆️ 2.5 kB
View Treemap

Image of diff

StripeIssuingSize 1.0 (1)
com.stripe.StripeIssuingSize

⚖️ Compare build
⏱️ Analyze build performance

Total install size change: ⬆️ 12.0 kB (0.18%)
Total download size change: ⬆️ 2.4 kB (0.12%)

Largest size changes

Item Install Size Change
📝 StripeCore.ParsedEnum.value witness ⬆️ 2.1 kB
DYLD.Exports ⬆️ 1.0 kB
📝 StripeCore.ParsedEnum.ParsedEnum ⬆️ 960 B
StripePayments.LinkSettings.decodedObject(fromAPIResponse) ⬆️ 808 B
📝 StripeCore._NativeSet.copyAndResize(capacity) ⬆️ 668 B
View Treemap

Image of diff

StripeApplePaySize 1.0 (1)
com.stripe.StripeApplePaySize

⚖️ Compare build
⏱️ Analyze build performance

Total install size change: ⬆️ 11.0 kB (0.66%)
Total download size change: ⬆️ 2.9 kB (0.58%)

Largest size changes

Item Install Size Change
📝 StripeCore.ParsedEnum.value witness ⬆️ 2.1 kB
📝 StripeCore.ParsedEnum.ParsedEnum ⬆️ 884 B
DYLD.Exports ⬆️ 816 B
Code Signature ⬆️ 520 B
Other ⬆️ 6.6 kB
View Treemap

Image of diff

StripeFinancialConnectionsSize 1.0 (1)
com.stripe.StripeFinancialConnectionsSize

⚖️ Compare build
⏱️ Analyze build performance

Total install size change: ⬆️ 10.5 kB (0.21%)
Total download size change: ⬆️ 2.9 kB (0.18%)

Largest size changes

Item Install Size Change
📝 StripeCore.ParsedEnum.value witness ⬆️ 2.1 kB
📝 StripeCore.ParsedEnum.ParsedEnum ⬆️ 872 B
DYLD.Exports ⬆️ 824 B
Other ⬆️ 6.7 kB
View Treemap

Image of diff

StripeConnectSize 1.0 (1)
com.stripe.StripeConnectSize

⚖️ Compare build
⏱️ Analyze build performance

Total install size change: ⬆️ 10.4 kB (0.17%)
Total download size change: ⬆️ 2.3 kB (0.13%)

Largest size changes

Item Install Size Change
📝 StripeCore.ParsedEnum.value witness ⬆️ 2.1 kB
📝 StripeCore.ParsedEnum.ParsedEnum ⬆️ 864 B
DYLD.Exports ⬆️ 840 B
Other ⬆️ 6.6 kB
View Treemap

Image of diff


🛸 Powered by Emerge Tools

@jkelle-stripe jkelle-stripe force-pushed the jkelle/unknown-pms-link branch 4 times, most recently from ab62edc to b64f9c3 Compare April 16, 2026 13:38
@jkelle-stripe jkelle-stripe changed the base branch from master to jkelle/filtered-supported-payment-methods April 16, 2026 13:58
@jkelle-stripe jkelle-stripe force-pushed the jkelle/unknown-pms-link branch 3 times, most recently from cf24967 to e2a4dbb Compare April 16, 2026 14:20
@jkelle-stripe jkelle-stripe marked this pull request as ready for review April 16, 2026 15:40
/// Known values: `value` is non-nil, `rawValue` matches the enum's raw value.
/// Unknown values: `value` is nil, `rawValue` contains the unrecognized API string.
/// :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.

Wondering if it's ok for me to add this type in StripeCore?
cc @porter-stripe since you got the random assignment of codeowners, but anyone feel free to add input!

Base automatically changed from jkelle/filtered-supported-payment-methods to master April 22, 2026 14:00
@jkelle-stripe jkelle-stripe force-pushed the jkelle/unknown-pms-link branch from e2a4dbb to cae01f1 Compare April 22, 2026 15:18
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.

Well done!

@jkelle-stripe jkelle-stripe merged commit 8bd42b5 into master Apr 24, 2026
7 checks passed
@jkelle-stripe jkelle-stripe deleted the jkelle/unknown-pms-link branch April 24, 2026 13:37
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