diff --git a/WooCommerce/Classes/ViewModels/CardPresentPayments/LegacyPaymentCaptureOrchestrator.swift b/WooCommerce/Classes/ViewModels/CardPresentPayments/LegacyPaymentCaptureOrchestrator.swift new file mode 100644 index 00000000000..628352e9253 --- /dev/null +++ b/WooCommerce/Classes/ViewModels/CardPresentPayments/LegacyPaymentCaptureOrchestrator.swift @@ -0,0 +1,265 @@ +import Yosemite +import PassKit +import WooFoundation + +/// Orchestrates the sequence of actions required to capture a payment: +/// 1. Check if there is a card reader connected +/// 2. Launch the reader discovering and pairing UI if there is no reader connected +/// 3. Obtain a Payment Intent from the card reader (i.e., create a payment intent, collect a payment method, and process the payment) +/// 4. Submit the Payment Intent to WCPay to capture a payment +/// Steps 1 and 2 will be implemented as part of https://github.com/woocommerce/woocommerce-ios/issues/4062 +final class LegacyPaymentCaptureOrchestrator { + private let currencyFormatter = CurrencyFormatter(currencySettings: ServiceLocator.currencySettings) + private let personNameComponentsFormatter = PersonNameComponentsFormatter() + private let paymentReceiptEmailParameterDeterminer: ReceiptEmailParameterDeterminer + + private let celebration = PaymentCaptureCelebration() + + private var walletSuppressionRequestToken: PKSuppressionRequestToken? + + private let stores: StoresManager + + init(stores: StoresManager = ServiceLocator.stores, + paymentReceiptEmailParameterDeterminer: ReceiptEmailParameterDeterminer = PaymentReceiptEmailParameterDeterminer()) { + self.stores = stores + self.paymentReceiptEmailParameterDeterminer = paymentReceiptEmailParameterDeterminer + } + + func collectPayment(for order: Order, + orderTotal: NSDecimalNumber, + paymentGatewayAccount: PaymentGatewayAccount, + paymentMethodTypes: [String], + stripeSmallestCurrencyUnitMultiplier: Decimal, + onWaitingForInput: @escaping (CardReaderInput) -> Void, + onProcessingMessage: @escaping () -> Void, + onDisplayMessage: @escaping (String) -> Void, + onProcessingCompletion: @escaping (PaymentIntent) -> Void, + onCompletion: @escaping (Result) -> Void) { + /// Set state of CardPresentPaymentStore + /// + let setAccount = CardPresentPaymentAction.use(paymentGatewayAccount: paymentGatewayAccount) + + stores.dispatch(setAccount) + + let parameters = paymentParameters(order: order, + orderTotal: orderTotal, + country: paymentGatewayAccount.country, + statementDescriptor: paymentGatewayAccount.statementDescriptor, + paymentMethodTypes: paymentMethodTypes, + stripeSmallestCurrencyUnitMultiplier: stripeSmallestCurrencyUnitMultiplier) + + /// Briefly suppress pass (wallet) presentation so that the merchant doesn't attempt to pay for the buyer's order when the + /// reader begins to collect payment. + /// + suppressPassPresentation() + + let paymentAction = CardPresentPaymentAction.collectPayment( + siteID: order.siteID, + orderID: order.orderID, + parameters: parameters, + onCardReaderMessage: { event in + switch event { + case .waitingForInput(let inputMethods): + onWaitingForInput(inputMethods) + case .displayMessage(let message): + onDisplayMessage(message) + case .cardRemovedAfterClientSidePaymentCapture: + onProcessingMessage() + default: + break + } + }, + onProcessingCompletion: { intent in + onProcessingCompletion(intent) + }, + onCompletion: { [weak self] result in + self?.allowPassPresentation() + self?.completePaymentIntentCapture( + order: order, + captureResult: result, + onCompletion: onCompletion + ) + } + ) + + stores.dispatch(paymentAction) + } + + func cancelPayment(onCompletion: @escaping (Result) -> Void) { + let action = CardPresentPaymentAction.cancelPayment() { [weak self] result in + self?.allowPassPresentation() + onCompletion(result) + } + stores.dispatch(action) + } + + func emailReceipt(for order: Order, params: CardPresentReceiptParameters, onContent: @escaping (String) -> Void) { + let action = ReceiptAction.generateContent(order: order, parameters: params) { emailContent in + onContent(emailContent) + } + + stores.dispatch(action) + } + + func saveReceipt(for order: Order, params: CardPresentReceiptParameters) { + let action = ReceiptAction.saveReceipt(order: order, parameters: params) + + stores.dispatch(action) + } +} + +private extension LegacyPaymentCaptureOrchestrator { + /// Suppress wallet presentation. This requires a special entitlement from Apple: + /// `com.apple.developer.passkit.pass-presentation-suppression` + /// See Woo-*.entitlements in WooCommerce/Resources + /// + func suppressPassPresentation() { + /// iPads don't support NFC passes. Attempting to call `requestAutomaticPassPresentationSuppression` on them will + /// return 0 `notSupported` + /// + guard !UIDevice.isPad() else { + return + } + + guard !PKPassLibrary.isSuppressingAutomaticPassPresentation() else { + return + } + + walletSuppressionRequestToken = PKPassLibrary.requestAutomaticPassPresentationSuppression() { result in + guard result == .success else { + DDLogWarn("Automatic pass presentation suppression request failed. Reason: \(result.rawValue)") + + let logProperties: [String: Any] = ["PKAutomaticPassPresentationSuppressionResult": result.rawValue] + ServiceLocator.crashLogging.logMessage( + "Automatic pass presentation suppression request failed", + properties: logProperties, + level: .warning + ) + return + } + } + } + + /// Restore wallet presentation. + func allowPassPresentation() { + /// iPads don't have passes (wallets) to present + /// + guard !UIDevice.isPad() else { + return + } + + guard let walletSuppressionRequestToken = walletSuppressionRequestToken, walletSuppressionRequestToken != 0 else { + return + } + + PKPassLibrary.endAutomaticPassPresentationSuppression(withRequestToken: walletSuppressionRequestToken) + } +} + +private extension LegacyPaymentCaptureOrchestrator { + func completePaymentIntentCapture(order: Order, + captureResult: Result, + onCompletion: @escaping (Result) -> Void) { + switch captureResult { + case .failure(let error): + onCompletion(.failure(error)) + case .success(let paymentIntent): + guard let paymentMethod = paymentIntent.paymentMethod(), + let receiptParameters = paymentIntent.receiptParameters() else { + let error = CardReaderServiceError.paymentCapture() + + DDLogError("⛔️ Payment completed without required metadata: \(error)") + + onCompletion(.failure(error)) + return + } + + celebrate() // plays a sound, haptic + saveReceipt(for: order, params: receiptParameters) + onCompletion(.success(.init(paymentMethod: paymentMethod, + receiptParameters: receiptParameters))) + } + } + + func paymentParameters(order: Order, + orderTotal: NSDecimalNumber, + country: String, + statementDescriptor: String?, + paymentMethodTypes: [String], + stripeSmallestCurrencyUnitMultiplier: Decimal) -> PaymentParameters { + let metadata = PaymentIntent.initMetadata( + store: stores.sessionManager.defaultSite?.name, + customerName: buildCustomerNameFromBillingAddress(order.billingAddress), + customerEmail: order.billingAddress?.email, + siteURL: stores.sessionManager.defaultSite?.url, + orderID: order.orderID, + paymentType: PaymentIntent.PaymentTypes.single + ) + + return PaymentParameters(amount: orderTotal as Decimal, + currency: order.currency, + stripeSmallestCurrencyUnitMultiplier: stripeSmallestCurrencyUnitMultiplier, + applicationFee: applicationFee(for: orderTotal, country: country), + receiptDescription: receiptDescription(orderNumber: order.number), + statementDescription: statementDescriptor, + receiptEmail: paymentReceiptEmailParameterDeterminer.receiptEmail(from: order), + paymentMethodTypes: paymentMethodTypes, + metadata: metadata) + } + + private func applicationFee(for orderTotal: NSDecimalNumber, country: String) -> Decimal? { + guard country.uppercased() == SiteAddress.CountryCode.CA.rawValue else { + return nil + } + + let fee = orderTotal.multiplying(by: Constants.canadaPercentageFee).adding(Constants.canadaFlatFee) + + let numberHandler = NSDecimalNumberHandler(roundingMode: .plain, + scale: 2, + raiseOnExactness: false, + raiseOnOverflow: false, + raiseOnUnderflow: false, + raiseOnDivideByZero: false) + return fee.rounding(accordingToBehavior: numberHandler) as Decimal + } + + func receiptDescription(orderNumber: String) -> String? { + guard let storeName = stores.sessionManager.defaultSite?.name, + let blogID = stores.sessionManager.defaultSite?.siteID else { + return nil + } + + return String.localizedStringWithFormat(Localization.receiptDescription, + orderNumber, + storeName, + String(blogID)) + } + + func celebrate() { + celebration.celebrate() + } + + private func buildCustomerNameFromBillingAddress(_ address: Address?) -> String { + var personNameComponents = PersonNameComponents() + personNameComponents.givenName = address?.firstName + personNameComponents.familyName = address?.lastName + return personNameComponentsFormatter.string(from: personNameComponents) + } +} + +private extension LegacyPaymentCaptureOrchestrator { + enum Constants { + static let canadaFlatFee = NSDecimalNumber(string: "0.15") + static let canadaPercentageFee = NSDecimalNumber(0) + } +} + +private extension LegacyPaymentCaptureOrchestrator { + enum Localization { + static let receiptDescription = NSLocalizedString( + "In-Person Payment for Order #%1$@ for %2$@ blog_id %3$@", + comment: "Message included in emailed receipts. " + + "Reads as: In-Person Payment for Order @{number} for @{store name} blog_id @{blog ID} " + + "Parameters: %1$@ - order number, %2$@ - store name, %3$@ - blog ID number") + } +} diff --git a/WooCommerce/Classes/ViewRelated/Orders/Collect Payments/CollectOrderPaymentUseCase.swift b/WooCommerce/Classes/ViewRelated/Orders/Collect Payments/CollectOrderPaymentUseCase.swift index af752ae8608..9787b136ebb 100644 --- a/WooCommerce/Classes/ViewRelated/Orders/Collect Payments/CollectOrderPaymentUseCase.swift +++ b/WooCommerce/Classes/ViewRelated/Orders/Collect Payments/CollectOrderPaymentUseCase.swift @@ -87,7 +87,7 @@ final class CollectOrderPaymentUseCase: NSObject, CollectOrderPaymentProtocol { /// IPP payments collector. /// - private lazy var paymentOrchestrator = PaymentCaptureOrchestrator(stores: stores) + private lazy var paymentOrchestrator = LegacyPaymentCaptureOrchestrator(stores: stores) /// Coordinates emailing a receipt after payment success. private var receiptEmailCoordinator: CardPresentPaymentReceiptEmailCoordinator? diff --git a/WooCommerce/Classes/ViewRelated/Orders/Collect Payments/LegacyCollectOrderPaymentUseCase.swift b/WooCommerce/Classes/ViewRelated/Orders/Collect Payments/LegacyCollectOrderPaymentUseCase.swift index 9a373192231..21bcbf9246e 100644 --- a/WooCommerce/Classes/ViewRelated/Orders/Collect Payments/LegacyCollectOrderPaymentUseCase.swift +++ b/WooCommerce/Classes/ViewRelated/Orders/Collect Payments/LegacyCollectOrderPaymentUseCase.swift @@ -66,7 +66,7 @@ final class LegacyCollectOrderPaymentUseCase: NSObject, CollectOrderPaymentProto /// IPP payments collector. /// - private lazy var paymentOrchestrator = PaymentCaptureOrchestrator(stores: stores) + private lazy var paymentOrchestrator = LegacyPaymentCaptureOrchestrator(stores: stores) /// Controller to connect a card reader. /// diff --git a/WooCommerce/WooCommerce.xcodeproj/project.pbxproj b/WooCommerce/WooCommerce.xcodeproj/project.pbxproj index e7d483a720a..7f264db0c68 100644 --- a/WooCommerce/WooCommerce.xcodeproj/project.pbxproj +++ b/WooCommerce/WooCommerce.xcodeproj/project.pbxproj @@ -472,7 +472,7 @@ 0366EAE12909A37800B51755 /* JustInTimeMessageAnnouncementCardViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0366EAE02909A37800B51755 /* JustInTimeMessageAnnouncementCardViewModel.swift */; }; 036CA6B9291E8D4B00E4DF4F /* CardPresentModalPreparingReader.swift in Sources */ = {isa = PBXBuildFile; fileRef = 036CA6B8291E8D4B00E4DF4F /* CardPresentModalPreparingReader.swift */; }; 036CA6F129229C9E00E4DF4F /* IndefiniteCircularProgressViewStyle.swift in Sources */ = {isa = PBXBuildFile; fileRef = 036CA6F029229C9E00E4DF4F /* IndefiniteCircularProgressViewStyle.swift */; }; - 036F6EA6281847D5006D84F8 /* PaymentCaptureOrchestratorTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 036F6EA5281847D5006D84F8 /* PaymentCaptureOrchestratorTests.swift */; }; + 036F6EA6281847D5006D84F8 /* LegacyPaymentCaptureOrchestratorTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 036F6EA5281847D5006D84F8 /* LegacyPaymentCaptureOrchestratorTests.swift */; }; 0371C3682875E47B00277E2C /* FeatureAnnouncementCardViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0371C3672875E47B00277E2C /* FeatureAnnouncementCardViewModel.swift */; }; 0371C36A2876DBCA00277E2C /* FeatureAnnouncementCardViewModelTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0371C3692876DBCA00277E2C /* FeatureAnnouncementCardViewModelTests.swift */; }; 0371C36E2876E92D00277E2C /* UpsellCardReadersCampaign.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0371C36D2876E92D00277E2C /* UpsellCardReadersCampaign.swift */; }; @@ -502,6 +502,7 @@ 03E471C8293A3076001A58AD /* CardPresentModalBuiltInConnectingToReader.swift in Sources */ = {isa = PBXBuildFile; fileRef = 03E471C7293A3075001A58AD /* CardPresentModalBuiltInConnectingToReader.swift */; }; 03E471CA293E0A30001A58AD /* CardPresentModalBuiltInConfigurationProgress.swift in Sources */ = {isa = PBXBuildFile; fileRef = 03E471C9293E0A2F001A58AD /* CardPresentModalBuiltInConfigurationProgress.swift */; }; 03E471CC293E0FB8001A58AD /* CardPresentModalProgressDisplaying.swift in Sources */ = {isa = PBXBuildFile; fileRef = 03E471CB293E0FB8001A58AD /* CardPresentModalProgressDisplaying.swift */; }; + 03E471CE293F63B4001A58AD /* PaymentCaptureOrchestrator.swift in Sources */ = {isa = PBXBuildFile; fileRef = 03E471CD293F63B4001A58AD /* PaymentCaptureOrchestrator.swift */; }; 03EF24FA28BF5D21006A033E /* InPersonPaymentsCashOnDeliveryToggleRowViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 03EF24F928BF5D21006A033E /* InPersonPaymentsCashOnDeliveryToggleRowViewModel.swift */; }; 03EF24FC28BF996F006A033E /* InPersonPaymentsCashOnDeliveryPaymentGatewayHelpers.swift in Sources */ = {isa = PBXBuildFile; fileRef = 03EF24FB28BF996F006A033E /* InPersonPaymentsCashOnDeliveryPaymentGatewayHelpers.swift */; }; 03EF24FE28C0B356006A033E /* CardPresentPaymentsPlugin+CashOnDelivery.swift in Sources */ = {isa = PBXBuildFile; fileRef = 03EF24FD28C0B356006A033E /* CardPresentPaymentsPlugin+CashOnDelivery.swift */; }; @@ -1653,7 +1654,7 @@ D85136CD231E15B800DD0539 /* MockReviews.swift in Sources */ = {isa = PBXBuildFile; fileRef = D85136CC231E15B700DD0539 /* MockReviews.swift */; }; D85136D5231E40B500DD0539 /* ProductReviewTableViewCellTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = D85136D4231E40B500DD0539 /* ProductReviewTableViewCellTests.swift */; }; D85136DD231E613900DD0539 /* ReviewsViewModelTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = D85136DC231E613900DD0539 /* ReviewsViewModelTests.swift */; }; - D85806292642BA5400A8AB6C /* PaymentCaptureOrchestrator.swift in Sources */ = {isa = PBXBuildFile; fileRef = D85806282642BA5400A8AB6C /* PaymentCaptureOrchestrator.swift */; }; + D85806292642BA5400A8AB6C /* LegacyPaymentCaptureOrchestrator.swift in Sources */ = {isa = PBXBuildFile; fileRef = D85806282642BA5400A8AB6C /* LegacyPaymentCaptureOrchestrator.swift */; }; D85A3C5026C153A500C0E026 /* InPersonPaymentsPluginNotActivatedView.swift in Sources */ = {isa = PBXBuildFile; fileRef = D85A3C4F26C153A500C0E026 /* InPersonPaymentsPluginNotActivatedView.swift */; }; D85A3C5226C15DE200C0E026 /* InPersonPaymentsPluginNotSupportedVersionView.swift in Sources */ = {isa = PBXBuildFile; fileRef = D85A3C5126C15DE200C0E026 /* InPersonPaymentsPluginNotSupportedVersionView.swift */; }; D85A3C5626C1911600C0E026 /* InPersonPaymentsPluginNotInstalledView.swift in Sources */ = {isa = PBXBuildFile; fileRef = D85A3C5526C1911600C0E026 /* InPersonPaymentsPluginNotInstalledView.swift */; }; @@ -2485,7 +2486,7 @@ 0366EAE02909A37800B51755 /* JustInTimeMessageAnnouncementCardViewModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = JustInTimeMessageAnnouncementCardViewModel.swift; sourceTree = ""; }; 036CA6B8291E8D4B00E4DF4F /* CardPresentModalPreparingReader.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CardPresentModalPreparingReader.swift; sourceTree = ""; }; 036CA6F029229C9E00E4DF4F /* IndefiniteCircularProgressViewStyle.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = IndefiniteCircularProgressViewStyle.swift; sourceTree = ""; }; - 036F6EA5281847D5006D84F8 /* PaymentCaptureOrchestratorTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PaymentCaptureOrchestratorTests.swift; sourceTree = ""; }; + 036F6EA5281847D5006D84F8 /* LegacyPaymentCaptureOrchestratorTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LegacyPaymentCaptureOrchestratorTests.swift; sourceTree = ""; }; 0371C3672875E47B00277E2C /* FeatureAnnouncementCardViewModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FeatureAnnouncementCardViewModel.swift; sourceTree = ""; }; 0371C3692876DBCA00277E2C /* FeatureAnnouncementCardViewModelTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FeatureAnnouncementCardViewModelTests.swift; sourceTree = ""; }; 0371C36D2876E92D00277E2C /* UpsellCardReadersCampaign.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = UpsellCardReadersCampaign.swift; sourceTree = ""; }; @@ -2515,6 +2516,7 @@ 03E471C7293A3075001A58AD /* CardPresentModalBuiltInConnectingToReader.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = CardPresentModalBuiltInConnectingToReader.swift; sourceTree = ""; }; 03E471C9293E0A2F001A58AD /* CardPresentModalBuiltInConfigurationProgress.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = CardPresentModalBuiltInConfigurationProgress.swift; sourceTree = ""; }; 03E471CB293E0FB8001A58AD /* CardPresentModalProgressDisplaying.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CardPresentModalProgressDisplaying.swift; sourceTree = ""; }; + 03E471CD293F63B4001A58AD /* PaymentCaptureOrchestrator.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = PaymentCaptureOrchestrator.swift; sourceTree = ""; }; 03EF24F928BF5D21006A033E /* InPersonPaymentsCashOnDeliveryToggleRowViewModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = InPersonPaymentsCashOnDeliveryToggleRowViewModel.swift; sourceTree = ""; }; 03EF24FB28BF996F006A033E /* InPersonPaymentsCashOnDeliveryPaymentGatewayHelpers.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = InPersonPaymentsCashOnDeliveryPaymentGatewayHelpers.swift; sourceTree = ""; }; 03EF24FD28C0B356006A033E /* CardPresentPaymentsPlugin+CashOnDelivery.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "CardPresentPaymentsPlugin+CashOnDelivery.swift"; sourceTree = ""; }; @@ -3675,7 +3677,7 @@ D85136CC231E15B700DD0539 /* MockReviews.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = MockReviews.swift; sourceTree = ""; }; D85136D4231E40B500DD0539 /* ProductReviewTableViewCellTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; name = ProductReviewTableViewCellTests.swift; path = WooCommerceTests/ViewRelated/ProductReviewTableViewCellTests.swift; sourceTree = SOURCE_ROOT; }; D85136DC231E613900DD0539 /* ReviewsViewModelTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; name = ReviewsViewModelTests.swift; path = WooCommerceTests/Reviews/ReviewsViewModelTests.swift; sourceTree = SOURCE_ROOT; }; - D85806282642BA5400A8AB6C /* PaymentCaptureOrchestrator.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PaymentCaptureOrchestrator.swift; sourceTree = ""; }; + D85806282642BA5400A8AB6C /* LegacyPaymentCaptureOrchestrator.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LegacyPaymentCaptureOrchestrator.swift; sourceTree = ""; }; D85A3C4F26C153A500C0E026 /* InPersonPaymentsPluginNotActivatedView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = InPersonPaymentsPluginNotActivatedView.swift; sourceTree = ""; }; D85A3C5126C15DE200C0E026 /* InPersonPaymentsPluginNotSupportedVersionView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = InPersonPaymentsPluginNotSupportedVersionView.swift; sourceTree = ""; }; D85A3C5526C1911600C0E026 /* InPersonPaymentsPluginNotInstalledView.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = InPersonPaymentsPluginNotInstalledView.swift; sourceTree = ""; }; @@ -8449,7 +8451,7 @@ 026D4A23280461960090164F /* LegacyCollectOrderPaymentUseCaseTests.swift */, 028E19BB2805BD22001C36E0 /* RefundSubmissionUseCaseTests.swift */, B9C4AB28280031AB007008B8 /* PaymentReceiptEmailParameterDeterminerTests.swift */, - 036F6EA5281847D5006D84F8 /* PaymentCaptureOrchestratorTests.swift */, + 036F6EA5281847D5006D84F8 /* LegacyPaymentCaptureOrchestratorTests.swift */, 02C27BCF282CDF9E0065471A /* CardPresentPaymentReceiptEmailCoordinatorTests.swift */, ); path = CardPresentPayments; @@ -8568,7 +8570,8 @@ E16715CA26663B0B00326230 /* CardPresentModalSuccessWithoutEmail.swift */, D8815B122638686200EDAD62 /* CardPresentModalError.swift */, D802541E2655137A001B2CC1 /* CardPresentModalNonRetryableError.swift */, - D85806282642BA5400A8AB6C /* PaymentCaptureOrchestrator.swift */, + 03E471CD293F63B4001A58AD /* PaymentCaptureOrchestrator.swift */, + D85806282642BA5400A8AB6C /* LegacyPaymentCaptureOrchestrator.swift */, B9C4AB2628002AF3007008B8 /* PaymentReceiptEmailParameterDeterminer.swift */, D82BB3A926454F3300A82741 /* CardPresentModalProcessing.swift */, 311D21E7264AEDB900102316 /* CardPresentModalScanningForReader.swift */, @@ -10223,7 +10226,7 @@ DE37517C28DC5FC6000163CB /* Authenticator.swift in Sources */, AED089F227C794BC0020AE10 /* View+CurrencySymbol.swift in Sources */, 03BB9EA7292E50B600251E9E /* CardPresentModalSelectSearchType.swift in Sources */, - D85806292642BA5400A8AB6C /* PaymentCaptureOrchestrator.swift in Sources */, + D85806292642BA5400A8AB6C /* LegacyPaymentCaptureOrchestrator.swift in Sources */, E1E636BB26FB467A00C9D0D7 /* Comparable+Woo.swift in Sources */, 450C2CB024CF006A00D570DD /* ProductTagsDataSource.swift in Sources */, 023D69BC2589BF5900F7DA72 /* PrintShippingLabelCoordinator.swift in Sources */, @@ -10814,6 +10817,7 @@ E10BC15E26CC06970064F5E2 /* ScrollableVStack.swift in Sources */, B50BB4162141828F00AF0F3C /* FooterSpinnerView.swift in Sources */, D8610CE2257099E100A5DF27 /* FancyAlertViewController+UnifiedLogin.swift in Sources */, + 03E471CE293F63B4001A58AD /* PaymentCaptureOrchestrator.swift in Sources */, B5980A6321AC879F00EBF596 /* Bundle+Woo.swift in Sources */, B59D1EE5219080B4009D1978 /* Note+Woo.swift in Sources */, 02913E9523A774C500707A0C /* UnitInputFormatter.swift in Sources */, @@ -11028,7 +11032,7 @@ 265D909D2446688C00D66F0F /* ProductCategoryViewModelBuilderTests.swift in Sources */, 03FBDAFD263EE4E800ACE257 /* CouponListViewModelTests.swift in Sources */, 02DAE7FF291B8C8A009342B7 /* DomainSelectorViewModelTests.swift in Sources */, - 036F6EA6281847D5006D84F8 /* PaymentCaptureOrchestratorTests.swift in Sources */, + 036F6EA6281847D5006D84F8 /* LegacyPaymentCaptureOrchestratorTests.swift in Sources */, B555531321B57E8800449E71 /* MockUserNotificationsCenterAdapter.swift in Sources */, 682210ED2909666600814E14 /* CustomerSearchUICommandTests.swift in Sources */, 4590B652261C8D1E00A6FCE0 /* WeightFormatterTests.swift in Sources */, diff --git a/WooCommerce/WooCommerceTests/ViewModels/CardPresentPayments/PaymentCaptureOrchestratorTests.swift b/WooCommerce/WooCommerceTests/ViewModels/CardPresentPayments/LegacyPaymentCaptureOrchestratorTests.swift similarity index 95% rename from WooCommerce/WooCommerceTests/ViewModels/CardPresentPayments/PaymentCaptureOrchestratorTests.swift rename to WooCommerce/WooCommerceTests/ViewModels/CardPresentPayments/LegacyPaymentCaptureOrchestratorTests.swift index 8e3d4ce2b09..827fe4f98bc 100644 --- a/WooCommerce/WooCommerceTests/ViewModels/CardPresentPayments/PaymentCaptureOrchestratorTests.swift +++ b/WooCommerce/WooCommerceTests/ViewModels/CardPresentPayments/LegacyPaymentCaptureOrchestratorTests.swift @@ -2,16 +2,16 @@ import XCTest import Yosemite @testable import WooCommerce -final class PaymentCaptureOrchestratorTests: XCTestCase { +final class LegacyPaymentCaptureOrchestratorTests: XCTestCase { private var stores: MockStoresManager! - private var sut: PaymentCaptureOrchestrator! + private var sut: LegacyPaymentCaptureOrchestrator! private let sampleSiteID: Int64 = 1234 override func setUp() { super.setUp() stores = MockStoresManager(sessionManager: SessionManager.makeForTesting()) - sut = PaymentCaptureOrchestrator(stores: stores, + sut = LegacyPaymentCaptureOrchestrator(stores: stores, paymentReceiptEmailParameterDeterminer: MockReceiptEmailParameterDeterminer()) }