With regards to your finding, this is a bug report issue to be investigated by the App Store Server team. The App Store Server is responsible for the contents of the appStoreReceipt. I’ve provided the instructions for you to submit a bug report below. First let me clarify the situation, then provide some suggestions as to how the app should behave when this situation is detected.
First to clarify the issue - The empty in-app array is occurring moments after the user has attempted an in-app purchase and the app has sent the appStoreReceipt directly to the verifyReceipt server or to your server and on to the verifyReceipt server, then the validated appStoreReceipt is returned where the app detects the empty in_app array. My reason for asking is that if the user has two devices, both with your app, and the purchase is made from one device, but the 2nd device is used and the app launched, and the appStoreReceipt processed, for the second app, the validated appStoreReceipt will show an empty in_app array.
Now for some thoughts on how the app should handle this situation -
1. If the in_app array is found to be empty, DO NOT call finishTransaction. Per the documentation <https://developer.apple.com/documentation/storekit/skpaymentqueue/1506003-finishtransaction>
“Call finishTransaction(_:) only after the app has finished all work it performs to complete the transaction. “
It would have been clearer to say - don’t call finishTransaction unless the app is satisfied that the purchase is valid and the content associated with the purchase has been provided to the user. The main reason for this - when the app makes the finishTransaction call, it’s telling the App Store that the transaction is now considered complete. If the finishTransaction is not made, then the consumable transaction remains on the transaction queue and will be processed the next time that the transactionObserver is activated. For an iOS app, there are three times that the transactionObserver is activated to check the App Store.
1. When the addTransactionObserver is called
2. When the addPayment call is made to make a purchase and
3. When the application moves from the background to the foreground - for example if the app is active and you move the app launch screen to the foreground, then switch back to activating the app, the transactionObserver will query the App Store.
The reason it’s important - the App Store is responsible for writing the contents of the appStoreReceipt. At some point it may finally realize the the purchase was not included, and add it - then when the transactionObserver fires and detects the queued transaction it will process it much as if the user just pressed the “Buy” button.
Another strategy to consider - that of validating the appStoreReceipt when the app launches to determine what in-app purchases have already been made - only validate the receipt if it is present. If the app validates the appStoreReceipt then this makes it possible for the solution - whereby users can delete the app and re-install it from the App Store. Some developers have reported that in doing this, the App Store installs the app with the updated appStoreReceipt and now the subscription service is available. There is no requirement that the app do this, but it’s a means to stay current as to what services are available to the app.
Finally, another solution - if your product is an auto-renewing subscription - a suggestion is to implement server-to-server notifications. Whenever a new subscription purchase occurs, your server will be notified as to the new transactions. The problem you've reported has been submitted by others, but I've not heard of this issue reported by developers who've implemented server-to-server notifications. For more information about server-to-server notifications, I refer you to the Apple Developer documentation - <https://developer.apple.com/documentation/storekit/in-app_purchase/subscriptions_and_offers/enabling_server-to-server_notifications>
As for submitting the bug report - I’ve been asked that when developer submit such report, please include a copy of the base64 encoded appStoreReceipts captured after the .purchased event along with the iTunes user account - if possible.
To submit a bug report, please use the Apple Developer Feedback web page -
<https://feedbackassistant.apple.com/>.
Enter the “Feedback Assistant” page and login
Click on the Compose icon to start a new bug report
Start by clicking on the appropriate OS button - “iOS and iPadOS”
1. In the “Descriptive Title” field, enter an appropriate description.
2. In the “Problem Area” field select “StoreKit”
3. In the “Type of Feedback” select “Incorrect / Unexpected Behavior”
4. In the “Describe the Issue” section enter the following
- application ID (and In-App Purchase identifiers if appropriate)
- production environment
- make sure to indicate the the issue has occurred moments after the user has made the in-app purchase and the app has been notified as to the successful transaction, then the appStoreReceipt in the app is validated.
- the information above - the appStoreReceipt may be in a text file and uploaded as per below.
rich kubota - rkubota@apple.com
developer technical support CoreOS/Hardware/MFI