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

Hide default checkbox and auto-set if first #4643

Merged
merged 6 commits into from
Mar 10, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -2816,10 +2816,8 @@ class PaymentSheetDefaultSPMUITests: PaymentSheetUITestCase {
var saveThisCardToggle = app.switches["Save payment details to Example, Inc. for future purchases"]
saveThisCardToggle.tap()
XCTAssertTrue(saveThisCardToggle.isSelected)
// toggle set this card as default
var setDefaultToggle = app.switches["Set as default payment method"]
setDefaultToggle.tap()
XCTAssertTrue(setDefaultToggle.isSelected)
// this card should be automatically set as the default, as there are no other saved pms
XCTAssertFalse(app.switches["Set as default payment method"].waitForExistence(timeout: 3))

// Complete payment
app.buttons["Pay $50.99"].waitForExistenceAndTap()
Expand Down Expand Up @@ -2854,8 +2852,7 @@ class PaymentSheetDefaultSPMUITests: PaymentSheetUITestCase {
saveThisCardToggle.tap()
XCTAssertTrue(saveThisCardToggle.isSelected)
// do not set this card as default
setDefaultToggle = app.switches["Set as default payment method"]
XCTAssertFalse(setDefaultToggle.isSelected)
XCTAssertFalse(app.switches["Set as default payment method"].isSelected)
Copy link
Collaborator

Choose a reason for hiding this comment

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

Do we need this? Is the "Set as default payment method" even visible?

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

We previously saved a card, so the "Set as default payment method" checkbox is shown when we try adding another card. Since the new card wouldn't be the only saved payment method, it wouldn't automatically be set as the default.


// Complete payment
app.buttons["Pay $50.99"].waitForExistenceAndTap()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,20 +13,23 @@ import StripePayments
import UIKit

extension PaymentSheetFormFactory {
func makeCard(cardBrandChoiceEligible: Bool = false, showSetAsDefaultCheckbox: Bool) -> PaymentMethodElement {
func makeCard(cardBrandChoiceEligible: Bool = false) -> PaymentMethodElement {
let showLinkInlineSignup = showLinkInlineCardSignup
var defaultCheckbox: PaymentMethodElementWrapper<CheckboxElement>?
if showSetAsDefaultCheckbox {
defaultCheckbox = makeDefaultCheckbox()
}
let defaultCheckbox: Element? = {
guard allowsSetAsDefaultPM else {
return nil
}
let defaultCheckbox = makeDefaultCheckbox()
return shouldDisplayDefaultCheckbox ? defaultCheckbox : SectionElement.HiddenElement(defaultCheckbox)
}()
let saveCheckbox = makeSaveCheckbox(
label: String.Localized.save_payment_details_for_future_$merchant_payments(
merchantDisplayName: configuration.merchantDisplayName
)
) { selected in
defaultCheckbox?.element.checkboxButton.isHidden = !selected
defaultCheckbox?.view.isHidden = !selected
}
defaultCheckbox?.element.checkboxButton.isHidden = !saveCheckbox.element.isSelected
defaultCheckbox?.view.isHidden = !saveCheckbox.element.isSelected

// Make section titled "Contact Information" w/ phone and email if merchant requires it.
let optionalPhoneAndEmailInformationSection: SectionElement? = {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,8 @@ class PaymentSheetFormFactory {
let countryCode: String?
let cardBrandChoiceEligible: Bool
let savePaymentMethodConsentBehavior: SavePaymentMethodConsentBehavior
let showSetAsDefaultCheckbox: Bool
let allowsSetAsDefaultPM: Bool
let isFirstSavedPaymentMethod: Bool
let analyticsHelper: PaymentSheetAnalyticsHelper?
let paymentMethodIncentive: PaymentMethodIncentive?

Expand All @@ -55,6 +56,10 @@ class PaymentSheetFormFactory {
}
}

var shouldDisplayDefaultCheckbox: Bool {
return allowsSetAsDefaultPM && !isFirstSavedPaymentMethod
}

var theme: ElementsAppearance {
return configuration.appearance.asElementsTheme
}
Expand Down Expand Up @@ -108,7 +113,8 @@ class PaymentSheetFormFactory {
isSettingUp: intent.isSettingUp,
countryCode: elementsSession.countryCode(overrideCountry: configuration.overrideCountry),
savePaymentMethodConsentBehavior: elementsSession.savePaymentMethodConsentBehavior,
showSetAsDefaultCheckbox: elementsSession.paymentMethodSetAsDefaultForPaymentSheet,
allowsSetAsDefaultPM: elementsSession.paymentMethodSetAsDefaultForPaymentSheet,
isFirstSavedPaymentMethod: elementsSession.customer?.paymentMethods.isEmpty ?? true,
analyticsHelper: analyticsHelper,
paymentMethodIncentive: elementsSession.incentive)
}
Expand All @@ -126,7 +132,8 @@ class PaymentSheetFormFactory {
isSettingUp: Bool,
countryCode: String?,
savePaymentMethodConsentBehavior: SavePaymentMethodConsentBehavior,
showSetAsDefaultCheckbox: Bool = false,
allowsSetAsDefaultPM: Bool = false,
isFirstSavedPaymentMethod: Bool = true,
analyticsHelper: PaymentSheetAnalyticsHelper?,
paymentMethodIncentive: PaymentMethodIncentive?
) {
Expand All @@ -147,7 +154,8 @@ class PaymentSheetFormFactory {
self.countryCode = countryCode
self.cardBrandChoiceEligible = cardBrandChoiceEligible
self.savePaymentMethodConsentBehavior = savePaymentMethodConsentBehavior
self.showSetAsDefaultCheckbox = showSetAsDefaultCheckbox
self.allowsSetAsDefaultPM = allowsSetAsDefaultPM
self.isFirstSavedPaymentMethod = isFirstSavedPaymentMethod
self.analyticsHelper = analyticsHelper
self.paymentMethodIncentive = paymentMethodIncentive
}
Expand All @@ -164,9 +172,9 @@ class PaymentSheetFormFactory {
// We have two ways to create the form for a payment method
// 1. Custom, one-off forms
if paymentMethod == .card {
return makeCard(cardBrandChoiceEligible: cardBrandChoiceEligible, showSetAsDefaultCheckbox: showSetAsDefaultCheckbox)
return makeCard(cardBrandChoiceEligible: cardBrandChoiceEligible)
} else if paymentMethod == .USBankAccount {
return makeUSBankAccount(merchantName: configuration.merchantDisplayName, showSetAsDefaultCheckbox: showSetAsDefaultCheckbox)
return makeUSBankAccount(merchantName: configuration.merchantDisplayName)
} else if paymentMethod == .UPI {
return makeUPI()
} else if paymentMethod == .cashApp && isSettingUp {
Expand Down Expand Up @@ -374,7 +382,7 @@ extension PaymentSheetFormFactory {
let element = CheckboxElement(
theme: configuration.appearance.asElementsTheme,
label: String.Localized.set_as_default_payment_method,
isSelectedByDefault: false,
isSelectedByDefault: isFirstSavedPaymentMethod,
didToggle: didToggle
)
return PaymentMethodElementWrapper(element) { checkbox, params in
Expand Down Expand Up @@ -556,12 +564,15 @@ extension PaymentSheetFormFactory {
)
}

func makeUSBankAccount(merchantName: String, showSetAsDefaultCheckbox: Bool) -> PaymentMethodElement {
func makeUSBankAccount(merchantName: String) -> PaymentMethodElement {
let isSaving = BoolReference()
var defaultCheckbox: PaymentMethodElementWrapper<CheckboxElement>?
if showSetAsDefaultCheckbox {
defaultCheckbox = makeDefaultCheckbox()
}
let defaultCheckbox: Element? = {
guard allowsSetAsDefaultPM else {
return nil
}
let defaultCheckbox = makeDefaultCheckbox()
return shouldDisplayDefaultCheckbox ? defaultCheckbox : SectionElement.HiddenElement(defaultCheckbox)
}()
let saveCheckbox = makeSaveCheckbox(
label: String(
format: .Localized.save_this_account_for_future_payments,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ final class USBankAccountPaymentMethodElement: ContainerElement {
private let bankInfoSectionElement: SectionElement
private let bankInfoView: BankAccountInfoView
private let saveCheckboxElement: PaymentMethodElementWrapper<CheckboxElement>?
private let defaultCheckboxElement: PaymentMethodElement?
private let defaultCheckboxElement: Element?
private var savingAccount: BoolReference
private let theme: ElementsAppearance

Expand Down Expand Up @@ -89,7 +89,7 @@ final class USBankAccountPaymentMethodElement: ContainerElement {
phoneElement: PaymentMethodElementWrapper<PhoneNumberElement>?,
addressElement: PaymentMethodElementWrapper<AddressSectionElement>?,
saveCheckboxElement: PaymentMethodElementWrapper<CheckboxElement>?,
defaultCheckboxElement: PaymentMethodElement?,
defaultCheckboxElement: Element?,
savingAccount: BoolReference,
merchantName: String,
initialLinkedBank: FinancialConnectionsLinkedBank?,
Expand Down Expand Up @@ -132,7 +132,7 @@ final class USBankAccountPaymentMethodElement: ContainerElement {
addressElement,
bankInfoSectionElement,
saveCheckboxElement,
defaultCheckboxElement
defaultCheckboxElement,
]
let autoSectioningElements = allElements.compactMap { $0 }
self.formElement = FormElement(autoSectioningElements: autoSectioningElements, theme: theme)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,7 @@ final class AddPaymentMethodViewControllerSnapshotTests: STPSnapshotTestCase {
let sut = AddPaymentMethodViewController(
intent: intent,
// ...and a "Set as default" checkbox...
elementsSession: ._testValue(intent: intent, allowsSetAsDefaultPM: true),
elementsSession: ._testValue(intent: intent, paymentMethods: [STPPaymentMethod._testCardJSON], allowsSetAsDefaultPM: true),
configuration: config,
previousCustomerInput: previousCustomerInput,
paymentMethodTypes: [.stripe(.payPal), .stripe(.card), .stripe(.cashApp)],
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -182,6 +182,8 @@ extension STPElementsSession {
intent: Intent,
linkMode: LinkMode? = nil,
linkFundingSources: Set<LinkSettings.FundingSource> = [],
defaultPaymentMethod: String? = nil,
paymentMethods: [[AnyHashable: Any]]? = nil,
allowsSetAsDefaultPM: Bool = false
) -> STPElementsSession {
let paymentMethodTypes: [String] = {
Expand Down Expand Up @@ -213,7 +215,9 @@ extension STPElementsSession {
paymentMethodTypes: paymentMethodTypes,
customerSessionData: customerSessionData,
linkMode: linkMode,
linkFundingSources: linkFundingSources
linkFundingSources: linkFundingSources,
defaultPaymentMethod: defaultPaymentMethod,
paymentMethods: paymentMethods
)
}
}
Expand Down Expand Up @@ -247,19 +251,21 @@ extension Intent {
}

extension STPPaymentMethod {
static let _testCardJSON = [
"id": "pm_123card",
"type": "card",
"card": [
"last4": "4242",
"brand": "visa",
"fingerprint": "B8XXs2y2JsVBtB9f",
"networks": ["available": ["visa"]],
"exp_month": "01",
"exp_year": "2040",
],
] as [AnyHashable: Any]

static func _testCard() -> STPPaymentMethod {
return STPPaymentMethod.decodedObject(fromAPIResponse: [
"id": "pm_123card",
"type": "card",
"card": [
"last4": "4242",
"brand": "visa",
"fingerprint": "B8XXs2y2JsVBtB9f",
"networks": ["available": ["visa"]],
"exp_month": "01",
"exp_year": "2040",
],
])!
return STPPaymentMethod.decodedObject(fromAPIResponse: _testCardJSON)!
}

static func _testCardAmex() -> STPPaymentMethod {
Expand Down
Loading