App rejected under 3.1.1: Reviewer mistook native iOS StoreKit prompt for a custom password field

Hello everyone,

I'm facing a very frustrating situation with App Review for my indie app, CoffeePomodoro, and I'm hoping someone here or an Apple engineer can help shed some light on how to escalate and resolve this.

My recent update (Version 1.3.1, Submission ID: 59763b52-7c14-4b27-a2cf-2799d2bafe35) was rejected under Guideline 3.1.1 - In-App Purchase. The rejection message states: "We found that the app includes a feature to restore previously purchased In-App Purchase products by entering the user's Apple Account and password. However, In-App Purchases cannot be restored in this manner."

The Reality: There is absolutely zero custom UI, form, or TextField in my app that asks for an Apple ID or password.

When a user taps "Restore Purchases", the app simply calls Purchases.shared.restorePurchases() via the RevenueCat SDK, which directly wraps Apple's native SKPaymentQueue.restoreCompletedTransactions().

The credential prompt the reviewer saw is the native iOS system-level authentication dialog that appears automatically in the sandbox/TestFlight environment. This usually happens if the device or simulator being used for the review doesn't have an active Sandbox Apple ID already logged in.

I have explained this in the App Store Connect Resolution Center. I provided screen recordings showing it's the system dialog, and I attached code snippets proving the app only calls native APIs. Unfortunately, my explanations seem to be ignored, and I keep facing the same roadblock. It feels like the reviewers are mistaking their own OS's native prompt for a custom credential-harvesting screen.

Meanwhile, my users are waiting for this update to resolve their subscription issues, and I am stuck in a rejection loop for using Apple's own native API exactly as intended.

Has anyone else experienced this specific misunderstanding by the review team? How can I escalate this so someone actually reviews the screen recording and code snippets I provided?

Thank you for your time.

Is there an updated version of the RevenueCat SDK you can use? SKPaymentQueue is deprecated. The note in the documentation says "No longer supported".

The restore purchase behaviour in StoreKit2 has significantly changed. Years ago, it was a big deal. I think Apple still requires a Restore feature in the app, but it's really only because end users expect to see it. In StoreKit2 itself, there isn't any restore functionality. You just call refresh() on the AppTransaction.

This may be a user privacy issue. In the old system, when someone would run a pirated version of an app, it could display the AppleID of the original purchaser, who was some rando on the internet.

Never use the "Comment" feature. All it does is hide your replies. I'm aware of this so sometimes I check my old replies to see if there's a hidden comment. But other people might not do that. Just use the standard Reply box at the bottom.

RevenueCat already handles that

Apparently not

It doesn't matter that it's a native OS prompt. There are lots of apps out there from years ago that may still need the old restore feature. But that doesn't mean that Apple wants any new apps to use the old system.

I can't speak for Apple, but I'm pretty sure there's no mistake here. StoreKit2 is radically different than the old mechanism. There isn't even any true "Restore" functionality anymore. It's now just a reset. But the reset doesn't have any user-facing UI.

They definitely test with logged in Apple IDs. It wouldn't work otherwise. The only difference is that these Apple IDs aren't connected to real credit cards.

App rejected under 3.1.1: Reviewer mistook native iOS StoreKit prompt for a custom password field
 
 
Q