diff --git a/ecommerce/extensions/api/serializers.py b/ecommerce/extensions/api/serializers.py
index 8ca14721d26..7b63d9a31a7 100644
--- a/ecommerce/extensions/api/serializers.py
+++ b/ecommerce/extensions/api/serializers.py
@@ -57,8 +57,8 @@
 )
 from ecommerce.extensions.catalogue.utils import attach_vouchers_to_coupon_product
 from ecommerce.extensions.checkout.views import ReceiptResponseView
-from ecommerce.extensions.iap.api.v1.utils import apply_price_of_inapp_purchase, get_auth_headers, create_ios_product
-from ecommerce.extensions.iap.constants import ANDROID_SKU_PREFIX, IOS_SKU_PREFIX
+from ecommerce.extensions.iap.api.v1.utils import apply_price_of_inapp_purchase, create_ios_product, get_auth_headers
+from ecommerce.extensions.iap.constants import ANDROID_SKU_PREFIX, CREATE_APPSTORE_PRODUCTS_FOR_INAPP, IOS_SKU_PREFIX
 from ecommerce.extensions.iap.processors.ios_iap import IOSIAP
 from ecommerce.extensions.iap.utils import create_mobile_seat
 from ecommerce.extensions.offer.constants import (
@@ -839,16 +839,18 @@ def _update_or_create_mobile_seats(self, course):
         if mobile_seats:
             self._update_mobile_seats(mobile_seats, web_seat, course)
         else:
+            logger.info("Creating mobile seats for course [%s]", course.id)
             create_mobile_seat(ANDROID_SKU_PREFIX, web_seat)
             ios_seat = create_mobile_seat(IOS_SKU_PREFIX, web_seat)
-            partner_short_code = self.context['request'].site.siteconfiguration.partner.short_code
-            configuration = settings.PAYMENT_PROCESSOR_CONFIG[partner_short_code.lower()][IOSIAP.NAME.lower()]
-            course_data = {
-                'price': ios_seat.stockrecords.first().price_excl_tax,
-                'name': course.name,
-                'key': course.id
-            }
-            create_ios_product(course_data, ios_seat, configuration)
+            if waffle.switch_is_active(CREATE_APPSTORE_PRODUCTS_FOR_INAPP):
+                partner_short_code = self.context['request'].site.siteconfiguration.partner.short_code
+                configuration = settings.PAYMENT_PROCESSOR_CONFIG[partner_short_code.lower()][IOSIAP.NAME.lower()]
+                course_data = {
+                    'price': ios_seat.price_excl_tax,
+                    'name': course.name,
+                    'key': course.id
+                }
+                create_ios_product(course_data, ios_seat, configuration)
 
     def _update_mobile_seats(self, mobile_seats, web_seat, course):
         failure_msg = False
@@ -942,7 +944,6 @@ def save(self):  # pylint: disable=arguments-differ
 
                 resp_message = course.publish_to_lms()
                 published = (resp_message is None)
-
                 if published:
                     self._update_or_create_mobile_seats(course)
 
diff --git a/ecommerce/extensions/api/v2/tests/views/test_publication.py b/ecommerce/extensions/api/v2/tests/views/test_publication.py
index adc881ac848..a76672dc47c 100644
--- a/ecommerce/extensions/api/v2/tests/views/test_publication.py
+++ b/ecommerce/extensions/api/v2/tests/views/test_publication.py
@@ -24,6 +24,7 @@
 from ecommerce.entitlements.utils import create_or_update_course_entitlement
 from ecommerce.extensions.api.v2.tests.views import JSON_CONTENT_TYPE
 from ecommerce.extensions.catalogue.tests.mixins import DiscoveryTestMixin
+from ecommerce.extensions.iap.constants import CREATE_APPSTORE_PRODUCTS_FOR_INAPP
 from ecommerce.extensions.iap.utils import create_child_products_for_mobile
 from ecommerce.tests.testcases import TestCase
 
@@ -158,6 +159,7 @@ def setUp(self):
         self.client.login(username=self.user.username, password=self.password)
 
         self.publication_switch = toggle_switch('publish_course_modes_to_lms', True)
+        self.appstore_product_switch = toggle_switch(CREATE_APPSTORE_PRODUCTS_FOR_INAPP, False)
 
     def _toggle_publication(self, is_enabled):
         """Toggle LMS publication."""
@@ -233,7 +235,7 @@ def assert_entitlement_saved(self, course, expected):
         self.assertEqual(entitlement.attr.UUID, self.course_uuid)
         self.assertEqual(entitlement.stockrecords.get(partner=self.partner).price_excl_tax, expected['price'])
 
-    def assert_seat_saved(self, course, expected, test_mobile_seats=False):
+    def assert_seat_saved(self, course, expected, test_mobile_seats=True):
         certificate_type = ''
         verified_product = False
 
@@ -258,17 +260,17 @@ def assert_seat_saved(self, course, expected, test_mobile_seats=False):
         self.assertEqual(seat.stockrecords.get(partner=self.partner).price_excl_tax, expected['price'])
 
         if test_mobile_seats and verified_product:
-            android_seat = course.seat_products.get(title='Android ' + seat_title)
+            android_seat = course.seat_products.get(title='Android ' + seat_title.lower())
             self.assertEqual(android_seat.expires, expires)
             self.assertEqual(android_seat.stockrecords.get(partner=self.partner).price_excl_tax, expected['price'])
 
-            ios_seat = course.seat_products.get(title='Ios ' + seat_title)
+            ios_seat = course.seat_products.get(title='Ios ' + seat_title.lower())
             self.assertEqual(ios_seat.expires, expires)
             self.assertEqual(ios_seat.stockrecords.get(partner=self.partner).price_excl_tax, expected['price'])
 
         return seat
 
-    def assert_course_saved(self, course_id, expected, enrollment_code_count=0, test_mobile_seats=False):
+    def assert_course_saved(self, course_id, expected, enrollment_code_count=0, test_mobile_seats=True):
         """Verify that the expected Course and associated products have been saved."""
         # Verify that Course was saved.
         self.assertTrue(Course.objects.filter(id=course_id).exists())
@@ -343,7 +345,7 @@ def test_update(self):
             response = self.client.put(self.update_path, json.dumps(updated_data), JSON_CONTENT_TYPE)
             self.assertEqual(response.status_code, 500)
             self.assertEqual(response.data.get('error'), error_msg)
-            self.assert_course_saved(self.course_id, expected=self.data)
+            self.assert_course_saved(self.course_id, expected=self.data, test_mobile_seats=False)
 
             # If publication succeeds, the view should return a 200 and data should be saved.
             mock_publish.return_value = None
@@ -512,8 +514,8 @@ def test_mobile_seats_update(self, _, __):
 
         # Since we are only concerned with expiry date and price
         # therefore we are setting title manually here.
-        android_seat.product.title = 'Android Seat in A New Name with verified certificate'
-        ios_seat.product.title = 'Ios Seat in A New Name with verified certificate'
+        android_seat.product.title = 'Android seat in a new name with verified certificate'
+        ios_seat.product.title = 'Ios seat in a new name with verified certificate'
         android_seat.product.save()
         ios_seat.product.save()
         with mock.patch.object(LMSPublisher, 'publish') as mock_publish:
@@ -523,5 +525,21 @@ def test_mobile_seats_update(self, _, __):
             response = self.client.put(self.update_path, json.dumps(updated_data), JSON_CONTENT_TYPE)
 
             self.assertEqual(response.status_code, 200)
-            self.assert_course_saved(self.course_id, expected=updated_data,
-                                     enrollment_code_count=1, test_mobile_seats=True)
+            self.assert_course_saved(self.course_id, expected=updated_data, enrollment_code_count=1)
+
+    @mock.patch('ecommerce.extensions.api.serializers.create_ios_product')
+    def test_ios_seat_created(self, mock_create_ios_product):
+        """Verify that a Course and associated mobile products can be updated and published."""
+        self.create_course_and_seats()
+        updated_data = self.generate_update_payload()
+
+        with mock.patch.object(LMSPublisher, 'publish') as mock_publish:
+            # If publication succeeds, the view should return a 200 and data should be saved.
+            mock_publish.return_value = None
+            self.appstore_product_switch.active = True
+            self.appstore_product_switch.save()
+
+            response = self.client.put(self.update_path, json.dumps(updated_data), JSON_CONTENT_TYPE)
+            mock_create_ios_product.assert_called_once()
+            self.assertEqual(response.status_code, 200)
+            self.assert_course_saved(self.course_id, expected=updated_data, enrollment_code_count=1)
diff --git a/ecommerce/extensions/iap/api/v1/views.py b/ecommerce/extensions/iap/api/v1/views.py
index a896421dd22..87033d4a4a6 100644
--- a/ecommerce/extensions/iap/api/v1/views.py
+++ b/ecommerce/extensions/iap/api/v1/views.py
@@ -4,6 +4,7 @@
 
 import app_store_notifications_v2_validator as asn2
 import httplib2
+import waffle
 from django.conf import settings
 from django.db import transaction
 from django.utils.decorators import method_decorator
@@ -84,6 +85,7 @@
 from ecommerce.extensions.iap.api.v1.exceptions import RefundCompletionException
 from ecommerce.extensions.iap.api.v1.serializers import MobileOrderSerializer
 from ecommerce.extensions.iap.api.v1.utils import create_ios_product, products_in_basket_already_purchased
+from ecommerce.extensions.iap.constants import CREATE_APPSTORE_PRODUCTS_FOR_INAPP
 from ecommerce.extensions.iap.models import IAPProcessorConfiguration
 from ecommerce.extensions.iap.processors.android_iap import AndroidIAP
 from ecommerce.extensions.iap.processors.ios_iap import IOSIAP
@@ -487,18 +489,19 @@ def post(self, request):
             course.publish_to_lms()
             created_skus[course_run_key] = [mobile_products[0].partner_sku, mobile_products[1].partner_sku]
 
-            # create ios product on appstore
-            partner_short_code = request.site.siteconfiguration.partner.short_code
-            configuration = settings.PAYMENT_PROCESSOR_CONFIG[partner_short_code.lower()][IOSIAP.NAME.lower()]
-            ios_product = list((filter(lambda sku: 'ios' in sku.partner_sku, mobile_products)))[0]
-            course_data = {
-                'price': ios_product.price_excl_tax,
-                'name': course.name,
-                'key': course_run_key
-            }
-            error_msg = create_ios_product(course_data, ios_product, configuration)
-            if error_msg:
-                failed_ios_products.append(error_msg)
+            if waffle.switch_is_active(CREATE_APPSTORE_PRODUCTS_FOR_INAPP):
+                # create ios product on appstore
+                partner_short_code = request.site.siteconfiguration.partner.short_code
+                configuration = settings.PAYMENT_PROCESSOR_CONFIG[partner_short_code.lower()][IOSIAP.NAME.lower()]
+                ios_product = list((filter(lambda sku: 'ios' in sku.partner_sku, mobile_products)))[0]
+                course_data = {
+                    'price': ios_product.price_excl_tax,
+                    'name': course.name,
+                    'key': course_run_key
+                }
+                error_msg = create_ios_product(course_data, ios_product, configuration)
+                if error_msg:
+                    failed_ios_products.append(error_msg)
 
         result = {
             'new_mobile_skus': created_skus,
diff --git a/ecommerce/extensions/iap/constants.py b/ecommerce/extensions/iap/constants.py
index 2847da95e90..1bfddff4cd8 100644
--- a/ecommerce/extensions/iap/constants.py
+++ b/ecommerce/extensions/iap/constants.py
@@ -2,3 +2,13 @@
 ANDROID_SKU_PREFIX = 'android'
 IOS_SKU_PREFIX = 'ios'
 MISSING_WEB_SEAT_ERROR = "Couldn't find existing web seat for course [%s]"
+
+# .. toggle_name: create_appstore_products_for_inapp
+# .. toggle_type: waffle_switch
+# .. toggle_default: False
+# .. toggle_description: Create ios products on appstore using Apple in-app apis.
+# .. toggle_use_cases: open_edx
+# .. toggle_creation_date: 2023-07-25
+# .. toggle_tickets: LEARNER-9951
+# .. toggle_status: supported
+CREATE_APPSTORE_PRODUCTS_FOR_INAPP = 'create_appstore_products_for_inapp'