diff --git a/Debug App/Sources/AppDelegate.swift b/Debug App/Sources/AppDelegate.swift index c4169f922c..8dbddd1bb7 100644 --- a/Debug App/Sources/AppDelegate.swift +++ b/Debug App/Sources/AppDelegate.swift @@ -43,5 +43,4 @@ class AppDelegate: UIResponder, UIApplicationDelegate { UINavigationBar.appearance().scrollEdgeAppearance = navigationBarAppearance } } - } diff --git a/Debug App/Sources/View Controllers/MerchantSessionAndSettingsViewController.swift b/Debug App/Sources/View Controllers/MerchantSessionAndSettingsViewController.swift index 093c01d3c1..834d6bd40e 100644 --- a/Debug App/Sources/View Controllers/MerchantSessionAndSettingsViewController.swift +++ b/Debug App/Sources/View Controllers/MerchantSessionAndSettingsViewController.swift @@ -446,7 +446,9 @@ class MerchantSessionAndSettingsViewController: UIViewController { applePayOptions: PrimerApplePayOptions( merchantIdentifier: "merchant.checkout.team", merchantName: merchantNameTextField.text ?? "Primer Merchant", - isCaptureBillingAddressEnabled: false)), + isCaptureBillingAddressEnabled: false, + showApplePayForUnsupportedDevice: false, + checkProvidedNetworks: false)), uiOptions: uiOptions, debugOptions: PrimerDebugOptions(is3DSSanityCheckEnabled: false) ) @@ -552,7 +554,9 @@ class MerchantSessionAndSettingsViewController: UIViewController { applePayOptions: PrimerApplePayOptions( merchantIdentifier: "merchant.checkout.team", merchantName: merchantNameTextField.text ?? "Primer Merchant", - isCaptureBillingAddressEnabled: false)), + isCaptureBillingAddressEnabled: false, + showApplePayForUnsupportedDevice: false, + checkProvidedNetworks: false)), uiOptions: nil, debugOptions: PrimerDebugOptions(is3DSSanityCheckEnabled: false) ) diff --git a/Sources/PrimerSDK/Classes/Core/PrimerHeadlessUniversalCheckout/Models/PrimerHeadlessUniversalCheckoutPaymentMethod.swift b/Sources/PrimerSDK/Classes/Core/PrimerHeadlessUniversalCheckout/Models/PrimerHeadlessUniversalCheckoutPaymentMethod.swift index c4440acff1..cf78c04122 100644 --- a/Sources/PrimerSDK/Classes/Core/PrimerHeadlessUniversalCheckout/Models/PrimerHeadlessUniversalCheckoutPaymentMethod.swift +++ b/Sources/PrimerSDK/Classes/Core/PrimerHeadlessUniversalCheckout/Models/PrimerHeadlessUniversalCheckoutPaymentMethod.swift @@ -8,15 +8,26 @@ import Foundation +import PassKit extension PrimerHeadlessUniversalCheckout { public class PaymentMethod: NSObject { static var availablePaymentMethods: [PrimerHeadlessUniversalCheckout.PaymentMethod] { - let availablePaymentMethods = PrimerAPIConfiguration.paymentMethodConfigs? + var availablePaymentMethods = PrimerAPIConfiguration.paymentMethodConfigs? .compactMap({ $0.type }) .compactMap({ PrimerHeadlessUniversalCheckout.PaymentMethod(paymentMethodType: $0) }) + + if PrimerSettings.current.paymentMethodOptions.applePayOptions?.showApplePayForUnsupportedDevice != true { + if !PKPaymentAuthorizationViewController.canMakePayments() { + // Filter out Apple pay from payment methods + availablePaymentMethods = availablePaymentMethods?.filter({ (method: PrimerHeadlessUniversalCheckout.PaymentMethod) in + return method.paymentMethodType != "APPLE_PAY" + }) + } + } + return availablePaymentMethods ?? [] } diff --git a/Sources/PrimerSDK/Classes/Data Models/PrimerConfiguration.swift b/Sources/PrimerSDK/Classes/Data Models/PrimerConfiguration.swift index 771631879a..44a12ce700 100644 --- a/Sources/PrimerSDK/Classes/Data Models/PrimerConfiguration.swift +++ b/Sources/PrimerSDK/Classes/Data Models/PrimerConfiguration.swift @@ -101,7 +101,14 @@ extension Response.Body { ?? [] let supportedNetworks = PaymentNetwork.iOSSupportedPKPaymentNetworks - if !PKPaymentAuthorizationViewController.canMakePayments(usingNetworks: supportedNetworks) { + var canMakePayment: Bool + if PrimerSettings.current.paymentMethodOptions.applePayOptions?.checkProvidedNetworks == true { + canMakePayment = PKPaymentAuthorizationViewController.canMakePayments(usingNetworks: supportedNetworks) + } else { + canMakePayment = PKPaymentAuthorizationViewController.canMakePayments() + } + + if !canMakePayment { if let applePayViewModel = viewModels.filter({ $0.config.type == PrimerPaymentMethodType.applePay.rawValue }).first, let applePayViewModelIndex = viewModels.firstIndex(where: { $0 == applePayViewModel }) { viewModels.remove(at: applePayViewModelIndex) diff --git a/Sources/PrimerSDK/Classes/Data Models/PrimerSettings.swift b/Sources/PrimerSDK/Classes/Data Models/PrimerSettings.swift index 2e2d84362c..06c281f3ab 100644 --- a/Sources/PrimerSDK/Classes/Data Models/PrimerSettings.swift +++ b/Sources/PrimerSDK/Classes/Data Models/PrimerSettings.swift @@ -97,11 +97,21 @@ public class PrimerApplePayOptions: Codable { let merchantIdentifier: String let merchantName: String let isCaptureBillingAddressEnabled: Bool - - public init(merchantIdentifier: String, merchantName: String, isCaptureBillingAddressEnabled: Bool = false) { + /// If in some cases you dont want to present ApplePay option if the device is not supporting it set this to `false`. Default value is `true`. + let showApplePayForUnsupportedDevice: Bool + /// Due to merchant report about ApplePay flow which was not presenting because canMakePayments(usingNetworks:) was returning false if there were no cards in the Wallet, we introduced this flag to continue supporting the old behaviour. Default value is `true`. + let checkProvidedNetworks: Bool + + public init(merchantIdentifier: String, + merchantName: String, + isCaptureBillingAddressEnabled: Bool = false, + showApplePayForUnsupportedDevice: Bool = true, + checkProvidedNetworks: Bool = true) { self.merchantIdentifier = merchantIdentifier self.merchantName = merchantName self.isCaptureBillingAddressEnabled = isCaptureBillingAddressEnabled + self.showApplePayForUnsupportedDevice = showApplePayForUnsupportedDevice + self.checkProvidedNetworks = checkProvidedNetworks } } diff --git a/Sources/PrimerSDK/Classes/User Interface/TokenizationViewModels/ApplePayTokenizationViewModel.swift b/Sources/PrimerSDK/Classes/User Interface/TokenizationViewModels/ApplePayTokenizationViewModel.swift index 5addd4779c..229269f508 100644 --- a/Sources/PrimerSDK/Classes/User Interface/TokenizationViewModels/ApplePayTokenizationViewModel.swift +++ b/Sources/PrimerSDK/Classes/User Interface/TokenizationViewModels/ApplePayTokenizationViewModel.swift @@ -196,7 +196,14 @@ class ApplePayTokenizationViewModel: PaymentMethodTokenizationViewModel { ) let supportedNetworks = PaymentNetwork.iOSSupportedPKPaymentNetworks - if PKPaymentAuthorizationViewController.canMakePayments(usingNetworks: supportedNetworks) { + var canMakePayment: Bool + if PrimerSettings.current.paymentMethodOptions.applePayOptions?.checkProvidedNetworks == true { + canMakePayment = PKPaymentAuthorizationViewController.canMakePayments(usingNetworks: supportedNetworks) + } else { + canMakePayment = PKPaymentAuthorizationViewController.canMakePayments() + } + + if canMakePayment { let request = PKPaymentRequest() let isBillingContactFieldsRequired = PrimerSettings.current.paymentMethodOptions.applePayOptions?.isCaptureBillingAddressEnabled == true request.requiredBillingContactFields = isBillingContactFieldsRequired ? [.postalAddress] : [] @@ -232,10 +239,18 @@ class ApplePayTokenizationViewModel: PaymentMethodTokenizationViewModel { } } else { - log(logLevel: .error, title: "APPLE PAY", message: "Cannot make payments on the provided networks") - let err = PrimerError.unableToMakePaymentsOnProvidedNetworks(userInfo: ["file": #file, "class": "\(Self.self)", "function": #function, "line": "\(#line)"], diagnosticsId: UUID().uuidString) - ErrorHandler.handle(error: err) - seal.reject(err) + if PrimerSettings.current.paymentMethodOptions.applePayOptions?.checkProvidedNetworks == true { + log(logLevel: .error, title: "APPLE PAY", message: "Cannot run ApplePay on this device") + let err = PrimerError.unableToMakePaymentsOnProvidedNetworks(userInfo: ["file": #file, "class": "\(Self.self)", "function": #function, "line": "\(#line)"], diagnosticsId: UUID().uuidString) + ErrorHandler.handle(error: err) + seal.reject(err) + } else { + log(logLevel: .error, title: "APPLE PAY", message: "Cannot run ApplePay on this device") + let err = PrimerError.unableToPresentPaymentMethod(paymentMethodType: "APPLE_PAY", userInfo: ["message:": "Cannot run ApplePay on this device", "file": #file, "class": "\(Self.self)", "function": #function, "line": "\(#line)"], diagnosticsId: UUID().uuidString) + ErrorHandler.handle(error: err) + seal.reject(err) + } + } } }