Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

read from customersession setting instead of config #4517

Open
wants to merge 24 commits into
base: master
Choose a base branch
from

Conversation

joyceqin-stripe
Copy link
Collaborator

@joyceqin-stripe joyceqin-stripe commented Jan 30, 2025

Summary

Reads whether the feature is enabled from ElementsSession.customer.customerSession instead of PaymentSheet/CustomerSheet Configuration

Motivation

MOBILESDK-2666

Testing

Changelog

Copy link

emerge-tools bot commented Jan 30, 2025

1 build decreased size, 7 builds had no size change

Name Version Download Change Install Change Approval
StripeSize
com.stripe.StripeSize
1.0 (1) 2.1 MB ⬆️ 6 B 7.0 MB - N/A
StripePaymentsSize
com.stripe.StripePaymentsSize
1.0 (1) 1.2 MB - 4.2 MB - N/A
StripePaymentsUISize
com.stripe.StripePaymentsUISize
1.0 (1) 1.9 MB ⬇️ 6 B 6.4 MB - N/A
StripePaymentSheetSize
com.stripe.StripePaymentSheetSize
1.0 (1) 3.8 MB ⬆️ 835 B (0.02%) 11.2 MB ⬇️ 388 B N/A
StripeIdentitySize
com.stripe.StripeIdentitySize
1.0 (1) 1.4 MB ⬆️ 2 B 4.4 MB - N/A
StripeApplePaySize
com.stripe.StripeApplePaySize
1.0 (1) 489.1 kB - 1.7 MB - N/A
StripeFinancialConnectionsSize
com.stripe.StripeFinancialConnectionsSize
1.0 (1) 1.5 MB ⬆️ 2 B 4.8 MB - N/A
StripeConnectSize
com.stripe.StripeConnectSize
1.0 (1) 1.7 MB ⬆️ 1 B 5.4 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: ⬇️ 388 B
Total download size change: ⬆️ 835 B (0.02%)

Largest size changes

Item Install Size Change
🗑 StripePaymentSheet.PaymentSheetFormFactory.makeCard(cardBrandChoi... ⬇️ -13.7 kB
📝 StripePaymentSheet.PaymentSheetFormFactory.makeCard(cardBrandChoi... ⬆️ 13.0 kB
🗑 StripePaymentSheet.PaymentSheetFormFactory.makeUSBankAccount(merc... ⬇️ -8.1 kB
📝 StripePaymentSheet.PaymentSheetFormFactory.makeUSBankAccount(merc... ⬆️ 7.4 kB
📝 StripePaymentSheet.SavedPaymentOptionsViewController.makeViewMode... ⬆️ 1.7 kB
View Treemap

Image of diff

StripeIdentitySize 1.0 (1)
com.stripe.StripeIdentitySize

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

@joyceqin-stripe joyceqin-stripe marked this pull request as ready for review February 10, 2025 15:39
@joyceqin-stripe joyceqin-stripe requested review from a team as code owners February 10, 2025 15:39
/// This is an experimental feature that may be removed at any time.
/// If true, users can set a payment method as default and sync their default payment method across web and mobile
/// If false (default), users cannot set default payment methods.
@_spi(AllowsSetAsDefaultPM) public var allowsSetAsDefaultPM = false
Copy link
Collaborator

Choose a reason for hiding this comment

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

Do a search in the codebase for I see 3 instances that need to be removed/cleaned up. (AllowsSetAsDefaultPM)

@@ -42,6 +42,7 @@ struct CustomerSession: Equatable, Hashable {
return nil
}
let paymentMethodRemoveLast = mobilePaymentElementFeaturesDict["payment_method_remove_last"] as? String ?? "enabled"
let paymentMethodSetAsDefault = mobilePaymentElementFeaturesDict["payment_method_set_as_default"] as? String ?? "disabled"
Copy link
Collaborator

Choose a reason for hiding this comment

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

Surprised we don't have any tests for this class? If so can we file a run ticket to get some tests created for this class.

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Created a ticket: RUN_MOBILESDK-3836

Copy link
Collaborator

Choose a reason for hiding this comment

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

We do have tests. They are in STPElementsSessionTest.swift

Copy link
Collaborator

Choose a reason for hiding this comment

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

Ah I see, it's a child of ElementsSession. Kinda hard to tell it's being tested might still be good to have standalone tests.

Comment on lines 282 to 283
}
func testSetAsDefault_disabled() {
Copy link
Collaborator

Choose a reason for hiding this comment

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

Super nit: Our linter on CI isn't working but let's always have a new line between functions

@@ -262,6 +262,41 @@ class STPElementsSessionTest: XCTestCase {

XCTAssertEqual(.legacy, savePaymentMethodConsentBehavior)
}
func testSetAsDefault_enabled() {
Copy link
Collaborator

Choose a reason for hiding this comment

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

Can we update testDecodedObjectFromAPIResponseMapping to make sure that paymentMethodSetAsDefaultForPaymentSheet defaults to false?

@@ -107,10 +107,10 @@ extension CustomerSessionAdapter {
return stripePaymentMethodId
}

func fetchSelectedPaymentOption(for customerId: String, customer: ElementsCustomer? = nil) -> CustomerPaymentOption? {
func fetchSelectedPaymentOption(for customerId: String, elementsSession: STPElementsSession? = nil) -> CustomerPaymentOption? {
Copy link
Collaborator

Choose a reason for hiding this comment

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

Similarly surprised we don't have tests for this, can you mention this class in the JIRA ticket you create.

@@ -42,7 +42,7 @@ class CustomerSheetDataSource {
await loadFormSpecs()
let customerId = try await customerSessionClientSecret.customerId
let elementSession = try await elementsSessionResult
let paymentOption = customerSessionAdapter.fetchSelectedPaymentOption(for: customerId, customer: elementSession.customer)
Copy link
Collaborator

Choose a reason for hiding this comment

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

Hm same, this entire file has no tests :(

Copy link
Collaborator

Choose a reason for hiding this comment

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

Not having tests for this class was intentional for most functions in this class as they are just switching on legacy ephemeral keys vs customersession. For loadPaymentMethodInfo it's debatable whether we want to add tests it seems like we'd end up with a lot of mocked responses so it's unclear how helpful it would be.

@@ -200,7 +200,7 @@ extension PaymentSheet {
params,
with: authenticationContext,
completion: { actionStatus, paymentIntent, error in
if let paymentIntent {
if let paymentIntent, !elementsSession.paymentMethodSetAsDefaultForPaymentSheet {
Copy link
Collaborator

Choose a reason for hiding this comment

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

This reads backwards to me, why are we setting default if necessary only if NOT paymentMethodSetAsDefaultForPaymentSheet. Is setDefaultPaymentMethodIfNecessary setting the default in the local storage? If so let's make this more clear there is a difference between where we are saving defaults.

Copy link
Collaborator

Choose a reason for hiding this comment

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

Maybe pass this flag into setDefaultPaymentMethodIfNecessary rather than checking it here? Seems like the wrong place to do it.

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Yeah, setDefaultPaymentMethodIfNecessary writes to local storage

@@ -222,7 +222,7 @@ extension PaymentSheet {
setupIntentParams,
with: authenticationContext,
completion: { actionStatus, setupIntent, error in
if let setupIntent {
if let setupIntent, !elementsSession.paymentMethodSetAsDefaultForPaymentSheet {
Copy link
Collaborator

Choose a reason for hiding this comment

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

Same here

Comment on lines 56 to 57
if let paymentOrSetupIntent, !allowsSetAsDefaultPM {
setDefaultPaymentMethodIfNecessary(actionStatus: status, intent: paymentOrSetupIntent, configuration: configuration)
Copy link
Collaborator

Choose a reason for hiding this comment

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

Same comment here as above

@@ -319,7 +318,7 @@ final class PaymentSheetLoader {
if let customerID = configuration.customer?.id {
var defaultPaymentMethodOption: CustomerPaymentOption?
// if opted in to the "set as default" feature, try to get default payment method from elements session
Copy link
Collaborator

Choose a reason for hiding this comment

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

Is this comment still true?

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Yes, we read from the CustomerSession setting to see if the feature is on, and if so, it tries to get the default payment method from the ElementsSession, but otherwise, it reads from the local storage

@@ -211,6 +211,10 @@ extension STPElementsSession {
return customer?.customerSession.mobilePaymentElementComponent.features?.paymentMethodRemoveLast ?? true
}

var paymentMethodSetAsDefaultForPaymentSheet: Bool {
Copy link
Collaborator

Choose a reason for hiding this comment

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

Doesn't need to be in this PR, but we should probably rename xForPaymentSheet to xForMPE

@@ -526,10 +530,10 @@ extension PaymentSheetFormFactory {
)
}

func makeUSBankAccount(merchantName: String) -> PaymentMethodElement {
func makeUSBankAccount(merchantName: String, showSetAsDefaultCheckbox: Bool = false) -> PaymentMethodElement {
Copy link
Collaborator

Choose a reason for hiding this comment

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

There doesn't seem to be a good reason to default to false.

@@ -13,10 +13,10 @@ import StripePayments
import UIKit

extension PaymentSheetFormFactory {
func makeCard(cardBrandChoiceEligible: Bool = false) -> PaymentMethodElement {
func makeCard(cardBrandChoiceEligible: Bool = false, showSetAsDefaultCheckbox: Bool = false) -> PaymentMethodElement {
Copy link
Collaborator

Choose a reason for hiding this comment

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

Is there a good reason to default showSetAsDefaultCheckbox to false?

Comment on lines +463 to +467
if let elementsSession = elementsSession,
let customer = elementsSession.customer,
let features = customer.customerSession.mobilePaymentElementComponent.features,
features.paymentMethodSetAsDefault,
let defaultPaymentMethod = customer.getDefaultOrFirstPaymentMethod() {
Copy link
Collaborator

Choose a reason for hiding this comment

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

If we go with this pattern, it could be more simply written:

        if let elementsSession,
           elementsSession.paymentMethodSetAsDefaultForPaymentSheet,
            let defaultPaymentMethod = elementsSession.customer?.getDefaultOrFirstPaymentMethod() {

But, taking a step back, have we considered passing in the elementsSession instance into CustomerPaymentOption so that we can just simply write something like:

 CustomerPaymentOption.defaultPaymentMethod(for: customerID, elementsSession: elementsSession, surface: .paymentSheet) 

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