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

Saved SEPA support #2908

Merged
merged 21 commits into from
Oct 19, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
21 commits
Select commit Hold shift + click to select a range
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
4 changes: 4 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,7 @@
## X.Y.Z 2023-XX-YY
### PaymentSheet
* [Added] Saved SEPA payment methods are now displayed to the customer for reuse, similar to saved cards.

## 23.17.2 2023-10-16
### PaymentsUI
* [Fixed] An issue with `STPPaymentCardTextField`, where the card params were not updated after deleting an empty sub field.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1140,6 +1140,13 @@ class PaymentSheetSnapshotTests: FBSnapshotTestCase {
},
fileMock: .saved_payment_methods_200
)
stubPaymentMethods(
stubRequestCallback: { urlRequest in
return urlRequest.url?.absoluteString.contains("/v1/payment_methods") ?? false
&& urlRequest.url?.absoluteString.contains("type=sepa_debit") ?? false
},
fileMock: .saved_payment_methods_200
)
stubCustomers()
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1274,6 +1274,78 @@ class PaymentSheetStandardLPMUITests: PaymentSheetUITestCase {

XCTAssertTrue(app.staticTexts["Success!"].waitForExistence(timeout: 15.0))
}

func testSavedSEPADebitPaymentMethod_FlowController_ShowsMandate() {
var settings = PaymentSheetTestPlaygroundSettings.defaultValues()
settings.uiStyle = .flowController
settings.customerMode = .new
settings.applePayEnabled = .off // disable Apple Pay
settings.mode = .setup
settings.allowsDelayedPMs = .on
loadPlayground(app, settings)

let paymentMethodButton = app.buttons["Payment method"]
XCTAssertTrue(paymentMethodButton.waitForExistence(timeout: 60.0))
paymentMethodButton.tap()

// Save SEPA
app.buttons["+ Add"].waitForExistenceAndTap()
guard let sepa = scroll(collectionView: app.collectionViews.firstMatch, toFindCellWithId: "SEPA Debit") else {
XCTFail("Couldn't find SEPA")
return
}
sepa.tap()

app.textFields["Full name"].tap()
app.typeText("John Doe" + XCUIKeyboardKey.return.rawValue)
app.typeText("[email protected]" + XCUIKeyboardKey.return.rawValue)
app.typeText("AT611904300234573201" + XCUIKeyboardKey.return.rawValue)
app.textFields["Address line 1"].tap()
app.typeText("510 Townsend St" + XCUIKeyboardKey.return.rawValue)
app.typeText("Floor 3" + XCUIKeyboardKey.return.rawValue)
app.typeText("San Francisco" + XCUIKeyboardKey.return.rawValue)
app.textFields["ZIP"].tap()
app.typeText("94102" + XCUIKeyboardKey.return.rawValue)
app.buttons["Continue"].tap()
app.buttons["Confirm"].tap()
XCTAssertTrue(app.staticTexts["Success!"].waitForExistence(timeout: 10.0))

// Reload w/ same customer
reload(app, settings: settings)
// Unfortunately, the next time you check out, Link is still selected by default.
// Select the saved SEPA PM to make it the default and make sure we can still check out successfully.
paymentMethodButton.tap()
app.buttons["••••3201"].waitForExistenceAndTap()
XCTAssertTrue(app.otherElements.matching(identifier: "mandatetextview").element.exists)
app.buttons["Continue"].tap()
app.buttons["Confirm"].tap()
XCTAssertTrue(app.staticTexts["Success!"].waitForExistence(timeout: 10.0))

// Reload w/ same customer
reload(app, settings: settings)
// This time, expect SEPA to be pre-selected as the default
XCTAssertEqual(paymentMethodButton.label, "••••3201")
// Tapping confirm without presenting flowcontroller should show the mandate
app.buttons["Confirm"].tap()
XCTAssertTrue(app.otherElements.matching(identifier: "mandatetextview").element.waitForExistence(timeout: 1))
// Tapping out should cancel the payment
app.tap()
XCTAssertTrue(app.staticTexts["Payment canceled."].waitForExistence(timeout: 10.0))
// Tapping confirm again and hitting continue should confirm the payment
app.buttons["Confirm"].tap()
app.buttons["Continue"].tap()
XCTAssertTrue(app.staticTexts["Success!"].waitForExistence(timeout: 10.0))

// Reload w/ same customer
reload(app, settings: settings)
// If you present the flowcontroller and see the mandate...
app.buttons["••••3201"].waitForExistenceAndTap()
XCTAssertTrue(app.otherElements.matching(identifier: "mandatetextview").element.exists)
// ...you shouldn't see the mandate again when you confirm
app.buttons["Continue"].tap()
app.buttons["Confirm"].tap()
XCTAssertTrue(app.staticTexts["Success!"].waitForExistence(timeout: 10.0))
}
}

class PaymentSheetDeferredUITests: PaymentSheetUITestCase {
Expand Down
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Original file line number Diff line number Diff line change
Expand Up @@ -77,7 +77,7 @@ class PaymentSheetImageLibrary {

extension STPCardBrand {
/// Returns a borderless image of the card brand's logo
func makeCarouselImage() -> UIImage {
func makeSavedPaymentMethodCellImage() -> UIImage {
let imageName: String
switch self {
case .JCB:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -410,7 +410,7 @@ extension PaymentSheet {
switch stpPaymentMethodType {
case .card:
return []
case .USBankAccount:
case .USBankAccount, .SEPADebit:
return [.userSupportsDelayedPaymentMethods]
default:
return [.unsupportedForReuse]
Expand Down
Loading