From f1d237ec9eda29eef1d0e95a95367bd76f08643e Mon Sep 17 00:00:00 2001 From: Martin Alleus Date: Mon, 11 Nov 2024 11:14:33 +0100 Subject: [PATCH 1/4] Extended support for web based SDK controller configuration and instrument mode payments --- .../Classes/Api/Models/MethodBaseModel.swift | 35 ++-- .../Api/Models/PaymentAttemptInstrument.swift | 11 +- .../Api/Models/PaymentSessionModel.swift | 21 +++ .../Api/SwedbankPayAPIEnpointRouter.swift | 36 ++-- .../ApplePay/SwedbankPayAuthorization.swift | 2 +- .../Classes/SwedbankPayPaymentSession.swift | 163 +++++++++++++----- 6 files changed, 184 insertions(+), 84 deletions(-) diff --git a/SwedbankPaySDK/Classes/Api/Models/MethodBaseModel.swift b/SwedbankPaySDK/Classes/Api/Models/MethodBaseModel.swift index 3b17e99..e662337 100644 --- a/SwedbankPaySDK/Classes/Api/Models/MethodBaseModel.swift +++ b/SwedbankPaySDK/Classes/Api/Models/MethodBaseModel.swift @@ -19,18 +19,17 @@ enum MethodBaseModel: Codable, Equatable, Hashable { case swish(prefills: [SwedbankPaySDK.SwishMethodPrefillModel]?, operations: [OperationOutputModel]?) case creditCard(prefills: [SwedbankPaySDK.CreditCardMethodPrefillModel]?, operations: [OperationOutputModel]?, cardBrands: [String]?) case applePay(operations: [OperationOutputModel]?, cardBrands: [String]?) - - case unknown(String) + case webBased(paymentMethod: String) private enum CodingKeys: String, CodingKey { - case instrument, prefills, operations, cardBrands + case paymentMethod, prefills, operations, cardBrands } init(from decoder: Decoder) throws { let container = try decoder.container(keyedBy: CodingKeys.self) - let type = try container.decode(String.self, forKey: .instrument) - switch type { + let paymentMethod = try container.decode(String.self, forKey: .paymentMethod) + switch paymentMethod { case "Swish": self = .swish( prefills: try? container.decode([SwedbankPaySDK.SwishMethodPrefillModel]?.self, forKey: CodingKeys.prefills), @@ -48,7 +47,7 @@ enum MethodBaseModel: Codable, Equatable, Hashable { cardBrands: try? container.decode([String]?.self, forKey: CodingKeys.cardBrands) ) default: - self = .unknown(type) + self = .webBased(paymentMethod: paymentMethod) } } @@ -65,8 +64,8 @@ enum MethodBaseModel: Codable, Equatable, Hashable { case .applePay(let operations, let cardBrands): try container.encode(operations) try container.encode(cardBrands) - case .unknown(let type): - try container.encode(type) + case .webBased(let paymentMethod): + try container.encode(paymentMethod) } } @@ -78,8 +77,8 @@ enum MethodBaseModel: Codable, Equatable, Hashable { return "CreditCard" case .applePay: return "ApplePay" - case .unknown: - return "Unknown" + case .webBased(let paymentMethod): + return paymentMethod } } @@ -91,16 +90,10 @@ enum MethodBaseModel: Codable, Equatable, Hashable { return opertations case .applePay(let operations, _): return operations - case .unknown: + case .webBased: return nil } } - - var isUnknown: Bool { - if case .unknown = self { return true } - - return false - } } extension Sequence where Iterator.Element == MethodBaseModel @@ -121,9 +114,9 @@ extension SwedbankPaySDK { case applePay - case webBased(identifier: String) + case webBased(paymentMethod: String) - var identifier: String { + var paymentMethod: String { switch self { case .swish: return "Swish" @@ -131,8 +124,8 @@ extension SwedbankPaySDK { return "CreditCard" case .applePay: return "ApplePay" - case .webBased(identifier: let identifier): - return identifier + case .webBased(let paymentMethod): + return paymentMethod } } } diff --git a/SwedbankPaySDK/Classes/Api/Models/PaymentAttemptInstrument.swift b/SwedbankPaySDK/Classes/Api/Models/PaymentAttemptInstrument.swift index c266c5d..9db75d0 100644 --- a/SwedbankPaySDK/Classes/Api/Models/PaymentAttemptInstrument.swift +++ b/SwedbankPaySDK/Classes/Api/Models/PaymentAttemptInstrument.swift @@ -21,7 +21,7 @@ extension SwedbankPaySDK { case applePay(merchantIdentifier: String) case newCreditCard(enabledPaymentDetailsConsentCheckbox: Bool) - var identifier: String { + var paymentMethod: String { switch self { case .swish: return "Swish" @@ -32,5 +32,14 @@ extension SwedbankPaySDK { return "ApplePay" } } + + var instrumentModeRequired: Bool { + switch self { + case .newCreditCard: + return true + case .swish, .applePay, .creditCard: + return false + } + } } } diff --git a/SwedbankPaySDK/Classes/Api/Models/PaymentSessionModel.swift b/SwedbankPaySDK/Classes/Api/Models/PaymentSessionModel.swift index b50aadd..2c2ffdd 100644 --- a/SwedbankPaySDK/Classes/Api/Models/PaymentSessionModel.swift +++ b/SwedbankPaySDK/Classes/Api/Models/PaymentSessionModel.swift @@ -18,6 +18,7 @@ import Foundation struct PaymentSessionModel: Codable, Hashable { let culture: String? let methods: [MethodBaseModel]? + let settings: SettingsModel? let urls: UrlsModel? let instrumentModePaymentMethod: String? } @@ -38,6 +39,22 @@ extension PaymentSessionModel { return allOperations } + + var allPaymentMethods: [String] { + return methods?.compactMap({$0.name}) ?? [] + } + + var restrictedToInstruments: [String]? { + guard let methods = methods, let settings = settings else { + return nil + } + + if allPaymentMethods.sorted() == settings.enabledPaymentMethods.sorted() { + return nil + } else { + return allPaymentMethods + } + } } struct UrlsModel: Codable, Hashable { @@ -47,3 +64,7 @@ struct UrlsModel: Codable, Hashable { let hostUrls: [URL]? let termsOfServiceUrl: URL? } + +struct SettingsModel: Codable, Hashable { + let enabledPaymentMethods: [String] +} diff --git a/SwedbankPaySDK/Classes/Api/SwedbankPayAPIEnpointRouter.swift b/SwedbankPaySDK/Classes/Api/SwedbankPayAPIEnpointRouter.swift index 268d2b4..73b94d6 100644 --- a/SwedbankPaySDK/Classes/Api/SwedbankPayAPIEnpointRouter.swift +++ b/SwedbankPaySDK/Classes/Api/SwedbankPayAPIEnpointRouter.swift @@ -32,8 +32,8 @@ enum EnpointRouter { case preparePayment case acknowledgeFailedAttempt case abortPayment - case applePay(paymentPayload: String) - case customizePayment(instrument: SwedbankPaySDK.PaymentAttemptInstrument?) + case attemptPayload(paymentPayload: String) + case customizePayment(instrument: SwedbankPaySDK.PaymentAttemptInstrument?, paymentMethod: String?, restrictToPaymentMethods: [String]?) case failPaymentAttempt(problemType: String, errorCode: String?) } @@ -50,7 +50,7 @@ struct SwedbankPayAPIEnpointRouter: EndpointRouterProtocol { var body: [String: Any?]? { switch endpoint.router { case .expandMethod(instrument: let instrument): - return ["instrumentName": instrument.identifier] + return ["paymentMethod": instrument.paymentMethod] case .startPaymentAttempt(let instrument, let culture): switch instrument { case .swish(let msisdn): @@ -119,24 +119,30 @@ struct SwedbankPayAPIEnpointRouter: EndpointRouterProtocol { "client": ["userAgent": SwedbankPaySDK.VersionReporter.userAgent, "ipAddress": NetworkStatusProvider.getAddress(for: .wifi) ?? NetworkStatusProvider.getAddress(for: .cellular) ?? ""], ] - case .applePay(let paymentPayload): - return ["instrument": "ApplePay", + case .attemptPayload(let paymentPayload): + return ["paymentMethod": "ApplePay", "paymentPayload": paymentPayload] - case .customizePayment(let instrument): - guard let instrument = instrument else { - return ["paymentMethod": nil] - } + case .customizePayment(let instrument, let paymentMethod, let restrictToPaymentMethods): - switch instrument { - case .newCreditCard(let enabledPaymentDetailsConsentCheckbox): + switch (instrument, paymentMethod, restrictToPaymentMethods) { + case (nil, nil, let restrictToPaymentMethods): + return ["paymentMethod": nil, + "restrictToPaymentMethods": restrictToPaymentMethods] + case (.newCreditCard(let enabledPaymentDetailsConsentCheckbox), _, _): return ["paymentMethod": "CreditCard", + "restrictToPaymentMethods": nil, "hideStoredPaymentOptions": true, "showConsentAffirmation" : enabledPaymentDetailsConsentCheckbox, ] - case .swish, - .creditCard, - .applePay: - return ["paymentMethod": instrument.identifier] + case (nil, let paymentMethod, nil): + return ["paymentMethod": paymentMethod, + "restrictToPaymentMethods": nil] + case (let instrument?, nil, nil): + return ["paymentMethod": instrument.paymentMethod, + "restrictToPaymentMethods": nil] + default: + return ["paymentMethod": nil, + "restrictToPaymentMethods": nil] } case .failPaymentAttempt(let problemType, let errorCode): return ["problemType": problemType, diff --git a/SwedbankPaySDK/Classes/ApplePay/SwedbankPayAuthorization.swift b/SwedbankPaySDK/Classes/ApplePay/SwedbankPayAuthorization.swift index 53024dc..02fbab7 100644 --- a/SwedbankPaySDK/Classes/ApplePay/SwedbankPayAuthorization.swift +++ b/SwedbankPaySDK/Classes/ApplePay/SwedbankPayAuthorization.swift @@ -105,7 +105,7 @@ extension SwedbankPayAuthorization: PKPaymentAuthorizationControllerDelegate { func paymentAuthorizationController(_ controller: PKPaymentAuthorizationController, didAuthorizePayment payment: PKPayment, handler completion: @escaping (PKPaymentAuthorizationResult) -> Void) { let paymentPayload = payment.token.paymentData.base64EncodedString() - let router = EnpointRouter.applePay(paymentPayload: paymentPayload) + let router = EnpointRouter.attemptPayload(paymentPayload: paymentPayload) SwedbankPayAPIEnpointRouter(endpoint: Endpoint(router: router, href: operation?.href, method: operation?.method), sessionStartTimestamp: Date()).makeRequest { result in diff --git a/SwedbankPaySDK/Classes/SwedbankPayPaymentSession.swift b/SwedbankPaySDK/Classes/SwedbankPayPaymentSession.swift index ab14a3b..2eda530 100644 --- a/SwedbankPaySDK/Classes/SwedbankPayPaymentSession.swift +++ b/SwedbankPaySDK/Classes/SwedbankPayPaymentSession.swift @@ -52,6 +52,11 @@ public protocol SwedbankPaySDKPaymentSessionDelegate: AnyObject { } public extension SwedbankPaySDK { + enum SwedbankPayPaymentSessionSDKControllerMode { + case menu(restrictedToInstruments: [SwedbankPaySDK.AvailableInstrument]?) + case instrumentMode(instrument: SwedbankPaySDK.AvailableInstrument) + } + /// Object that handles payment sessions class SwedbankPayPaymentSession: CallbackUrlDelegate { /// Order information that provides `PaymentSession` with callback URLs. @@ -64,6 +69,7 @@ public extension SwedbankPaySDK { private var sessionIsOngoing: Bool = false private var paymentViewSessionIsOngoing: Bool = false private var instrument: SwedbankPaySDK.PaymentAttemptInstrument? = nil + private var sdkControllerMode: SwedbankPaySDK.SwedbankPayPaymentSessionSDKControllerMode? = nil private var hasShownAvailableInstruments: Bool = false private var merchantIdentifier: String? = nil @@ -102,6 +108,7 @@ public extension SwedbankPaySDK { sessionIsOngoing = true paymentViewSessionIsOngoing = false instrument = nil + sdkControllerMode = nil merchantIdentifier = nil ongoingModel = nil hasLaunchClientAppURLs = [] @@ -163,12 +170,12 @@ public extension SwedbankPaySDK { case .swish(let msisdn): BeaconService.shared.log(type: .sdkMethodInvoked(name: "makePaymentAttempt", succeeded: true, - values: ["instrument": instrument.identifier, + values: ["instrument": instrument.paymentMethod, "msisdn": msisdn])) case .creditCard(let prefill): BeaconService.shared.log(type: .sdkMethodInvoked(name: "makePaymentAttempt", succeeded: true, - values: ["instrument": instrument.identifier, + values: ["instrument": instrument.paymentMethod, "paymentToken": prefill.paymentToken, "cardNumber": prefill.maskedPan, "cardExpiryMonth": prefill.expiryMonth, @@ -176,11 +183,11 @@ public extension SwedbankPaySDK { case .applePay: BeaconService.shared.log(type: .sdkMethodInvoked(name: "makePaymentAttempt", succeeded: true, - values: ["instrument": instrument.identifier])) + values: ["instrument": instrument.paymentMethod])) case .newCreditCard(enabledPaymentDetailsConsentCheckbox: let enabledPaymentDetailsConsentCheckbox): BeaconService.shared.log(type: .sdkMethodInvoked(name: "makePaymentAttempt", succeeded: true, - values: ["instrument": instrument.identifier, + values: ["instrument": instrument.paymentMethod, "showConsentAffirmation": enabledPaymentDetailsConsentCheckbox.description])) } @@ -191,7 +198,24 @@ public extension SwedbankPaySDK { /// There needs to be an active payment session before an payment attempt can be made. /// /// - returns:- SwedbankPaySDKController to be shown. - public func createSwedbankPaySDKController() { + public func createSwedbankPaySDKController(mode: SwedbankPayPaymentSessionSDKControllerMode) { + guard let ongoingModel = ongoingModel else { + self.delegate?.sdkProblemOccurred(problem: .internalInconsistencyError) + + BeaconService.shared.log(type: .sdkCallbackInvoked(name: "sdkProblemOccurred", + succeeded: self.delegate != nil, + values: ["problem": SwedbankPaySDK.PaymentSessionProblem.internalInconsistencyError.rawValue])) + + return + } + + paymentViewSessionIsOngoing = false + sdkControllerMode = mode + + sessionOperationHandling(paymentOutputModel: ongoingModel, culture: ongoingModel.paymentSession.culture) + } + + private func createSwedbankPaySDKController() { guard let ongoingModel = ongoingModel, let operation = ongoingModel.operations?.firstOperation(withRel: .viewPayment), let orderInfo = orderInfo, @@ -412,29 +436,77 @@ public extension SwedbankPaySDK { makeRequest(router: .preparePayment, operation: preparePayment) } else if let attemptPayload = operations.firstOperation(withRel: .attemptPayload), - let failPayment = paymentOutputModel.paymentSession.methods?.firstMethod(withName: AvailableInstrument.applePay.identifier)?.operations?.firstOperation(withRel: .failPaymentAttempt), + let failPayment = paymentOutputModel.paymentSession.methods?.firstMethod(withName: AvailableInstrument.applePay.paymentMethod)?.operations?.firstOperation(withRel: .failPaymentAttempt), let walletSdk = attemptPayload.firstTask(withRel: .walletSdk) { // We have an active walletSdk task, this means we should initiate an Apple Pay Payment Request locally on the device makeApplePayAuthorization(attemptPayloadOperation: attemptPayload, failPaymentAttemptOperation: failPayment, task: walletSdk) } else if let instrument = self.instrument, - ongoingModel?.paymentSession.instrumentModePaymentMethod != nil && ongoingModel?.paymentSession.instrumentModePaymentMethod != instrument.identifier, - let customizePayment = ongoingModel?.operations?.firstOperation(withRel: .customizePayment) { - makeRequest(router: .customizePayment(instrument: nil), operation: customizePayment) + (paymentOutputModel.paymentSession.instrumentModePaymentMethod != nil && paymentOutputModel.paymentSession.instrumentModePaymentMethod != instrument.paymentMethod) + || !paymentOutputModel.paymentSession.allPaymentMethods.contains(where: {$0 == instrument.paymentMethod}), + let customizePayment = paymentOutputModel.operations?.firstOperation(withRel: .customizePayment) { + // Resetting Instrument Mode session to Menu Mode (instrumentModePaymentMethod set to nil), if new payment attempt is made with an instrument other than the current Instrument Mode instrument or with an instrument not in the list of methods (restricted menu) + + makeRequest(router: .customizePayment(instrument: nil, paymentMethod: nil, restrictToPaymentMethods: nil), operation: customizePayment) + } else if let instrument = self.instrument, + instrument.instrumentModeRequired, + paymentOutputModel.paymentSession.instrumentModePaymentMethod == nil + || paymentOutputModel.paymentSession.instrumentModePaymentMethod != instrument.paymentMethod, + let customizePayment = paymentOutputModel.operations?.firstOperation(withRel: .customizePayment) { + // Switching to Instrument Mode from Menu Mode session (instrumentModePaymentMethod set to nil) or from Instrument Mode with other instrument, if new payment attempt is made with an Instrument Mode required instrument (newCreditCard) + + makeRequest(router: .customizePayment(instrument: instrument, paymentMethod: nil, restrictToPaymentMethods: nil), operation: customizePayment) } else if let instrument = self.instrument, - case .newCreditCard = instrument, - ongoingModel?.paymentSession.instrumentModePaymentMethod == nil || ongoingModel?.paymentSession.instrumentModePaymentMethod != instrument.identifier, - let customizePayment = ongoingModel?.operations?.firstOperation(withRel: .customizePayment) { - makeRequest(router: .customizePayment(instrument: instrument), operation: customizePayment) - } else if case .newCreditCard = self.instrument, - ongoingModel?.paymentSession.instrumentModePaymentMethod == "CreditCard" { + instrument.instrumentModeRequired, + paymentOutputModel.paymentSession.instrumentModePaymentMethod == instrument.paymentMethod { + // Session is in Instrument Mode, and the set instrument is matching payment attempt, time to create a web based view and send to the merchant app + + self.instrument = nil + + DispatchQueue.main.async { + self.createSwedbankPaySDKController() + } + } else if let sdkControllerMode = self.sdkControllerMode, + case .instrumentMode(let instrument) = sdkControllerMode, + paymentOutputModel.paymentSession.instrumentModePaymentMethod == nil + || paymentOutputModel.paymentSession.instrumentModePaymentMethod != instrument.paymentMethod, + let customizePayment = paymentOutputModel.operations?.firstOperation(withRel: .customizePayment) { + // Switching to Instrument Mode from Menu Mode session (instrumentModePaymentMethod set to nil) or from Instrument Mode with other instrument, if a SDK view controller is requiested in instrument mode + + makeRequest(router: .customizePayment(instrument: nil, paymentMethod: instrument.paymentMethod, restrictToPaymentMethods: nil), operation: customizePayment) + } else if let sdkControllerMode = self.sdkControllerMode, + case .instrumentMode(let instrument) = sdkControllerMode, + paymentOutputModel.paymentSession.instrumentModePaymentMethod == instrument.paymentMethod { + // Session is in Instrument Mode, and the set SDK view controller mode is matching the instrument, time to create a web based view and send to the merchant app + + self.sdkControllerMode = nil + + DispatchQueue.main.async { + self.createSwedbankPaySDKController() + } + } else if let sdkControllerMode = self.sdkControllerMode, + case .menu(let restrictedToInstruments) = sdkControllerMode, + paymentOutputModel.paymentSession.instrumentModePaymentMethod != nil + || paymentOutputModel.paymentSession.restrictedToInstruments?.sorted() != restrictedToInstruments?.compactMap({$0.paymentMethod}).sorted(), + let customizePayment = paymentOutputModel.operations?.firstOperation(withRel: .customizePayment) { + // Switching to Menu Mode with potential list of restricted instruments from Instrument Mode or when list of restricted instruments doesn't match (different list of instruments) + + makeRequest(router: .customizePayment(instrument: nil, paymentMethod: nil, restrictToPaymentMethods: restrictedToInstruments?.compactMap({$0.paymentMethod})), operation: customizePayment) + } else if let sdkControllerMode = self.sdkControllerMode, + case .menu(let restrictedToInstruments) = sdkControllerMode, + paymentOutputModel.paymentSession.instrumentModePaymentMethod == nil + && paymentOutputModel.paymentSession.restrictedToInstruments?.sorted() == restrictedToInstruments?.compactMap({$0.paymentMethod}).sorted() { + // Session is in Menu Mode, and the list of restricted instruments match the set SDK view controller mode, time to create a web based view and send to the merchant app + + self.sdkControllerMode = nil + DispatchQueue.main.async { self.createSwedbankPaySDKController() } } else if operations.containsOperation(withRel: .startPaymentAttempt), let instrument = instrument, - let startPaymentAttempt = ongoingModel?.paymentSession.methods? - .firstMethod(withName: instrument.identifier)?.operations? + let startPaymentAttempt = paymentOutputModel.paymentSession.methods? + .firstMethod(withName: instrument.paymentMethod)?.operations? .firstOperation(withRel: .startPaymentAttempt) { // We have a startPaymentAttempt and it's matching the set instrument, time to make a payment attempt @@ -462,9 +534,7 @@ public extension SwedbankPaySDK { self.scaMethodRequestDataPerformed.append((name: task.expects?.value(for: "threeDSMethodData") ?? "null", value: "N")) } - if let model = self.ongoingModel { - self.sessionOperationHandling(paymentOutputModel: model, culture: culture) - } + self.sessionOperationHandling(paymentOutputModel: paymentOutputModel, culture: culture) } } } else if let createAuthentication = operations.firstOperation(withRel: .createAuthentication), @@ -546,33 +616,9 @@ public extension SwedbankPaySDK { scaRedirectDataPerformed = [] notificationUrl = nil hasShownAvailableInstruments = false - } else if ((operations.containsOperation(withRel: .expandMethod) || operations.containsOperation(withRel: .startPaymentAttempt)) && - hasShownAvailableInstruments == false) { - DispatchQueue.main.async { - let availableInstruments: [AvailableInstrument] = paymentOutputModel.paymentSession.methods?.compactMap({ model in - switch model { - case .swish(let prefills, _): - return AvailableInstrument.swish(prefills: prefills) - case .creditCard(let prefills, _, _): - return AvailableInstrument.creditCard(prefills: prefills) - case .applePay: - return AvailableInstrument.applePay - case .unknown(let identifier): - return AvailableInstrument.webBased(identifier: identifier) - } - }) ?? [] - - self.hasShownAvailableInstruments = true - - self.delegate?.paymentSessionFetched(availableInstruments: availableInstruments) - - BeaconService.shared.log(type: .sdkCallbackInvoked(name: "paymentSessionFetched", - succeeded: self.delegate != nil, - values: ["instruments": availableInstruments.compactMap({ $0.identifier }).joined(separator: ";")])) - } } else if let instrument = self.instrument, - let operation = ongoingModel?.paymentSession.methods? - .firstMethod(withName: instrument.identifier)?.operations? + let operation = paymentOutputModel.paymentSession.methods? + .firstMethod(withName: instrument.paymentMethod)?.operations? .first(where: { $0.rel == .expandMethod || $0.rel == .startPaymentAttempt || $0.rel == .getPayment }) { // We have a method matching the set instrument, and it has one of the three supported method operations (expandMethod, startPaymentAttempt or getPayment) @@ -604,6 +650,31 @@ public extension SwedbankPaySDK { self.sessionStartTimestamp = Date() self.makeRequest(router: .getPayment, operation: getPayment) } + } else if hasShownAvailableInstruments == false { + // No process has been initiated above, and we haven't sent the available instrumnts to the merchant app for this session yet, so send the list and wait for action + + DispatchQueue.main.async { + let availableInstruments: [AvailableInstrument] = paymentOutputModel.paymentSession.methods?.compactMap({ model in + switch model { + case .swish(let prefills, _): + return AvailableInstrument.swish(prefills: prefills) + case .creditCard(let prefills, _, _): + return AvailableInstrument.creditCard(prefills: prefills) + case .applePay: + return AvailableInstrument.applePay + case .webBased(let paymentMethod): + return AvailableInstrument.webBased(paymentMethod: paymentMethod) + } + }) ?? [] + + self.hasShownAvailableInstruments = true + + self.delegate?.paymentSessionFetched(availableInstruments: availableInstruments) + + BeaconService.shared.log(type: .sdkCallbackInvoked(name: "paymentSessionFetched", + succeeded: self.delegate != nil, + values: ["instruments": availableInstruments.compactMap({ $0.paymentMethod }).joined(separator: ";")])) + } } else if !hasShowedError { // No process has been initiated at all. The session is in a state that this session operation handling logic can't resolve. From 9ff6eb7893a51acb00f35fbaaa8691a97b3363b1 Mon Sep 17 00:00:00 2001 From: Martin Alleus Date: Wed, 13 Nov 2024 11:57:28 +0100 Subject: [PATCH 2/4] Improving beacon logging for new web based modes --- .../Classes/SwedbankPayPaymentSession.swift | 23 +++++++++++++++---- 1 file changed, 19 insertions(+), 4 deletions(-) diff --git a/SwedbankPaySDK/Classes/SwedbankPayPaymentSession.swift b/SwedbankPaySDK/Classes/SwedbankPayPaymentSession.swift index 2eda530..64a5c8d 100644 --- a/SwedbankPaySDK/Classes/SwedbankPayPaymentSession.swift +++ b/SwedbankPaySDK/Classes/SwedbankPayPaymentSession.swift @@ -209,6 +209,25 @@ public extension SwedbankPaySDK { return } + let logValues: [String: String?] + + switch mode { + case .instrumentMode(let instrument): + logValues = [ + "mode": "instrumentMode", + "instrument": instrument.paymentMethod + ] + case .menu(let restrictedToInstruments): + logValues = [ + "mode": "menu", + "restrictedToInstruments": restrictedToInstruments?.compactMap({ $0.paymentMethod }).joined(separator: ";") + ] + } + + BeaconService.shared.log(type: .sdkMethodInvoked(name: "createSwedbankPaySDKController", + succeeded: true, + values: logValues)) + paymentViewSessionIsOngoing = false sdkControllerMode = mode @@ -245,10 +264,6 @@ public extension SwedbankPaySDK { paymentOrder: nil, userData: nil) - BeaconService.shared.log(type: .sdkMethodInvoked(name: "createSwedbankPaySDKController", - succeeded: true, - values: nil)) - paymentViewSessionIsOngoing = true viewController.internalDelegate = self From ce345ab57b47feb798251e96b5a0594c8d575459 Mon Sep 17 00:00:00 2001 From: Martin Alleus Date: Thu, 14 Nov 2024 12:23:02 +0100 Subject: [PATCH 3/4] Tweaking customize-payment request parameters --- .../Classes/Api/SwedbankPayAPIEnpointRouter.swift | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/SwedbankPaySDK/Classes/Api/SwedbankPayAPIEnpointRouter.swift b/SwedbankPaySDK/Classes/Api/SwedbankPayAPIEnpointRouter.swift index 73b94d6..b84fb60 100644 --- a/SwedbankPaySDK/Classes/Api/SwedbankPayAPIEnpointRouter.swift +++ b/SwedbankPaySDK/Classes/Api/SwedbankPayAPIEnpointRouter.swift @@ -125,16 +125,16 @@ struct SwedbankPayAPIEnpointRouter: EndpointRouterProtocol { case .customizePayment(let instrument, let paymentMethod, let restrictToPaymentMethods): switch (instrument, paymentMethod, restrictToPaymentMethods) { - case (nil, nil, let restrictToPaymentMethods): + case (nil, nil, let restrictToPaymentMethods?): return ["paymentMethod": nil, - "restrictToPaymentMethods": restrictToPaymentMethods] + "restrictToPaymentMethods": restrictToPaymentMethods.isEmpty ? nil : restrictToPaymentMethods] case (.newCreditCard(let enabledPaymentDetailsConsentCheckbox), _, _): return ["paymentMethod": "CreditCard", "restrictToPaymentMethods": nil, "hideStoredPaymentOptions": true, "showConsentAffirmation" : enabledPaymentDetailsConsentCheckbox, ] - case (nil, let paymentMethod, nil): + case (nil, let paymentMethod?, nil): return ["paymentMethod": paymentMethod, "restrictToPaymentMethods": nil] case (let instrument?, nil, nil): From 1b1de4fd0315ea64216aaf589e3d6d6ba2c36eb6 Mon Sep 17 00:00:00 2001 From: Martin Alleus Date: Thu, 14 Nov 2024 12:23:20 +0100 Subject: [PATCH 4/4] Exposing paymentMethod on AvailableInstrument, for easier access --- SwedbankPaySDK/Classes/Api/Models/MethodBaseModel.swift | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/SwedbankPaySDK/Classes/Api/Models/MethodBaseModel.swift b/SwedbankPaySDK/Classes/Api/Models/MethodBaseModel.swift index e662337..6a01f12 100644 --- a/SwedbankPaySDK/Classes/Api/Models/MethodBaseModel.swift +++ b/SwedbankPaySDK/Classes/Api/Models/MethodBaseModel.swift @@ -116,7 +116,7 @@ extension SwedbankPaySDK { case webBased(paymentMethod: String) - var paymentMethod: String { + public var paymentMethod: String { switch self { case .swish: return "Swish"