From 2a6b3120a1bca2cdc65e5a91482c575665ca5409 Mon Sep 17 00:00:00 2001 From: Martin Alleus Date: Tue, 19 Nov 2024 09:58:21 +0100 Subject: [PATCH] Using server side problem node for ClientAppLaunchFailed error --- .../Api/SwedbankPayAPIEnpointRouter.swift | 10 ++++++++-- .../Classes/SwedbankPayPaymentSession.swift | 18 ++++++++---------- .../PaymentSessionProblem.swift | 2 -- 3 files changed, 16 insertions(+), 14 deletions(-) diff --git a/SwedbankPaySDK/Classes/Api/SwedbankPayAPIEnpointRouter.swift b/SwedbankPaySDK/Classes/Api/SwedbankPayAPIEnpointRouter.swift index 6583eee..51ee0f0 100644 --- a/SwedbankPaySDK/Classes/Api/SwedbankPayAPIEnpointRouter.swift +++ b/SwedbankPaySDK/Classes/Api/SwedbankPayAPIEnpointRouter.swift @@ -23,6 +23,12 @@ struct Endpoint { let method: String? } +enum FailPaymentAttemptProblemType: String { + case userCancelled = "UserCancelled" + case technicalError = "TechnicalError" + case clientAppLaunchFailed = "ClientAppLaunchFailed" +} + enum EnpointRouter { case expandMethod(instrument: SwedbankPaySDK.PaymentAttemptInstrument) case startPaymentAttempt(instrument: SwedbankPaySDK.PaymentAttemptInstrument, culture: String?) @@ -34,7 +40,7 @@ enum EnpointRouter { case abortPayment case attemptPayload(paymentPayload: String) case customizePayment(instrument: SwedbankPaySDK.PaymentAttemptInstrument?, paymentMethod: String?, restrictToPaymentMethods: [String]?) - case failPaymentAttempt(problemType: String, errorCode: String?) + case failPaymentAttempt(problemType: FailPaymentAttemptProblemType, errorCode: String?) } protocol EndpointRouterProtocol { @@ -145,7 +151,7 @@ struct SwedbankPayAPIEnpointRouter: EndpointRouterProtocol { "restrictToPaymentMethods": nil] } case .failPaymentAttempt(let problemType, let errorCode): - return ["problemType": problemType, + return ["problemType": problemType.rawValue, "errorCode": errorCode] default: return nil diff --git a/SwedbankPaySDK/Classes/SwedbankPayPaymentSession.swift b/SwedbankPaySDK/Classes/SwedbankPayPaymentSession.swift index 0e45603..9c35256 100644 --- a/SwedbankPaySDK/Classes/SwedbankPayPaymentSession.swift +++ b/SwedbankPaySDK/Classes/SwedbankPayPaymentSession.swift @@ -352,7 +352,7 @@ public extension SwedbankPaySDK { } } - private func launchClientApp(task: IntegrationTask) { + private func launchClientApp(task: IntegrationTask, failPaymentAttemptOperation: OperationOutputModel) { guard let href = task.href, var components = URLComponents(string: href) else { self.delegate?.sdkProblemOccurred(problem: .internalInconsistencyError) @@ -375,15 +375,12 @@ public extension SwedbankPaySDK { if let url = components.url { DispatchQueue.main.async { UIApplication.shared.open(url) { complete in + self.instrument = nil + if complete { self.hasLaunchClientAppURLs.append(url) - self.instrument = nil } else { - self.delegate?.sdkProblemOccurred(problem: .clientAppLaunchFailed) - - BeaconService.shared.log(type: .sdkCallbackInvoked(name: "sdkProblemOccurred", - succeeded: self.delegate != nil, - values: ["problem": SwedbankPaySDK.PaymentSessionProblem.clientAppLaunchFailed.rawValue])) + self.makeRequest(router: .failPaymentAttempt(problemType: .clientAppLaunchFailed, errorCode: nil), operation: failPaymentAttemptOperation) } BeaconService.shared.log(type: .launchClientApp(values: ["callbackUrl": self.orderInfo?.paymentUrl?.absoluteString ?? "", @@ -410,9 +407,9 @@ public extension SwedbankPaySDK { case .success(let paymentOutputModel): self.sessionOperationHandling(paymentOutputModel: paymentOutputModel, culture: paymentOutputModel.paymentSession.culture) case .failure(ApplePayError.userCancelled): - self.makeRequest(router: .failPaymentAttempt(problemType: "UserCancelled", errorCode: ""), operation: failPaymentAttemptOperation) + self.makeRequest(router: .failPaymentAttempt(problemType: .userCancelled, errorCode: nil), operation: failPaymentAttemptOperation) case .failure(let error): - self.makeRequest(router: .failPaymentAttempt(problemType: "TechnicalError", errorCode: error.localizedDescription), operation: failPaymentAttemptOperation) + self.makeRequest(router: .failPaymentAttempt(problemType: .technicalError, errorCode: error.localizedDescription), operation: failPaymentAttemptOperation) } } } @@ -528,10 +525,11 @@ public extension SwedbankPaySDK { self.instrument = nil } else if let launchClientApp = operations.first(where: { $0.firstTask(withRel: .launchClientApp) != nil }), let tasks = launchClientApp.firstTask(withRel: .launchClientApp), + let failPayment = paymentOutputModel.paymentSession.methods?.firstMethod(withName: AvailableInstrument.swish(prefills: nil).paymentMethod)?.operations?.firstOperation(withRel: .failPaymentAttempt), !hasLaunchClientAppURLs.contains(where: { $0.absoluteString.contains(tasks.href ?? "") }) { // We have an active launchClientApp task, and the contained URL isn't in the list of already launched Client App URLs, launch the external app on the device - self.launchClientApp(task: launchClientApp.firstTask(withRel: .launchClientApp)!) + self.launchClientApp(task: tasks, failPaymentAttemptOperation: failPayment) } else if let scaMethodRequest = operations.first(where: { $0.firstTask(withRel: .scaMethodRequest) != nil }), let task = scaMethodRequest.firstTask(withRel: .scaMethodRequest), let href = task.href, diff --git a/SwedbankPaySDK/Classes/SwedbankPaySDK+Extensions/PaymentSessionProblem.swift b/SwedbankPaySDK/Classes/SwedbankPaySDK+Extensions/PaymentSessionProblem.swift index f944a39..108d90c 100644 --- a/SwedbankPaySDK/Classes/SwedbankPaySDK+Extensions/PaymentSessionProblem.swift +++ b/SwedbankPaySDK/Classes/SwedbankPaySDK+Extensions/PaymentSessionProblem.swift @@ -22,7 +22,6 @@ public extension SwedbankPaySDK { case paymentSessionAPIRequestFailed(error: Error, retry: (()->Void)?) case paymentControllerPaymentFailed(error: Error, retry: (()->Void)?) case paymentSession3DSecureViewControllerLoadFailed(error: Error, retry: (()->Void)?) - case clientAppLaunchFailed case internalInconsistencyError case automaticConfigurationFailed @@ -32,7 +31,6 @@ public extension SwedbankPaySDK { case .paymentSessionAPIRequestFailed: "paymentSessionAPIRequestFailed" case .paymentControllerPaymentFailed: "paymentControllerPaymentFailed" case .paymentSession3DSecureViewControllerLoadFailed: "paymentSession3DSecureViewControllerLoadFailed" - case .clientAppLaunchFailed: "clientAppLaunchFailed" case .internalInconsistencyError: "internalInconsistencyError" case .automaticConfigurationFailed: "automaticConfigurationFailed" }