React Native - Subscriptions (iOS)01 Mar 2018
- implement subscriptions in application
- add subscription in IC
- test subscription on real device
- publish release with subscription
- view financial reports
- iTunes Connect
- in-app purchase
- Workflow for configuring in-app purchases
- In-App Purchase Programming Guide
implement subscriptions in application
- Adding In-App Purchase to Your Applications
- Validating Receipts With the App Store
- Receipt Fields
obtain a shared secret
shared secret is used to validate receipts with
add subscription in IC
Select the in-app purchase you want to create.
Create Auto-Renewable Subscription
No Ads Monthly
<bundle_id>is the value of
PRODUCT_BUNDLE_IDENTIFIERproperty in project.pbxproj -
com.iceperk.iceperkappfor our application.
product ID must be unique - even after deleting subscription its product ID cannot be reused for new subscriptions.
Create Subscription Group
Create New Subscription Group
Subscription Group Reference Name(input):
must be more general than subscription reference name.
Cleared for Sale
Subscription Prices(section) →
RUB - Russian Ruble
Subscription Display Name(input):
Скрытие рекламы на месяц
Полное отключение рекламы в приложении(not required)
Leave the state of your product as Missing Metadata.
Upload a a screenshot of your in-app purchase product once you are done testing it and ready to upload it for review.
configure subscription group
it’s required to add localization for subscription group as well:
Before you can submit your in-app purchase for review, you must add at least one localization to your subscription group.
Subscription Group Display Name(input):
App Name Display Name: [x] Use App Name
test subscription on real device
it’s required to run application on real device to make purchases: the only action allowed from inside emulator is loading products.
- have shortened periods (say, 1 month → 5 minutes)
- renew 5 times only (cancelled automatically afterwards)
- cannot be managed (say, cancelled manually)
test subscriptions are not created separately - they are real subscriptions but with special characteristics and behaviour for sandbox testers.
the sandbox environment handles auto-renewing subscriptions in an automated fashion - that is subscription periods are shortened and renew only 5 times and not controlled through the subscription management screen.
add sandbox testers (sandbox tester accounts)
NOTE: it’s not required to use sandbox testers to check subscription status (skip this section if all you want is to check subscription status).
tips and notes regarding sandbox tester:
new sandbox tester shouldn’t have an existing Apple ID
That email address is already associated with an existing Apple IDerror when I tried to add myself as a sandbox tester - Apple ID is created for each new sandox tester right after it’s added here.
sign out of Apple ID on iPhone before testing subscription
it’s also important not to sign in as a sandbox tester in
Settingsbut in application only (when prompted before making a purchase) - a sandbox tester account is not a fully functional one and tester’s Apple ID cannot be used to access iTunes Store or the App Store.
Apple ID Verificationalert dialog might appear asking to enter password for sandbox tester account in
Settings- it’s safe to ignore it and press
Not Nowbutton all the time.
about verification of sandbox tester email
generally speaking it’s necessary to verify new sandbox tester account by following the link sent to specified email:
You must validate your e-mail, or any purchases you make will silently fail.
but I couldn’t verify account of a new sandbox tester - after clicking the link email verification page kept on loading forever with an activity indicator in the middle of the screen and JS errors in Chrome Console:
bundle.js:46270 Refused to create a worker from 'blob:https://id.apple.com/...' because it violates the following Content Security Policy directive...
IDK if it matters or not but I signed in to iCloud with this account (in browser) and completed registration by adding 3 secret questions.
in the end I could make a purchase using not verified sandbox tester account.
I have successfully verified email of another sandbox tester - most likely it was temporary technical problem on Apple side.
set environment in application
sandbox tester can purchase a test subscription in
production environment but
subscription status cannot be checked since sandbox receipt cannot be validated
production environment (see
troubleshooting section for details):
- test subscriptions can be purchased in both
subscription status can be checked in
make sure checking subscription status is not disabled for
DaemonHelpers.updateSubscriptionStatus()in my case).
NOTE: there were lots of
Network request failed errors when purchasing a test
subscription => keep on trying.
run application on real device
- React Native - Running on Real Device
run application in Xcode (in debug or release mode):
App installation failed. An unknown error has occurred.
where when Xcode modal window trying to run application on real device
- close Xcode
- unplug device
- uninstall application from device
- open Xcode
- clean build in Xcode
- run application on device again
where when Log.error checking subscription status
no receipt is found:
there is no signed in Apple ID
Sign-In Requiredmodal window or sign in manually in iPhone’s
current Apple ID has never made a purchase in this application
process this error in application so that user is considered to be unsubscribed.
Sandbox receipt sent to Production environment
where when Log.error checking subscription status
current environment is
productionand it’s passed to
iap-receipt-validatorpackage when trying to validate receipt of sandbox tester.
=> switch to
developmentenvironment or send
iapReceiptValidatorfunction regardless of current environment.
checking subscription status always fails in production release
this is exactly the error above - you cannot validate receipt of sandbox tester in
and this is why Apple reviewer couldn’t test subscription:
- he signs in as sandbox tester on his iPhone
- he uses production release - so it’s a
- by default subscription status is
true(before any checks)
- checking subscription status always fails for sandbox tester in production release
- subscription status remains to be
- reviewer doesn’t see subscribe button and decides that subscription functionality is not implemented
- binary is rejected in IC :(
solution? I guess production releases shouldn’t be tested by sandbox testers at all since we can’t tell sandbox tester from real user inside our application - it’s not our application user but currently signed in Apple ID on iPhone itself. so we always have to assume
productionenvironment when validating receipt in production release.
one thing we can do here is to change behaviour of our application and set default subscription status to
falseso that subscribe button is shown by default - all subsequent subscription status checks will fail so the button will always be shown until sandbox tester makes a purchase.
after making a purchase subscription status should change to
truethough since this is done inside operation to purchase a subscription - not within operation to check subscription status which keeps on failing forever. and it’s all okay until the user decides to restart application - subscription status is then reset to its default value
false(which is incorrect) but this value won’t change because of failing checks.
When validating receipts on your server, your server needs to be able to handle a production-signed app getting its receipts from Apple’s test environment. The recommended approach is for your production server to always validate receipts against the production App Store first. If validation fails with the error code “Sandbox receipt used in production”, validate against the test environment instead.
beta testers (or just testers) are IC users who are invited to test TestFlight builds - that is they must have been already added before. just like sandbox testers they:
- deal with test subscriptions only (shortened periods, etc.)
- are not charged when making IAP
NOTE: beta testers can’t buy subscription even if it’s approved in IC.
install application from TestFlight
when beta tester is making a purchase, all Apple dialogs no longer have the line
[Environment: Sandbox] (like for sandbox testers).
publish release with subscription
fill review information
Screenshot: screenshot of your app with subscription popup
Review Notes: details on how you work with subscription in your app
notes might also include details about how you’re going to monetize your application and some implementation details (the more the better I guess).
after you fill review information, subscription status is automatically changed
Missing Metadata to
Ready to Submit.
create new app version
Store Version Number: new version number (say,
new app version has
Prepare for Submission status now.
add IAP to new app version
In-App Purchases page:
Your first in-app purchase must be submitted with a new app version. Select it from the app’s In-App Purchases section and click Submit.
Once your binary has been uploaded and your first in-app purchase has been submitted for review, additional in-app purchases can be submitted using the table below.
In-App Purchases section is available only if you’ve created IAP before.
select IAP (your subscription) in popup window
Select in-app purchases for us to review with this app version. The in-app purchases shown below are the only ones in the Ready to Submit state.
Done(button to select IAP and close popup window)
Save(button to save changes to app version)
release new app version
iTunes Store email received after releasing new app version:
It can take up to 24 hours before your app is available on the App Store. This delay is dependent on any app availability issues
in fact it took about 30 minutes for new app version to appear in the App Store.
Your app is using the Advertising Identifier (IDFA)
when trying to submit a binary:
Your app is using the Advertising Identifier (IDFA). You must either provide details about the IDFA usage or remove it from the app and submit your binary again.
The Mobile Ads SDK for iOS utilizes Apple’s advertising identifier (IDFA).
3.14 Prepare for Submission(left menu) →
Submit for Review(button)
Does this app use the Advertising Identifier (IDFA)?: [x]
This app uses the Advertising Identifier to (select all that apply):
Serve advertisements within the app
Attribute this app installation to a previously served advertisement
Attribute an action taken within this app to a previously served advertisement
I, <MY_NAME>, confirm that this app...
binary rejected (release didn’t pass a review because of IAP)
App Store Versions(left menu) →
2. 1 Performance: App Completeness
3. 1.2 Business:
Payments - Subscriptions
Guideline 2.1 - Performance - App Completeness
We found that while you have submitted in-app purchase products for your app, the in-app purchase functionality is not present in your binary.
If you would like to include in-app purchases in your app, you will need to upload a new binary that incorporates the in-app purchase API to enable users to make a purchase.
Once you revise and resubmit your binary, you will also need to resubmit your in-app purchases for review since they are in the Developer Action Required state. For each in-app purchase product submitted, please be sure to edit the detail information or cancel the request to change the detail information for the in-app purchases using iTunes Connect.
Guideline 3.1.2 - Business - Payments - Subscriptions
We noticed that your app or its metadata did not fully meet the terms and conditions for auto-renewing subscriptions, as specified in Schedule 2, section 3.8(b) of the Paid Applications agreement.
Your app’s binary did not include:
- The following information about the auto-renewable nature of the subscription
- Title of publication or service
- Length of subscription (time period and content or services provided during each subscription period)
- Price of subscription, and price per unit if appropriate
- Payment will be charged to iTunes Account at confirmation of purchase
- Subscription automatically renews unless auto-renew is turned off at least 24-hours before the end of the current period
- Account will be charged for renewal within 24-hours prior to the end of the current period, and identify the cost of the renewal
- Subscriptions may be managed by the user and auto-renewal may be turned off by going to the user's Account Settings after purchase
- Any unused portion of a free trial period, if offered, will be forfeited when the user purchases a subscription to that publication, where applicable
Note: Adding the above information to the StoreKit modal alert is not sufficient; the information must also be displayed within the app itself, and it must be displayed clearly and conspicuously during the purchase flow without requiring additional action from the user, such as opening a link.
Your app’s metadata did not include:
- The following information about the auto-renewable nature of the subscription (same subitems as for app's binary)
To resolve this issue, please revise your app or its metadata to include the missing information.
If the above information is in your app, please reply to this message in Resolution Center to provide details on where to locate it.
what we made to resolve these issues:
1 Performance: App Completeness
I fixed an issue when sandbox tester receipt couldn’t be validated in production environment - as a result subscription status checks didn’t work and subscription remained active forever (it’s active by default) effectively hiding subscription functionality (subscribe button).
also I processed the situation when user had never made IAP before and thus had no receipt at all -
not_availableerror in this case and you should return subscription status
falseinstead of raising error (the latter wouldn’t change subscription status and user would remain subscribed).
1.2 Business: Payments - Subscriptions
we added this information to both subscription page in application and application description in IC:
- subscription title
- subscription length
- subscription price
- information about auto-renewable nature of subscription
it’s pretty standard and can be safely copied from description of any application in the App Store that provides subscriptions.
in addition I edited review notes for our IAP to reflect new changes.
after making all required changes it’s necessary:
make sure IAP status is changed from
Developer Action Neededto
Waiting for Review
In-App Purchases(left menu) →
find the section that has a red circle mark - it’s necessary to update information there. in my case it was
Localizationssection and I had a red circle next to
if you’re not going to change anything and just want to re-submit IAP, edit rejected section (say, localized russian description in my case), save IAP, revert the changes and save again => red circle turns into a yellow one and IAP status becomes
Waiting for Review.
upload new build, select it in current application version and submit the latter for review
after that you can submit application version for review again.
- The following information about the auto-renewable nature of the subscription
In-App Purchasessection is gone in application version
I found this out after submitting application for review (previous binary was rejected and IAP status was
Developer Action Needed).
after that we decided that IAP status was the reason why IAP section was missing in application version and that IAP wouldn’t be included in a new release at all.
thus we removed current application version from review and updated IAP status (see notes above) but IAP section still didn’t appear so we had to submit application version for review just like before - without any mentions of IAP in application version.
Apple has approved of our release eventually (it took 3 days for them to review our release):
- iOS App status is changed to
Pending Developer Release(we checked
Manually release this versionoption)
- IAP status is changed to
- iOS App status is changed to
view financial reports