Skip to content

Commit

Permalink
remove alternateUpdatePaymentMethodNavigation flag and updated tests (#…
Browse files Browse the repository at this point in the history
…4337)

## Summary
<!-- Simple summary of what was changed. -->
Removed the alternateUpdatePaymentMethodNavigation flag that gated the
new update payment method screen. Now, by default, any payment method
that can be removed or edited (card, US bank account, SEPA debit) will
display an edit icon or chevron (horizontal vs vertical) that will lead
to the new UpdatePaymentMethod screen.
## Motivation
<!-- Why are you making this change? If it's for fixing a bug, if
possible, please include a code snippet or example project that
demonstrates the issue. -->

## Testing
<!-- How was the code tested? Be as specific as possible. -->

## Changelog
<!-- Is this a notable change that affects users? If so, add a line to
`CHANGELOG.md` and prefix the line with one of the following:
    - [Added] for new features.
    - [Changed] for changes in existing functionality.
    - [Deprecated] for soon-to-be removed features.
    - [Removed] for now removed features.
    - [Fixed] for any bug fixes.
    - [Security] in case of vulnerabilities.
-->
[Changed] Changed the edit and remove saved payment method flow so that
tapping 'Edit' displays an icon that leads to a new update payment
method screen
  • Loading branch information
joyceqin-stripe authored Dec 6, 2024
1 parent e5585f7 commit 6a12711
Show file tree
Hide file tree
Showing 39 changed files with 118 additions and 401 deletions.
3 changes: 3 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,6 @@
### PaymentSheet, CustomerSheet
* [Changed] Changed the edit and remove saved payment method flow so that tapping 'Edit' displays an icon that leads to a new update payment method screen that displays payment method details for card (last 4 digits of card number, cvc and expiry date fields), US Bank account (name, email, last 4 digits of bank acocunt), and SEPA debit (name, email, last 4 digits of IBAN).

## 24.1.2 2024-12-05
### PaymentSheet
* [Fixed] Fixed an issue where FlowController returned incorrect `PaymentOptionDisplayData` for Link card brand transactions.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -75,7 +75,6 @@ struct CustomerSheetTestPlayground: View {
SettingView(setting: $playgroundController.settings.autoreload)
TextField("headerTextForSelectionScreen", text: headerTextForSelectionScreenBinding)
SettingView(setting: $playgroundController.settings.allowsRemovalOfLastSavedPaymentMethod)
SettingView(setting: $playgroundController.settings.alternateUpdatePaymentMethodNavigation)
HStack {
Text("Macros").font(.headline)
Spacer()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
//

import Combine
@_spi(STP) @_spi(CustomerSessionBetaAccess) @_spi(CardBrandFilteringBeta) @_spi(AlternateUpdatePaymentMethodNavigation) import StripePaymentSheet
@_spi(STP) @_spi(CustomerSessionBetaAccess) @_spi(CardBrandFilteringBeta) import StripePaymentSheet
import SwiftUI

class CustomerSheetTestPlaygroundController: ObservableObject {
Expand Down Expand Up @@ -147,7 +147,6 @@ class CustomerSheetTestPlaygroundController: ObservableObject {
case .allowVisa:
configuration.cardBrandAcceptance = .allowed(brands: [.visa])
}
configuration.alternateUpdatePaymentMethodNavigation = settings.alternateUpdatePaymentMethodNavigation == .on
return configuration
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -148,12 +148,6 @@ public struct CustomerSheetTestPlaygroundSettings: Codable, Equatable {
case allowVisa
}

enum AlternateUpdatePaymentMethodNavigation: String, PickerEnum {
static let enumName: String = "alternateUpdatePaymentMethodNavigation"
case on
case off
}

var customerMode: CustomerMode
var customerId: String?
var customerKeyType: CustomerKeyType
Expand All @@ -175,7 +169,6 @@ public struct CustomerSheetTestPlaygroundSettings: Codable, Equatable {
var paymentMethodRemoveLast: PaymentMethodRemoveLast
var paymentMethodAllowRedisplayFilters: PaymentMethodAllowRedisplayFilters
var cardBrandAcceptance: CardBrandAcceptance
var alternateUpdatePaymentMethodNavigation: AlternateUpdatePaymentMethodNavigation

static func defaultValues() -> CustomerSheetTestPlaygroundSettings {
return CustomerSheetTestPlaygroundSettings(customerMode: .new,
Expand All @@ -197,8 +190,7 @@ public struct CustomerSheetTestPlaygroundSettings: Codable, Equatable {
paymentMethodRemove: .enabled,
paymentMethodRemoveLast: .enabled,
paymentMethodAllowRedisplayFilters: .always,
cardBrandAcceptance: .all,
alternateUpdatePaymentMethodNavigation: .off)
cardBrandAcceptance: .all)
}

var base64Data: String {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,6 @@ struct PaymentSheetTestPlayground: View {
SettingView(setting: $playgroundController.settings.requireCVCRecollection)
SettingView(setting: $playgroundController.settings.autoreload)
SettingView(setting: $playgroundController.settings.shakeAmbiguousViews)
SettingView(setting: $playgroundController.settings.alternateUpdatePaymentMethodNavigation)
SettingView(setting: $playgroundController.settings.instantDebitsIncentives)
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -444,12 +444,6 @@ struct PaymentSheetTestPlaygroundSettings: Codable, Equatable {
case allowVisa
}

enum AlternateUpdatePaymentMethodNavigation: String, PickerEnum {
static let enumName: String = "alternateUpdatePaymentMethodNavigation"
case on
case off
}

var uiStyle: UIStyle
var layout: Layout
var mode: Mode
Expand Down Expand Up @@ -496,7 +490,6 @@ struct PaymentSheetTestPlaygroundSettings: Codable, Equatable {
var formSheetAction: FormSheetAction
var embeddedViewDisplaysMandateText: DisplaysMandateTextEnabled
var cardBrandAcceptance: CardBrandAcceptance
var alternateUpdatePaymentMethodNavigation: AlternateUpdatePaymentMethodNavigation

static func defaultValues() -> PaymentSheetTestPlaygroundSettings {
return PaymentSheetTestPlaygroundSettings(
Expand Down Expand Up @@ -542,8 +535,7 @@ struct PaymentSheetTestPlaygroundSettings: Codable, Equatable {
collectAddress: .automatic,
formSheetAction: .confirm,
embeddedViewDisplaysMandateText: .on,
cardBrandAcceptance: .all,
alternateUpdatePaymentMethodNavigation: .off)
cardBrandAcceptance: .all)
}

static let nsUserDefaultsKey = "PaymentSheetTestPlaygroundSettings"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ import Contacts
import PassKit
@_spi(STP) import StripeCore
@_spi(STP) import StripePayments
@_spi(CustomerSessionBetaAccess) @_spi(STP) @_spi(PaymentSheetSkipConfirmation) @_spi(ExperimentalAllowsRemovalOfLastSavedPaymentMethodAPI) @_spi(EmbeddedPaymentElementPrivateBeta) @_spi(CardBrandFilteringBeta) @_spi(AlternateUpdatePaymentMethodNavigation) import StripePaymentSheet
@_spi(CustomerSessionBetaAccess) @_spi(STP) @_spi(PaymentSheetSkipConfirmation) @_spi(ExperimentalAllowsRemovalOfLastSavedPaymentMethodAPI) @_spi(EmbeddedPaymentElementPrivateBeta) @_spi(CardBrandFilteringBeta) import StripePaymentSheet
import SwiftUI
import UIKit

Expand Down Expand Up @@ -184,7 +184,6 @@ class PlaygroundController: ObservableObject {
case .allowVisa:
configuration.cardBrandAcceptance = .allowed(brands: [.visa])
}
configuration.alternateUpdatePaymentMethodNavigation = settings.alternateUpdatePaymentMethodNavigation == .on
return configuration
}

Expand Down Expand Up @@ -272,7 +271,6 @@ class PlaygroundController: ObservableObject {
case .allowVisa:
configuration.cardBrandAcceptance = .allowed(brands: [.visa])
}
configuration.alternateUpdatePaymentMethodNavigation = settings.alternateUpdatePaymentMethodNavigation == .on
return configuration
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -475,7 +475,6 @@ class CustomerSheetUITest: XCTestCase {

func testCardBrandChoiceUpdateAndRemove() {
var settings = CustomerSheetTestPlaygroundSettings.defaultValues()
settings.alternateUpdatePaymentMethodNavigation = .on
settings.merchantCountryCode = .FR
settings.customerMode = .returning

Expand Down Expand Up @@ -552,7 +551,8 @@ class CustomerSheetUITest: XCTestCase {
XCTAssertTrue(app.staticTexts["Done"].waitForExistence(timeout: 1)) // Sanity check "Done" button is there

// Remove one saved PM
XCTAssertNotNil(scroll(collectionView: app.collectionViews.firstMatch, toFindButtonWithId: "CircularButton.Remove")?.tap())
XCTAssertNotNil(scroll(collectionView: app.collectionViews.firstMatch, toFindButtonWithId: "CircularButton.Edit")?.tap())
app.buttons["Remove"].waitForExistenceAndTap()
XCTAssertTrue(app.alerts.buttons["Remove"].waitForExistenceAndTap())

// Sleep for 1 second to ensure animation has been completed
Expand All @@ -573,7 +573,11 @@ class CustomerSheetUITest: XCTestCase {
XCTAssertTrue(app.staticTexts["Done"].waitForExistence(timeout: 1)) // Sanity check "Done" button is there

// Remove the 4242 saved PM
XCTAssertNotNil(scroll(collectionView: app.collectionViews.firstMatch, toFindButtonWithId: "CircularButton.Remove")?.tap())
// circularEditButton shows up in the view hierarchy, but it's not actually on the screen or tappable so we scroll a little
let startCoordinate = app.collectionViews.firstMatch.coordinate(withNormalizedOffset: CGVector(dx: 0.9, dy: 0.99))
startCoordinate.press(forDuration: 0.1, thenDragTo: app.collectionViews.firstMatch.coordinate(withNormalizedOffset: CGVector(dx: 0.1, dy: 0.99)))
XCTAssertTrue(app.buttons.matching(identifier: "CircularButton.Edit").element(boundBy: 1).waitForExistenceAndTap())
app.buttons["Remove"].waitForExistenceAndTap()
XCTAssertTrue(app.alerts.buttons["Remove"].waitForExistenceAndTap())

// Wait for alert view to disappear and removal animation to finish
Expand Down Expand Up @@ -623,7 +627,6 @@ class CustomerSheetUITest: XCTestCase {
// Assert there are no remove buttons on each tile and the update screen
XCTAssertNil(scroll(collectionView: app.collectionViews.firstMatch, toFindButtonWithId: "CircularButton.Remove"))
XCTAssertTrue(app.buttons["CircularButton.Edit"].waitForExistenceAndTap(timeout: timeout))
XCTAssertFalse(app.buttons["Remove"].exists)

// Dismiss Sheet
app.buttons["Back"].waitForExistenceAndTap(timeout: timeout)
Expand Down Expand Up @@ -658,7 +661,6 @@ class CustomerSheetUITest: XCTestCase {
// Assert there are no remove buttons on each tile and the update screen
XCTAssertNil(scroll(collectionView: app.collectionViews.firstMatch, toFindButtonWithId: "CircularButton.Remove"))
XCTAssertTrue(app.buttons["CircularButton.Edit"].waitForExistenceAndTap(timeout: timeout))
XCTAssertFalse(app.buttons["Remove"].exists)

// Dismiss Sheet
app.buttons["Back"].waitForExistenceAndTap(timeout: timeout)
Expand Down Expand Up @@ -695,8 +697,9 @@ class CustomerSheetUITest: XCTestCase {
}

func removeFirstPaymentMethodInList(alertBody: String = "Visa •••• 4242") {
let removeButton1 = app.buttons["Remove"].firstMatch
removeButton1.tap()
let editButton = app.buttons["Edit"].firstMatch
editButton.tap()
app.buttons["Remove"].waitForExistenceAndTap()
dismissAlertView(alertBody: alertBody, alertTitle: "Remove card?", buttonToTap: "Remove")
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -309,7 +309,7 @@ class EmbeddedUITests: PaymentSheetUITestCase {
// Switch from 1001 to 4242
app.buttons["View more"].waitForExistenceAndTap()
app.buttons["Edit"].waitForExistenceAndTap()
app.buttons["CircularButton.Edit"].waitForExistenceAndTap()
app.buttons["chevron"].firstMatch.waitForExistenceAndTap()
app.otherElements["Card Brand Dropdown"].waitForExistenceAndTap()
app.pickerWheels.firstMatch.swipeUp()
app.buttons["Done"].waitForExistenceAndTap()
Expand Down Expand Up @@ -355,7 +355,8 @@ class EmbeddedUITests: PaymentSheetUITestCase {
// Remove selected 4242 card
app.buttons["View more"].waitForExistenceAndTap()
app.buttons["Edit"].waitForExistenceAndTap()
app.buttons["CircularButton.Remove"].firstMatch.waitForExistenceAndTap()
app.buttons["chevron"].firstMatch.waitForExistenceAndTap()
app.buttons["Remove"].waitForExistenceAndTap()
dismissAlertView(alertBody: "Visa •••• 4242", alertTitle: "Remove card?", buttonToTap: "Remove")
app.buttons["Done"].waitForExistenceAndTap()

Expand All @@ -367,21 +368,21 @@ class EmbeddedUITests: PaymentSheetUITestCase {

// Remove 6789 & verify
app.buttons["Edit"].waitForExistenceAndTap()
app.buttons["CircularButton.Remove"].firstMatch.waitForExistenceAndTap()
app.buttons["Remove"].waitForExistenceAndTap()
dismissAlertView(alertBody: "Bank account •••• 6789", alertTitle: "Remove bank account?", buttonToTap: "Remove")

XCTAssertFalse(card4242Button.waitForExistence(timeout: 3.0))
XCTAssertFalse(bank6789Button.waitForExistence(timeout: 3.0))
XCTAssertFalse(app.textViews["By continuing, you agree to authorize payments pursuant to these terms."].waitForExistence(timeout: 3.0))
let events = analyticsLog.compactMap({ $0[string: "event"] })
.filter({ !$0.starts(with: "luxe") })
.suffix(5)
.suffix(7)

XCTAssertEqual(
events,
["mc_embedded_paymentoption_savedpm_select",
"mc_carousel_payment_method_tapped", "mc_embedded_paymentoption_removed",
"mc_carousel_payment_method_tapped", "mc_embedded_paymentoption_removed",
"mc_carousel_payment_method_tapped", "mc_open_edit_screen", "mc_embedded_paymentoption_removed",
"mc_carousel_payment_method_tapped", "mc_open_edit_screen", "mc_embedded_paymentoption_removed",
]
)
}
Expand Down Expand Up @@ -425,7 +426,8 @@ class EmbeddedUITests: PaymentSheetUITestCase {
// Remove bank acct. while it isn't selected
app.buttons["View more"].waitForExistenceAndTap()
app.buttons["Edit"].waitForExistenceAndTap()
app.buttons["CircularButton.Remove"].firstMatch.waitForExistenceAndTap()
app.buttons["chevron"].firstMatch.waitForExistenceAndTap()
app.buttons["Remove"].waitForExistenceAndTap()
dismissAlertView(alertBody: "Bank account •••• 6789", alertTitle: "Remove bank account?", buttonToTap: "Remove")
app.buttons["Done"].waitForExistenceAndTap()

Expand All @@ -438,7 +440,7 @@ class EmbeddedUITests: PaymentSheetUITestCase {

// Remove 4242
app.buttons["Edit"].waitForExistenceAndTap()
app.buttons["CircularButton.Remove"].firstMatch.waitForExistenceAndTap()
app.buttons["Remove"].waitForExistenceAndTap()
dismissAlertView(alertBody: "Visa •••• 4242", alertTitle: "Remove card?", buttonToTap: "Remove")

XCTAssertFalse(card4242Button.waitForExistence(timeout: 3.0))
Expand Down Expand Up @@ -482,7 +484,8 @@ class EmbeddedUITests: PaymentSheetUITestCase {
// Delete one payment method so we only have one left, we should not auto select the last remaining saved PM
XCTAssertTrue(app.buttons["View more"].waitForExistenceAndTap())
XCTAssertTrue(app.buttons["Edit"].waitForExistenceAndTap())
XCTAssertTrue(app.buttons["CircularButton.Remove"].firstMatch.waitForExistenceAndTap())
XCTAssertTrue(app.buttons["chevron"].firstMatch.waitForExistenceAndTap())
XCTAssertTrue(app.buttons["Remove"].waitForExistenceAndTap())
dismissAlertView(alertBody: "Visa •••• 4242", alertTitle: "Remove card?", buttonToTap: "Remove")
XCTAssertTrue(app.buttons["Done"].waitForExistenceAndTap())

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1027,7 +1027,6 @@ class PaymentSheetStandardLPMUICBCTests: PaymentSheetStandardLPMUICase {

func testCardBrandChoiceUpdateAndRemove() {
var settings = PaymentSheetTestPlaygroundSettings.defaultValues()
settings.alternateUpdatePaymentMethodNavigation = .on
settings.merchantCountryCode = .FR
settings.currency = .eur
settings.customerMode = .returning
Expand Down
Loading

0 comments on commit 6a12711

Please sign in to comment.