All in-app purchases are suddenly marked with a red warning sign in the App Store

My app is currently being reviewed. It is being rejected because of the error 301 (it is an "underlying error") encountered when purchasing an item through the review team. With Testflight, all purchases and restores work just fine with no such error ever occurring. I have already using 15 different sandbox account users and performed about 1000 test purchases and restores without errors. I still don't know when or why the 301 error occurs. The error only occurs when the app is in review.

In any case, after the rejection message, I looked at the product list in the App Store. I noticed that all products have a red warning label:

Then I changed the price for one of the products, which initially led to an error message. But after a second try the price change worked for one of the products, and all warning messages were gone:

Does anyone know the reason for these warning labels?

Does anyone have experience with error number 301?

I am using iOS 14.5 with the target platforms iPhone / iPodTouch and as IAP: non-consumable content hosted by Apple.

Accepted Reply

About rejected products:

I've got feedback from Apple about the invalidation, resp. rejection of the products:

This is the expected behavior. In-app purchases submitted for review using the app version binary are reviewed as part of the app review process. If the app is rejected, any in-app purchases associated with the app version binary are also rejected. [Translated from German language]

About Error code 301 when purchasing a product during app review:

I made these two changes after multiple rejections due to Error code 301:

1.) I missed to use a distribution provisioning profile, instead i used a developer provisioning profile (... ok my fault .... 🤓)

2.) During the TestFlight tests and the tests with the StoreKit test framework, the following code worked well:

SKMutablePayment *payment = [[SKMutablePayment alloc] init];
payment.productIdentifier = productid;

But as you can read here: Requesting a Payment from the App Store:

When the user selects a product to buy, create a payment request using the corresponding SKProduct object and set the quantity if needed, as shown below. The product object comes from the array of products returned by your app’s products request, as discussed in Fetching Product Information from the App Store.

Therefore I have changed my code accordingly:

SKMutablePayment *payment = [SKMutablePayment paymentWithProduct:_products[productid]];

with _products like this: NSMutableDictionary<NSString *,SKProduct *> *_products; it holds all the SKProduct objects.

** After these two changes, the app and products are now no longer rejected. 😌**

Replies

About rejected products:

I've got feedback from Apple about the invalidation, resp. rejection of the products:

This is the expected behavior. In-app purchases submitted for review using the app version binary are reviewed as part of the app review process. If the app is rejected, any in-app purchases associated with the app version binary are also rejected. [Translated from German language]

About Error code 301 when purchasing a product during app review:

I made these two changes after multiple rejections due to Error code 301:

1.) I missed to use a distribution provisioning profile, instead i used a developer provisioning profile (... ok my fault .... 🤓)

2.) During the TestFlight tests and the tests with the StoreKit test framework, the following code worked well:

SKMutablePayment *payment = [[SKMutablePayment alloc] init];
payment.productIdentifier = productid;

But as you can read here: Requesting a Payment from the App Store:

When the user selects a product to buy, create a payment request using the corresponding SKProduct object and set the quantity if needed, as shown below. The product object comes from the array of products returned by your app’s products request, as discussed in Fetching Product Information from the App Store.

Therefore I have changed my code accordingly:

SKMutablePayment *payment = [SKMutablePayment paymentWithProduct:_products[productid]];

with _products like this: NSMutableDictionary<NSString *,SKProduct *> *_products; it holds all the SKProduct objects.

** After these two changes, the app and products are now no longer rejected. 😌**