Hello everyone,
In our iOS app, we offer multiple auto-renewable subscription tiers within the same subscription group:
Lite (Monthly / Yearly) Basic (Monthly / Yearly) Plus (Monthly / Yearly) Pro (Monthly / Yearly) We are using Apple's native Offer Code redemption sheet (SKPaymentQueue.default().presentCodeRedemptionSheet() / AppStore.presentOfferCodeRedeemSheet).
The Issue We Are Facing: The user navigates to our subscription screen and selects the Pro Plan. The user taps our in-app "Redeem Offer Code" button, which presents Apple’s native redemption sheet. The user inputs an offer code that was created in App Store Connect specifically for the Basic Plan. When the user taps "Continue", Apple accepts the code and immediately presents the Apple Pay / Face ID confirmation to charge/subscribe the user to the Basic Plan. Because presentCodeRedemptionSheet() does not take any product ID parameter, Apple accepts the code for whichever product it was created for, regardless of the tier the user had selected on our paywall.
By the time our transaction observer receives the transaction callback (paymentQueue(_:updatedTransactions:)), the payment/purchase has already been finalized by Apple.
Questions: Can we restrict the native sheet to a specific Product ID? Is there any way with StoreKit 1 or StoreKit 2 to pass an expected productID to the redemption sheet so Apple only accepts codes eligible for that specific product?
Can we intercept or validate the code before payment? Is there any delegate callback or hook when the user taps the "Continue" button on the "Redeem Offer" sheet so we can validate if the code matches the selected plan before the transaction is charged?
What is Apple's recommended best practice? If a user redeems a code for a different tier (e.g., Basic instead of Pro), is the recommended approach to automatically switch and activate the redeemed plan on our backend since Apple has already completed the purchase, rather than rejecting it?
Any guidance from Apple engineers or developers who have handled this multi-tier scenario would be greatly appreciated!