Testing In-App-Purchases in TestFlight/Sandbox purchase modal issue - ios

We are experiencing a very weird behavior when testing In-App-Purchases via TestFlight/Sandbox. The tooling used for the implementation in React Native is: Expo In App purchases
We have configured multiple renewable subscriptions as our offered products.
After a successful subscription purchase, almost all testers are experiencing a very rare interaction with the purchase modal, even happening when the app is in the background.
We are steadily trying to find what could be wrong with our implementation, but the fact that the modal is appearing randomly presenting the confirm purchase dialog multiple times, and with a random plan, we are a bit lost on the cause.
Especially because with the app in background mode, app code should not be executing/running since we don’t have background mode capabilities set up for that to work.
Is this by chance a wrong/known behavior of the Sandbox environment?
In any case, any clue or idea to re-orientate the efforts in that direction is very valuable at this point.
EDIT 1:
The modal appearing is the following one:

You can get this behavior if you test auto renewable subscriptions in a test environment (such as when launched from Xcode).
In order to make it easier to test the nature of auto renewable subscriptions, the renewal time has been shortened when in a test environment, so that 5 minutes in real time represents 1 month in subscription time, 1 hour in real time represents one year in subscription time and so on...
When in test mode, a subscription is renewed up to six times by default and then it will be allowed to expire. Since iOS 14, you can change some of these test parameters.
The reason you get these calls to your app in both foreground and in the background, is most likely because StoreKit tries to simulate calls that your app would normally receive whenever a subscription is renewed.
In a test environment, this often prompts the user to enter their account credentials, in order for iOS to be able to sync the subscription status with AppStore; so this behavior with password dialogs popping up every now and then, is not something your real users will normally experience from the actual release.
If you test a lot of different auto renewable subscriptions on one account, these password dialogs that pop up can be a real hassle, but they will eventually stop appearing once all your test subscriptions has expired.
You can read all about testing auto renewable subscriptions here:
https://help.apple.com/app-store-connect/#/dev7e89e149d

Related

Testing iOS subscriptions upgrade/downgrade on sandbox

At the moment, we have one auto-renewable subscription on our live app, and we want to add two more, where the only difference is the price and the subscription time. To accomplish that, we created a "subscription group" and everything is set up on the apple side:
and the app is currently reading all the packs from the store and allow the user to buy them.
Our issue is that we can't fully test the upgrade/downgrade feature when trying to buy another subscription level on sandbox (iOS 14.5). If we buy the lowest pack first, and then try to buy a superior pack, a popup should appear saying that we want to modify our current subscription plan to another one and that it will start on XX/XX/2021 as seen here (image from a tutorial):
This is not the behaviour we are seeing on our app (on sandbox). When we try to buy a superior plan the app shows the normal purchase popup:
and it proceeds to buy the pack normally without showing the popup warning that we are changing our current plan.
This causes some concerns, as it implies that the user is buying two subscriptions. They are on the same subscription group, so it should be impossible, but still brings concerns... Did anyone experienced the same issue? Is this the normal behaviour in sandbox?

iOS subscriptions: Why get subscriptions in sandbox stuck in is_in_billing_retry_period?

I am working on implementing iOS subscriptions. If a new subscription is purchased for a new test user in most cases the subscription will be renewed 5 times and is than canceled.
However, in some cases the subscription moves to is_in_billing_retry_period = true after the initial purchase and is stuck in this state forever.
I know that is_in_billing_retry_period is used to implement a grace period and than in production Apple will try to recover the the subscription (e.g. solve any billing issues) and it is great that this use case can be tested.
BUT is there any logic on which purchases will renew and which will get stuck in is_in_billing_retry_period? Or is this a random behaviour?
It is quite hard to test special use cases if one cannot specify which use case will be performed next by the sandbox...

iOS Manage my Subscription with Sandbox Account

Background
I have an application that supports in-app purchase with Apple subscription (in particular auto-renewable plans).
Using the WWDC 2016 slides material, in the Manage Subscription page, (inside iTunes & App Store -> View my Apple ID), we have this:
in which the user is allowed to change the current subscription plan (and also to cancel it). So far, so good.
Case scenario
I would like to simulate the scenario of a user changing account (or cancelling the current subscription) from the Manage Subscriptions page.
My issue (and possible solutions)
Thus, I am now facing the issue of testing the reported scenario.
It seems to conflict with Sandbox Account for testing purposes. In particular: if I try to login with the sandbox Apple ID into the iTunes Store & App Store page, I of course receive the message: iTunes Account creation not allowed (as reported in this question).
The most straight-forward solution seems the one reported in this thread (shortly: let the subscription plan auto-renew for 5 times with 5 minutes period, after which we should receive the 21006 error). Anyway, I am not sure that it could be applied to this case, since it seems only including the cancel my subscription case.
Another thread comes directly from the apple forum (this thread) but: (1) something is strange, i.e. the iTunes account creation not allowed error seems not to appear when logging into iTunes with sandbox accounts - while it happens to me systematically) and (2) even after logging in, the subscriptions are reported not to be shown.
I expect that everything works using a real Apple ID, but this is something I don't really want to do.
Conclusion (?) and question
So, finally :), my question. Is there a way to test the reported case scenario (or an equivalent one) without using a real apple ID, thus without triggering a real transaction? I don't really want to believe that the current sandbox testing mechanism does not include it.
Thanks in avance to all!
An iTunesConnect Sandbox test user account can test auto-renewing subscriptions but that account cannot login to iTunes and utilize the Manage Subscriptions.
Only Option
The only option I have seen being utilized is to essentially get your app fully approved for the app store (do not auto-release). Once approved, use a promo code to download and live test the Manage Subscription scenarios. If it all checks out, release the app. (I cant seem to find the link for this but will add it here if I come across it.)
Other Notes Testing Auto-Renewing Subscriptions
Duration times are shortened when test your auto-renewable subscriptions. Additionally, test subscriptions only auto-renew a maximum of six times.
Reference Link
~Emphasis is mine
1 week = 3 minutes
1 month = 5 minutes
2 months = 10 minutes
3 months = 15 minutes
6 months = 30 minutes
1 year = 1 hour
This thread has a response posted from an Apple Developer in regards to this situation. Link

Auto restore/sync in-app purchases in Newsstand app prior to iOS 9 and iTunes password prompt issue

I have recently started developing Newsstand application and need to deal with the restoration of in-app purchases. There are cases resported that some users made unwanted "duplicated" purchase in the following situation:
There are two kinds of purchases in the app:
1. One year subscription which will allow users to have access to all magazines issued within the subscription period
2. Single specific issue purchase, which will allow users to buy specific issue they would like to access to
And the problem arises when:
User made an one year subscription
User install the Newsstand app on another device/re-stall after deleting the app
User purchase single issue which should be included in the subscription
In step 3, the user should have "owned" the issue he wanted to purchase and the purchase option for that specific issue will not be available, but since he/she didn't perform a restore, the app does not know the user has an active subscription which includes the targeted issue, as a result the user is charged for the specific issue while he/she should not be.
To deal with this, I am thinking of prompting the user to perform a restore upon first launch of the app after installation, but there are a few questions I would like to clearify and couldn't find any reference or documentation:
I was told that prior to iOS 9, the Newsstand app (the one which will have all contents of newsstand applications' contents showed up as a bookshelf) could auto sync/restore purchased contents of the iTunes account logged-in on the device, i.e. after installation and launch the app, the user will have all of his previous purchase there without manually performing a restore. Is this real and is there any documentation regarding this? Or is this related to certain settings related to AppStore's auto-download, etc? This is reported by one of the user and he claimed that he is very sure that he got all the contents without manually restoration after installing the app as he tested this on his iOS 8 device. I ran out of luck in finding and proofing this as I do not have any physical device with iOS 8 or before, and the simulator does not support purchase related API.
When performing restoration, under what circumstances the user will be prompted for password input? As sometimes I would proceed to restoration directly without password input, is this related to time passed since last password input?
Thanks!

Cross-device In-AppPurchases

due to the fact that Apple requires at least one auto-renewable subscription or one free subscription for a newsstand app, we changed all monthly subscriptions of our news app to auto-renewable ones while adding newsstand functionality.
When I try to buy one of these subscriptions on device #1 (e.g. my iPad) everything works fine. When I try to buy the same subscription on device #2 (e.g. my iPhone), I get a message from the Store Kit telling me that I am already a subscriber of this certain issue (which is ok as well) but afterwards the process is finished without having bought anything.
Checking the log shows, that the SKPaymentTransactionObserver delegate method paymentQueue:updatedTransactions: first gets a transaction for that product in the state 'SKPaymentTransactionStatePurchasing' (ok so far) followed by transaction in the state 'SKPaymentTransactionStateFailed'. Having a closer look on the transaction error code and message of the last transaction, the transaction error description says "Cannot connect to iTunes Store'. A second purchase of another product (bought the first time on the second device) works perfectly. Both purchases are done against the sandbox, does anybody has a hint how to address this problem.
Thanks for your help in advance
Michael
It shouldn't be possible to to purchase the same auto-renewing subscription on multiple devices, instead you should implement restore functionality, and restore on the second device. It's worth noting that the sandbox uses time compression for testing, so a 1 month subscription, will actually auto-renew every 5 minutes or so, and will only renew 5 times in a day. it's possible the original subscription has expired by the time you try to repurchase for the second time.
Often the sandbox error messages are not useful, the "Couldn't connect to iTunes" is not relevant.
I would suggest reading the whole of this page very carefully, as there are a lot of important details it's easy to miss. The bit about restoring purchases is here:
https://developer.apple.com/library/ios/#documentation/NetworkingInternet/Conceptual/StoreKitGuide/MakingaPurchase/MakingaPurchase.html#//apple_ref/doc/uid/TP40008267-CH3-SW1
Best of luck

Resources