@@ -26,16 +26,12 @@ final class StoreCreationCoordinator: Coordinator {
2626 /// This property is kept as a lazy var instead of a dependency in the initializer because `InAppPurchasesForWPComPlansManager` is a @MainActor.
2727 /// If it's passed in the initializer, all call sites have to become @MainActor which results in too many changes.
2828 @MainActor
29- private lazy var iapManager : InAppPurchasesForWPComPlansProtocol = {
30- #if DEBUG
29+ private lazy var purchasesManager : InAppPurchasesForWPComPlansProtocol = {
3130 if featureFlagService. isFeatureFlagEnabled ( . storeCreationM2WithInAppPurchasesEnabled) {
3231 return InAppPurchasesForWPComPlansManager ( stores: stores)
3332 } else {
34- return MockInAppPurchases ( )
33+ return WebPurchasesForWPComPlans ( stores : stores )
3534 }
36- #else
37- InAppPurchasesForWPComPlansManager ( stores: stores)
38- #endif
3935 } ( )
4036
4137 @Published private var siteIDFromStoreCreation : Int64 ?
@@ -54,7 +50,7 @@ final class StoreCreationCoordinator: Coordinator {
5450 stores: StoresManager = ServiceLocator . stores,
5551 analytics: Analytics = ServiceLocator . analytics,
5652 featureFlagService: FeatureFlagService = ServiceLocator . featureFlagService,
57- iapManager : InAppPurchasesForWPComPlansProtocol ? = nil ) {
53+ purchasesManager : InAppPurchasesForWPComPlansProtocol ? = nil ) {
5854 self . source = source
5955 self . navigationController = navigationController
6056 // Passing the `standard` configuration to include sites without WooCommerce (`isWooCommerceActive = false`).
@@ -68,8 +64,8 @@ final class StoreCreationCoordinator: Coordinator {
6864 self . featureFlagService = featureFlagService
6965
7066 Task { @MainActor in
71- if let iapManager {
72- self . iapManager = iapManager
67+ if let purchasesManager {
68+ self . purchasesManager = purchasesManager
7369 }
7470 }
7571 }
@@ -81,15 +77,17 @@ final class StoreCreationCoordinator: Coordinator {
8177 Task { @MainActor in
8278 do {
8379 presentIAPEligibilityInProgressView ( )
84- guard await iapManager . inAppPurchasesAreSupported ( ) else {
80+ guard await purchasesManager . inAppPurchasesAreSupported ( ) else {
8581 throw PlanPurchaseError . iapNotSupported
8682 }
87- let products = try await iapManager. fetchProducts ( )
83+ let products = try await purchasesManager. fetchProducts ( )
84+ let expectedPlanIdentifier = featureFlagService. isFeatureFlagEnabled ( . storeCreationM2WithInAppPurchasesEnabled) ?
85+ Constants . iapPlanIdentifier: Constants . webPlanIdentifier
8886 guard let product = products. first,
89- product. id == Constants . planIdentifier else {
87+ product. id == expectedPlanIdentifier else {
9088 throw PlanPurchaseError . noMatchingProduct
9189 }
92- guard try await iapManager . userIsEntitledToProduct ( with: product. id) == false else {
90+ guard try await purchasesManager . userIsEntitledToProduct ( with: product. id) == false else {
9391 throw PlanPurchaseError . productNotEligible
9492 }
9593 navigationController. dismiss ( animated: true ) { [ weak self] in
@@ -299,18 +297,20 @@ private extension StoreCreationCoordinator {
299297 guard let self else { return }
300298 self . showWPCOMPlan ( from: navigationController,
301299 planToPurchase: planToPurchase,
302- siteID: result. siteID)
300+ siteID: result. siteID,
301+ siteSlug: result. siteSlug)
303302 }
304303 navigationController. pushViewController ( storeSummary, animated: true )
305304 }
306305
307306 @MainActor
308307 func showWPCOMPlan( from navigationController: UINavigationController ,
309308 planToPurchase: WPComPlanProduct ,
310- siteID: Int64 ) {
309+ siteID: Int64 ,
310+ siteSlug: String ) {
311311 let storePlan = StoreCreationPlanHostingController ( viewModel: . init( plan: planToPurchase) ) { [ weak self] in
312312 guard let self else { return }
313- await self . purchasePlan ( from: navigationController, siteID: siteID, planToPurchase: planToPurchase)
313+ await self . purchasePlan ( from: navigationController, siteID: siteID, siteSlug : siteSlug , planToPurchase: planToPurchase)
314314 } onClose: { [ weak self] in
315315 guard let self else { return }
316316 self . showDiscardChangesAlert ( )
@@ -321,25 +321,40 @@ private extension StoreCreationCoordinator {
321321 @MainActor
322322 func purchasePlan( from navigationController: UINavigationController ,
323323 siteID: Int64 ,
324+ siteSlug: String ,
324325 planToPurchase: WPComPlanProduct ) async {
325326 do {
326- let result = try await iapManager. purchaseProduct ( with: planToPurchase. id, for: siteID)
327- switch result {
328- case . success:
329- showInProgressViewWhileWaitingForJetpackSite ( from: navigationController, siteID: siteID)
330- default :
331- if !featureFlagService. isFeatureFlagEnabled ( . storeCreationM2WithInAppPurchasesEnabled) {
332- // Since a successful result cannot be easily mocked, any result is considered a success
333- // when using a mock for IAP.
327+ let result = try await purchasesManager. purchaseProduct ( with: planToPurchase. id, for: siteID)
328+
329+ if featureFlagService. isFeatureFlagEnabled ( . storeCreationM2WithInAppPurchasesEnabled) {
330+ switch result {
331+ case . success:
334332 showInProgressViewWhileWaitingForJetpackSite ( from: navigationController, siteID: siteID)
333+ default :
334+ return
335+ }
336+ } else {
337+ switch result {
338+ case . pending:
339+ showWebCheckout ( from: navigationController, siteID: siteID, siteSlug: siteSlug)
340+ default :
341+ return
335342 }
336- return
337343 }
338344 } catch {
339345 showPlanPurchaseErrorAlert ( from: navigationController, error: error)
340346 }
341347 }
342348
349+ @MainActor
350+ func showWebCheckout( from navigationController: UINavigationController , siteID: Int64 , siteSlug: String ) {
351+ let checkoutViewModel = WebCheckoutViewModel ( siteSlug: siteSlug) { [ weak self] in
352+ self ? . showInProgressViewWhileWaitingForJetpackSite ( from: navigationController, siteID: siteID)
353+ }
354+ let checkoutController = AuthenticatedWebViewController ( viewModel: checkoutViewModel)
355+ navigationController. pushViewController ( checkoutController, animated: true )
356+ }
357+
343358 @MainActor
344359 func showInProgressViewWhileWaitingForJetpackSite( from navigationController: UINavigationController ,
345360 siteID: Int64 ) {
@@ -410,11 +425,6 @@ private extension StoreCreationCoordinator {
410425 return continuation. resume ( throwing: StoreCreationError . newSiteUnavailable)
411426 }
412427
413- // When using a mock for IAP, returns the site without waiting for the site to become a Jetpack site.
414- if !self . featureFlagService. isFeatureFlagEnabled ( . storeCreationM2WithInAppPurchasesEnabled) {
415- return continuation. resume ( returning: site)
416- }
417-
418428 guard site. isJetpackConnected && site. isJetpackThePluginInstalled else {
419429 return continuation. resume ( throwing: StoreCreationError . newSiteIsNotJetpackSite)
420430 }
@@ -425,8 +435,10 @@ private extension StoreCreationCoordinator {
425435
426436 @MainActor
427437 func showPlanPurchaseErrorAlert( from navigationController: UINavigationController , error: Error ) {
438+ let errorMessage = featureFlagService. isFeatureFlagEnabled ( . storeCreationM2WithInAppPurchasesEnabled) ?
439+ Localization . PlanPurchaseErrorAlert. defaultErrorMessage: Localization . PlanPurchaseErrorAlert. webPurchaseErrorMessage
428440 let alertController = UIAlertController ( title: Localization . PlanPurchaseErrorAlert. title,
429- message: Localization . PlanPurchaseErrorAlert . defaultErrorMessage ,
441+ message: errorMessage ,
430442 preferredStyle: . alert)
431443 alertController. view. tintColor = . text
432444 _ = alertController. addCancelActionWithTitle ( Localization . StoreCreationErrorAlert. cancelActionTitle) { _ in }
@@ -493,6 +505,10 @@ private extension StoreCreationCoordinator {
493505 " Please try again and make sure you are signed in to an App Store account eligible for purchase. " ,
494506 comment: " Message of the alert when the WPCOM plan cannot be purchased in the store creation flow. "
495507 )
508+ static let webPurchaseErrorMessage = NSLocalizedString (
509+ " Please try again, or exit the screen and check back on your store if you previously left the checkout screen while payment is in progress. " ,
510+ comment: " Message of the alert when the WPCOM plan cannot be purchased in a webview in the store creation flow. "
511+ )
496512 static let cancelActionTitle = NSLocalizedString (
497513 " OK " ,
498514 comment: " Button title to dismiss the alert when the WPCOM plan cannot be purchased in the store creation flow. "
@@ -510,7 +526,8 @@ private extension StoreCreationCoordinator {
510526
511527 enum Constants {
512528 // TODO: 8108 - update the identifier to production value when it's ready
513- static let planIdentifier = " debug.woocommerce.ecommerce.monthly "
529+ static let iapPlanIdentifier = " debug.woocommerce.ecommerce.monthly "
530+ static let webPlanIdentifier = " 1021 "
514531 }
515532
516533 /// Error scenarios when purchasing a WPCOM plan.
0 commit comments