Apphud – Integrate, analyze and improve subscriptions in your iOS app

iOS subscription levels explained simply

Subscription levels and their configuration is the topic of this article. What are subscription levels, how to configure them and in which cases users get refund after changing their subscription.

What are subscription levels?

It’s a ranking system, where the higher subscription level offers more features and content. Subscriptions can be of the same level or different. In reality, very few apps offer more than one subscription level. In most cases apps with multiple subscription levels are content based apps, like NY Times newspaper app, which offers basic and premium subscriptions with different levels but belonging to the same subscription group.

Two subscriptions of different levels in "The New York Times" app
Two subscriptions of different levels in “The New York Times” app

How to set up subscription levels?

To set up subscription level go to your app in App Store Connect, then open your subscription group. There you will be able to rearrange subscriptions by dragging them up or down.

Changing subscription levels
Changing subscription levels

The most top subscription should offer the best service. You can have all subscriptions under the same level or different. Subscription duration doesn’t depend on the level. For example, you can have only one yearly subscription for the top level, and only monthly for the lower level.

Subscription levels changes

After purchasing a subscription a user can manage it in App Store settings. Users can upgrade, downgrade or cross-grade their subscription. Let’s take a closer look.

Subscription upgrade

If the current subscription is active, a user will be immediately switched to new subscription and receive a refund of the prorated amount of his previous subscription. You can see how to determine subscription upgrade and calculate prorated amount at the end of this article.

Subscription upgrade
Subscription upgrade

Subscription downgrade

When a user chooses subscription with lower level, the new subscription starts from the next renewal date with the new price and duration.

Subscription cross-grade

This is the most common situation. It has two cases: switch subscriptions having different duration and the same.

When switching subscription to a different duration the process will be the same as in downgrade. New subscription will be applied at the next renewal date.

However, when a user changes subscription with the same duration the process will be the same as in upgrade. New subscription will start immediately and user will receive a refund of the prorated amount of his previous subscription.

How to determine subscription change in your server?

To determine whether subscription was changed you should validate user’s App Store receipt or set up Apple server-to-server notifications.

You can check auto_renew_product_id field in pending_renewal_info to know which subscription will be renewed at the next renewal date. Another way is to check product_id in each transaction from latest_receipt_info array. If you have server-to-server notifications enabled, you should listen for DID_CHANGE_RENEWAL_PREF notification. It will contain new product_id in request parameters.

How to calculate refund amount?

To know whether subscription was upgraded, you should check for is_upgraded field in transaction JSON. If it’s true, then subscription was upgraded and the next transaction belongs to new subscription.

The field is_upgraded will be true also when cross-grading subscription of the same duration. In other words, is_upgraded = true is not actually an upgrade, but it’s changing subscription with a refund.

Besides is_upgraded field there will is also appear cancellation_date, which is the time user made an upgrade. It equals or almost equals the purchase date of new transaction.

So cancellation_date field appears not only upon subscription refund, but upon upgrade as well. Another thing is that cancellation_date doesn’t appear in Sandbox. While testing in Sandbox you should check purchase_date of new transaction instead of cancellation_date. More information is available here.

To calculate prorated amount of the refund, you should divide unused portion of subscription duration by the full duration:

# upgrade_date is `cancellation_date` in production or purchase_date of new transaction in sandbox
# to_f converts date to float timestamp value
prorate_amount = price * (upgrade_date.to_f - cancellation_date.to_f) / (expires_date.to_f - purchase_date.to_f)

How it works in Apphud?

Apphud automatically tracks all subscription changes, and calculates prorated amount of refund if applicable.

Example of subscription upgrade with partial refund


As it turned out, just updating the value of product_id is not enough. In case of subscription upgrade and cross-grade with same duration, you should calculate prorated amount of refund.

Working with subscriptions is hard. There are lots of situations you should take into consideration. We are building Apphud – a tool for developers that makes work with subscriptions easy. You can start using it today for free. Just follow this link.