From 8cccf25344217d561f768aefbf134458f10beb47 Mon Sep 17 00:00:00 2001 From: stechiu Date: Tue, 2 Jul 2024 17:08:44 -0700 Subject: [PATCH 1/8] Add `exceededTimeoutLimit` 3DS error --- .../BraintreeThreeDSecure/BTThreeDSecureError.swift | 7 +++++++ .../BTThreeDSecureV2Provider.swift | 12 ++++++++++-- 2 files changed, 17 insertions(+), 2 deletions(-) diff --git a/Sources/BraintreeThreeDSecure/BTThreeDSecureError.swift b/Sources/BraintreeThreeDSecure/BTThreeDSecureError.swift index b3d407c876..c445354151 100644 --- a/Sources/BraintreeThreeDSecure/BTThreeDSecureError.swift +++ b/Sources/BraintreeThreeDSecure/BTThreeDSecureError.swift @@ -29,6 +29,9 @@ public enum BTThreeDSecureError: Error, CustomNSError, LocalizedError, Equatable /// 8. Deallocated BTThreeDSecureClient case deallocated + /// 9. 3D Secure was idle and exceeded timout limit + case exceededTimeoutLimit + public static var errorDomain: String { "com.braintreepayments.BTThreeDSecureFlowErrorDomain" } @@ -53,6 +56,8 @@ public enum BTThreeDSecureError: Error, CustomNSError, LocalizedError, Equatable return 7 case .deallocated: return 8 + case .exceededTimeoutLimit: + return 9 } } @@ -76,6 +81,8 @@ public enum BTThreeDSecureError: Error, CustomNSError, LocalizedError, Equatable return [NSLocalizedDescriptionKey: "The request could not be serialized."] case .deallocated: return [NSLocalizedDescriptionKey: "BTThreeDSecureClient has been deallocated."] + case .exceededTimeoutLimit: + return [NSLocalizedDescriptionKey: "User exceeded timeout limit."] } } diff --git a/Sources/BraintreeThreeDSecure/BTThreeDSecureV2Provider.swift b/Sources/BraintreeThreeDSecure/BTThreeDSecureV2Provider.swift index 476bdbf1eb..eec112f30a 100644 --- a/Sources/BraintreeThreeDSecure/BTThreeDSecureV2Provider.swift +++ b/Sources/BraintreeThreeDSecure/BTThreeDSecureV2Provider.swift @@ -122,14 +122,22 @@ extension BTThreeDSecureV2Provider: CardinalValidationDelegate { completion: completionHandler ) case .error, .timeout: - let userInfo = [NSLocalizedDescriptionKey: validateResponse.errorDescription] + var userInfo = [NSLocalizedDescriptionKey: validateResponse.errorDescription] var errorCode: Int = BTThreeDSecureError.unknown.errorCode if validateResponse.errorNumber == 1050 { errorCode = BTThreeDSecureError.failedAuthentication("").errorCode + completionHandler(nil, BTThreeDSecureError.failedAuthentication("")) + } + else if validateResponse.actionCode == .timeout { + errorCode = BTThreeDSecureError.exceededTimeoutLimit.errorCode + userInfo = [NSLocalizedDescriptionKey: BTThreeDSecureError.exceededTimeoutLimit.localizedDescription] + completionHandler(nil, BTThreeDSecureError.exceededTimeoutLimit) + } + else { + completionHandler(nil, NSError(domain: BTThreeDSecureError.errorDomain, code: errorCode, userInfo: userInfo)) } apiClient.sendAnalyticsEvent(BTThreeDSecureAnalytics.challengeFailed) - completionHandler(nil, NSError(domain: BTThreeDSecureError.errorDomain, code: errorCode, userInfo: userInfo)) case .cancel: completionHandler(nil, BTThreeDSecureError.canceled) default: From a6a11ace06e536636692c7e99ca1be78958fe9bb Mon Sep 17 00:00:00 2001 From: stechiu Date: Tue, 2 Jul 2024 17:17:01 -0700 Subject: [PATCH 2/8] Added CHANGELOG --- CHANGELOG.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 699352e510..f4014c681b 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,9 @@ # Braintree iOS SDK Release Notes +## unreleased +* BraintreeThreeDSecure + * Add error code and error message for `exceededTimeoutLimit` + ## 6.22.0 (2024-07-02) * BraintreeThreeDSecure * Add `customFields` param to `BTThreeDSecureRequest` From 84bc207d58e9fa0667633a4a14d75235728f3c01 Mon Sep 17 00:00:00 2001 From: Stephanie <127455800+stechiu@users.noreply.github.com> Date: Thu, 11 Jul 2024 10:49:47 -0700 Subject: [PATCH 3/8] Refactored `completionHandler` Co-authored-by: scannillo <35243507+scannillo@users.noreply.github.com> --- Sources/BraintreeThreeDSecure/BTThreeDSecureV2Provider.swift | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Sources/BraintreeThreeDSecure/BTThreeDSecureV2Provider.swift b/Sources/BraintreeThreeDSecure/BTThreeDSecureV2Provider.swift index eec112f30a..85921bfd1b 100644 --- a/Sources/BraintreeThreeDSecure/BTThreeDSecureV2Provider.swift +++ b/Sources/BraintreeThreeDSecure/BTThreeDSecureV2Provider.swift @@ -135,7 +135,7 @@ extension BTThreeDSecureV2Provider: CardinalValidationDelegate { completionHandler(nil, BTThreeDSecureError.exceededTimeoutLimit) } else { - completionHandler(nil, NSError(domain: BTThreeDSecureError.errorDomain, code: errorCode, userInfo: userInfo)) + completionHandler(nil, BTThreeDSecureError.exceededTimeoutLimit) } apiClient.sendAnalyticsEvent(BTThreeDSecureAnalytics.challengeFailed) case .cancel: From 0c9576c09d0aeac2bebde969c591ec2b9df5c69f Mon Sep 17 00:00:00 2001 From: Stephanie <127455800+stechiu@users.noreply.github.com> Date: Thu, 11 Jul 2024 10:49:57 -0700 Subject: [PATCH 4/8] Spacing Co-authored-by: scannillo <35243507+scannillo@users.noreply.github.com> --- .../BraintreeThreeDSecure/BTThreeDSecureV2Provider.swift | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/Sources/BraintreeThreeDSecure/BTThreeDSecureV2Provider.swift b/Sources/BraintreeThreeDSecure/BTThreeDSecureV2Provider.swift index 85921bfd1b..e0f862a5e9 100644 --- a/Sources/BraintreeThreeDSecure/BTThreeDSecureV2Provider.swift +++ b/Sources/BraintreeThreeDSecure/BTThreeDSecureV2Provider.swift @@ -128,13 +128,11 @@ extension BTThreeDSecureV2Provider: CardinalValidationDelegate { if validateResponse.errorNumber == 1050 { errorCode = BTThreeDSecureError.failedAuthentication("").errorCode completionHandler(nil, BTThreeDSecureError.failedAuthentication("")) - } - else if validateResponse.actionCode == .timeout { + } else if validateResponse.actionCode == .timeout { errorCode = BTThreeDSecureError.exceededTimeoutLimit.errorCode userInfo = [NSLocalizedDescriptionKey: BTThreeDSecureError.exceededTimeoutLimit.localizedDescription] completionHandler(nil, BTThreeDSecureError.exceededTimeoutLimit) - } - else { + } else { completionHandler(nil, BTThreeDSecureError.exceededTimeoutLimit) } apiClient.sendAnalyticsEvent(BTThreeDSecureAnalytics.challengeFailed) From eef1ac63c6c091fbd0f89faee239acb92f470041 Mon Sep 17 00:00:00 2001 From: stechiu Date: Tue, 16 Jul 2024 08:41:33 -0700 Subject: [PATCH 5/8] Addressed PR comments --- .../BTThreeDSecureV2Provider.swift | 22 ++++++++++--------- 1 file changed, 12 insertions(+), 10 deletions(-) diff --git a/Sources/BraintreeThreeDSecure/BTThreeDSecureV2Provider.swift b/Sources/BraintreeThreeDSecure/BTThreeDSecureV2Provider.swift index e0f862a5e9..2d22d84c6a 100644 --- a/Sources/BraintreeThreeDSecure/BTThreeDSecureV2Provider.swift +++ b/Sources/BraintreeThreeDSecure/BTThreeDSecureV2Provider.swift @@ -14,6 +14,7 @@ class BTThreeDSecureV2Provider { var lookupResult: BTThreeDSecureResult? = nil var completionHandler: (BTThreeDSecureResult?, Error?) -> Void = { _, _ in } + var errorCode: Int = BTThreeDSecureError.unknown.errorCode // MARK: - Initializer @@ -121,21 +122,22 @@ extension BTThreeDSecureV2Provider: CardinalValidationDelegate { forResult: lookupResult, completion: completionHandler ) - case .error, .timeout: - var userInfo = [NSLocalizedDescriptionKey: validateResponse.errorDescription] - var errorCode: Int = BTThreeDSecureError.unknown.errorCode + case .error: + let errorUserInfo = [NSLocalizedDescriptionKey: validateResponse.errorDescription] if validateResponse.errorNumber == 1050 { errorCode = BTThreeDSecureError.failedAuthentication("").errorCode - completionHandler(nil, BTThreeDSecureError.failedAuthentication("")) - } else if validateResponse.actionCode == .timeout { - errorCode = BTThreeDSecureError.exceededTimeoutLimit.errorCode - userInfo = [NSLocalizedDescriptionKey: BTThreeDSecureError.exceededTimeoutLimit.localizedDescription] - completionHandler(nil, BTThreeDSecureError.exceededTimeoutLimit) - } else { - completionHandler(nil, BTThreeDSecureError.exceededTimeoutLimit) + completionHandler(nil, NSError(domain: BTThreeDSecureError.errorDomain, code: errorCode, userInfo: errorUserInfo)) } apiClient.sendAnalyticsEvent(BTThreeDSecureAnalytics.challengeFailed) + case .timeout: + let timeoutUserInfo = [NSLocalizedDescriptionKey: BTThreeDSecureError.exceededTimeoutLimit.localizedDescription] + + if validateResponse.actionCode == .timeout { + errorCode = BTThreeDSecureError.exceededTimeoutLimit.errorCode + completionHandler(nil, NSError(domain: timeoutUserInfo.description, code: errorCode, userInfo: timeoutUserInfo) + ) + } case .cancel: completionHandler(nil, BTThreeDSecureError.canceled) default: From 7806c3570ccdd3e9613808ed736cdf507109d8c2 Mon Sep 17 00:00:00 2001 From: Stephanie <127455800+stechiu@users.noreply.github.com> Date: Tue, 16 Jul 2024 08:56:28 -0700 Subject: [PATCH 6/8] Addressed PR comment Co-authored-by: Rich Herrera --- Sources/BraintreeThreeDSecure/BTThreeDSecureV2Provider.swift | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/Sources/BraintreeThreeDSecure/BTThreeDSecureV2Provider.swift b/Sources/BraintreeThreeDSecure/BTThreeDSecureV2Provider.swift index 2d22d84c6a..56d7b36e1c 100644 --- a/Sources/BraintreeThreeDSecure/BTThreeDSecureV2Provider.swift +++ b/Sources/BraintreeThreeDSecure/BTThreeDSecureV2Provider.swift @@ -135,8 +135,7 @@ extension BTThreeDSecureV2Provider: CardinalValidationDelegate { if validateResponse.actionCode == .timeout { errorCode = BTThreeDSecureError.exceededTimeoutLimit.errorCode - completionHandler(nil, NSError(domain: timeoutUserInfo.description, code: errorCode, userInfo: timeoutUserInfo) - ) + completionHandler(nil, NSError(domain: timeoutUserInfo.description, code: errorCode, userInfo: timeoutUserInfo)) } case .cancel: completionHandler(nil, BTThreeDSecureError.canceled) From ed185efb0fdeb66bf61f503aee1857846adba24a Mon Sep 17 00:00:00 2001 From: stechiu Date: Tue, 16 Jul 2024 17:08:44 -0700 Subject: [PATCH 7/8] Updated CHANGELOG --- CHANGELOG.md | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index a3083a0638..525b541464 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,12 +1,15 @@ # Braintree iOS SDK Release Notes +## unreleased +* BraintreeThreeDSecure + * Add error code and error message for `exceededTimeoutLimit` + ## 6.23.0 (2024-07-15) * BraintreeShopperInsights (BETA) * Add error when using an invalid authorization type * BraintreeCore * Update `URLOpener.openURL(_:completionHandler:)` protocol method to fix method signature change in Xcode 16 beta 3 (fixes #1359) * BraintreeThreeDSecure - * Add error code and error message for `exceededTimeoutLimit` * Fix bug to conditionally unwrap `customFields` - this caused an error when this value was not set on `BTThreeDSecureRequest` ## 6.22.0 (2024-07-02) From 764789c0c7fdeb99aa01cdd9a7ff63ed6275ea39 Mon Sep 17 00:00:00 2001 From: stechiu Date: Wed, 17 Jul 2024 12:02:35 -0700 Subject: [PATCH 8/8] Reverted changes --- .../BTThreeDSecureV2Provider.swift | 12 +++--------- 1 file changed, 3 insertions(+), 9 deletions(-) diff --git a/Sources/BraintreeThreeDSecure/BTThreeDSecureV2Provider.swift b/Sources/BraintreeThreeDSecure/BTThreeDSecureV2Provider.swift index 2d22d84c6a..cf07d8ad28 100644 --- a/Sources/BraintreeThreeDSecure/BTThreeDSecureV2Provider.swift +++ b/Sources/BraintreeThreeDSecure/BTThreeDSecureV2Provider.swift @@ -14,7 +14,6 @@ class BTThreeDSecureV2Provider { var lookupResult: BTThreeDSecureResult? = nil var completionHandler: (BTThreeDSecureResult?, Error?) -> Void = { _, _ in } - var errorCode: Int = BTThreeDSecureError.unknown.errorCode // MARK: - Initializer @@ -124,20 +123,15 @@ extension BTThreeDSecureV2Provider: CardinalValidationDelegate { ) case .error: let errorUserInfo = [NSLocalizedDescriptionKey: validateResponse.errorDescription] + var errorCode: Int = BTThreeDSecureError.unknown.errorCode if validateResponse.errorNumber == 1050 { errorCode = BTThreeDSecureError.failedAuthentication("").errorCode - completionHandler(nil, NSError(domain: BTThreeDSecureError.errorDomain, code: errorCode, userInfo: errorUserInfo)) } apiClient.sendAnalyticsEvent(BTThreeDSecureAnalytics.challengeFailed) + completionHandler(nil, NSError(domain: BTThreeDSecureError.errorDomain, code: errorCode, userInfo: errorUserInfo)) case .timeout: - let timeoutUserInfo = [NSLocalizedDescriptionKey: BTThreeDSecureError.exceededTimeoutLimit.localizedDescription] - - if validateResponse.actionCode == .timeout { - errorCode = BTThreeDSecureError.exceededTimeoutLimit.errorCode - completionHandler(nil, NSError(domain: timeoutUserInfo.description, code: errorCode, userInfo: timeoutUserInfo) - ) - } + completionHandler(nil, BTThreeDSecureError.exceededTimeoutLimit) case .cancel: completionHandler(nil, BTThreeDSecureError.canceled) default: