Unpredictable Sandbox Environment for IAP Auto-renewable Subscriptions

Denken
4 min readAug 5, 2019

2020/11/9 Update: slides with more latest info here ;)

#WWDC20
#WorldWideDevelopersConfused20

Good morning! Welcome to Unpredictable Sandbox Environment for IAP Auto-renewable Subscriptions. My name is Denken, and I’m a confused iOS app developer.

We’ll talk about a number of things today:

  • Sandbox Tester
  • Subscription Management
  • Billing Retry Service
  • App Store Server Notifications

Sandbox Tester

Do you really need to create a sandbox account to start testing? We’ve been pretty vague about this, and we’ll continue to do so. Because you already got it: No need.

Just use your Apple ID, if you have downloaded from TestFlight, or built from Xcode. During the purchasing process, it will show “Beta testers aren’t charged for this In-App purchase and it will only be available during testing.” or “[Environment: Sandbox]”, respectively.

You may ask, “What if I need multiple sandbox tester accounts?” Well, there are strict steps to create and use them. Follow Them Or You May Get Stuck:

  1. Go to App Store Connect — Users and Access — Sandbox — Testers to create new testers.

2. Go to iOS device — Settings — iTunes & App Store — Log out current account, and DO NOT log in sandbox tester account here!! (Ref)

3. Launch the app, purchase IAP with sandbox tester account.

“Important: Don’t use your test user account to sign in to the production environment. If you do, the test user account becomes invalid and can no longer be used.” from In-App Purchase Programming Guide — Retrieving Product Information — Suggested Testing Steps

Subscription Management

Let’s talk about subscription management in App Store, where users manage their subscriptions in one place. Do we have subscription management in sandbox environment? No, the App Store app doesn’t support it. There’s no way to manually cancel a subscription, and you can only upgrade or downgrade subscription inside your app. And it’s buggy, yeah. (Update: You can finally manage your subscription of sandbox account, in Settings on iOS 14 devices. Yay!)

But we do provide “maximum” 5 automatic renewals (WWDC 2018 — Session 704 Slides P.37) for you to test on! Notice the word “maximum” and what does that mean? Well, it usually starts with 5 renewals, and no renewal afterwards. We never tell you how long the cooldown time is. Probably hours.

Billing Retry Service

We’ve shown you how amazing our billing retry service is, without telling you any details about it because it is simply amazing. So what about testing billing retry in sandbox environment? We never talk about that.

Because it is even amazing that you may get receipt that is_in_billing_retry_period randomly for true from time to time, and get stuck there forever unless you purchase another new subscription. Surprise!

App Store Server Notifications

When you implement subscription, you understand there are two techniques: Status Polling and Server-to-Server Notification (Ref). Let’s talk about notification. Not the NSNotificationCenter, not the Apple Push Notification Service, it’s the Server-to-Server Notification. By the way, it was called Status Update Notifications on the official document, but still called Server-to-Server Notification elsewhere since the beginning, and lastly renamed as App Store Server Notifications since WWDC20.

We have extremely simple and elegant naming of those notifications. You may think CANCEL notification comes when users cancel their subscription, or RENEWAL notification comes when users renew their subscription. It is NOT. Read closely, and I append our official document and official explanation from the forum as below:

CANCEL

- Indicates that either Apple customer support canceled the subscription or the user upgraded their subscription. The cancellation_date key contains the date and time of the change.

- This event is not the same as when the user enters their iTunes account — Subscription section, and indicates that they choose not to allow an existing auto-renewing subscription to renew. There is no notification type for this event. I call this the “EXPIRE” event — there is no server-to-server notification when the user makes this choice. There is no support at present to simulate this event in the sandbox environment.

RENEWAL (Update: it’s been renamed as DID_RECOVER)

- Indicates a successful automatic renewal of an expired subscription that failed to renew in the past. Check expires_date to determine the next renewal date and time.

- In general, iTunes will attempt to charge the user account a day before an auto-renewing subscription is scheduled to expire. If the renewal is successful, there is no server-to server notification because the auto-renewing subscription did not enter into an expired state. However, in the few cases that iTunes is unable to renew the subscription (generally there was a connection problem with the credit card server) and the auto-renewing subscription is not renewed before the expiration_date passes, the auto-renewing subscription is technically considered “expired”. However, iTunes will still continue to attempt to renew the subscription. If iTunes is successful, then the “RENEWAL” event is sent. For this reason, the advice is presented — “Check Subscription Expiration Date to determine the next renewal date and time.” There is no support at present to simulate this event in the sandbox environment.

You may not have watched our legendary introduction of Server-to-Server Notification and understood why we did this mechanism.

Summary

Really need to implement IAP Auto-renewable Subscriptions? Think twice, or brace for impact!

And there’s one more thing: When exactly will original_transaction_id for a specific user ever change? We never tell you, either.

Thank you and have a great rest of your afternoon.

Disclaimer

It’s all based on our developing experience. All undocumented behaviors may change.

--

--