From 7486b059224b32f05baf3ff7aa736e25556c2cfa Mon Sep 17 00:00:00 2001 From: Mat Schmid Date: Thu, 14 Nov 2024 15:03:46 -0500 Subject: [PATCH] [CONSUMERBANK-528] Handle invalid phone numbers in Link signup more gracefully --- .../LinkLogin/LinkLoginViewController.swift | 17 ++++++++++++- .../LinkSignupFormView.swift | 1 + .../PhoneTextField.swift | 24 +++++++++++++++++-- 3 files changed, 39 insertions(+), 3 deletions(-) diff --git a/StripeFinancialConnections/StripeFinancialConnections/Source/Native/LinkLogin/LinkLoginViewController.swift b/StripeFinancialConnections/StripeFinancialConnections/Source/Native/LinkLogin/LinkLoginViewController.swift index 11740e2f6a4..7a5b28b2aaa 100644 --- a/StripeFinancialConnections/StripeFinancialConnections/Source/Native/LinkLogin/LinkLoginViewController.swift +++ b/StripeFinancialConnections/StripeFinancialConnections/Source/Native/LinkLogin/LinkLoginViewController.swift @@ -179,6 +179,7 @@ final class LinkLoginViewController: UIViewController { } } else { formView?.showAndEditPhoneNumberFieldIfNeeded() + setContinueWithLinkButtonDisabledState() } case .failure(let error): self.delegate?.linkLoginViewController(self, didReceiveTerminalError: error) @@ -210,7 +211,21 @@ final class LinkLoginViewController: UIViewController { case .success(let response): self.delegate?.linkLoginViewController(self, signedUpAttachedAndSynchronized: response) case .failure(let error): - self.delegate?.linkLoginViewController(self, didReceiveTerminalError: error) + func completeWithTerminalError() { + self.delegate?.linkLoginViewController(self, didReceiveTerminalError: error) + } + + guard let stripeError = error as? StripeError, case .apiError(let stripeAPIError) = stripeError else { + return completeWithTerminalError() + } + + // Hack to determine if the error is related to the phone number. + // If so, show a generic error message under the phone textfield. + if let errorMessage = stripeAPIError.message, errorMessage.contains("phone") { + formView.phoneTextField.setErrorText(PhoneTextField.LocalizedStrings.invalidPhoneNumber) + } else { + completeWithTerminalError() + } } } } diff --git a/StripeFinancialConnections/StripeFinancialConnections/Source/Native/NetworkingLinkSignupPane/LinkSignupFormView.swift b/StripeFinancialConnections/StripeFinancialConnections/Source/Native/NetworkingLinkSignupPane/LinkSignupFormView.swift index b37e8cb2b71..95070e55009 100644 --- a/StripeFinancialConnections/StripeFinancialConnections/Source/Native/NetworkingLinkSignupPane/LinkSignupFormView.swift +++ b/StripeFinancialConnections/StripeFinancialConnections/Source/Native/NetworkingLinkSignupPane/LinkSignupFormView.swift @@ -194,6 +194,7 @@ extension LinkSignupFormView: PhoneTextFieldDelegate { _ phoneTextField: PhoneTextField, didChangePhoneNumber phoneNumber: PhoneNumber? ) { + phoneTextField.clearErrorText() delegate?.linkSignupFormViewDidUpdateFields(self) } } diff --git a/StripeFinancialConnections/StripeFinancialConnections/Source/Native/NetworkingLinkSignupPane/PhoneTextField.swift b/StripeFinancialConnections/StripeFinancialConnections/Source/Native/NetworkingLinkSignupPane/PhoneTextField.swift index 74839010602..24a1e437c71 100644 --- a/StripeFinancialConnections/StripeFinancialConnections/Source/Native/NetworkingLinkSignupPane/PhoneTextField.swift +++ b/StripeFinancialConnections/StripeFinancialConnections/Source/Native/NetworkingLinkSignupPane/PhoneTextField.swift @@ -19,9 +19,21 @@ protocol PhoneTextFieldDelegate: AnyObject { final class PhoneTextField: UIView { + enum LocalizedStrings { + static let textfieldPlaceholder = STPLocalizedString( + "Phone number", + "The title of a user-input-field that appears when a user is signing up to Link (a payment service). It instructs user to type a phone number." + ) + + static let invalidPhoneNumber = STPLocalizedString( + "Your mobile phone number is invalid.", + "An error message that instructs the user to keep typing their phone number in a user-input field." + ) + } + fileprivate lazy var textField: RoundedTextField = { let textField = RoundedTextField( - placeholder: STPLocalizedString("Phone number", "The title of a user-input-field that appears when a user is signing up to Link (a payment service). It instructs user to type a phone number."), + placeholder: LocalizedStrings.textfieldPlaceholder, showDoneToolbar: true, theme: theme ) @@ -158,13 +170,21 @@ final class PhoneTextField: UIView { if text.isEmpty { // no error message if empty } else { - textField.errorText = STPLocalizedString("Your mobile phone number is incomplete.", "An error message that instructs the user to keep typing their phone number in a user-input field.") + textField.errorText = LocalizedStrings.invalidPhoneNumber } } } delegate?.phoneTextField(self, didChangePhoneNumber: phoneNumber) } + + func setErrorText(_ errorMessage: String) { + textField.errorText = errorMessage + } + + func clearErrorText() { + textField.errorText = nil + } } // MARK: - RoundedTextFieldDelegate