Summary
iOS subscription levels and events like subscription upgrades and downgrades can cause a lot of confusion. This guide summarises everything you need to know on these subjects.
First, you need to understand the following two concepts used by Apple on the App Store Connect:
Subscription group
Service Level
![iOS Subscription upgrades](https://framerusercontent.com/images/q0ydnf29EyKr8Gq1HPkeEvulxM.jpg)
What is a subscription group?
What is a subscription service level?
In-app products unlock premium access on your app for your users. For example, in some well-known apps the product unlocks access to the following app service:
YouTube Premium
Netflix Standart, Netflix Premium
Duolingo Plus
You have to manage the logic of user access on your app on your own or let Qonversion Permissions handle that for you. But the App Store provides a subscription service level essentially to distinguish what level of premium access a user gets for each product. App Store needs to know a subscription service level for each product to understand how to handle a subscriber if he switches between the products. We’ll dive into that in a moment.
But first, let’s have a look at how to manage in-app product subscription levels on the App Store.
Navigate to Subscription Groups in your App Store Connect account. You can change the order of the in-app products and combine them by dragging and dropping. Have a look at the video below:
The number you see to the left of your products is a subscription level. So far we have shown that in-app products within the subscription group may have different service levels. After a user purchases any of the in-app products he can make an upgrade, downgrade, or cross-grade to a different product within this subscription group. A user can navigate to his subscription settings and see all of the available subscription options within the subscription group of his current subscription.
Subscription Upgrade
Subscription upgrade happens when a user choses a subscription with higher service level than his current subscription. For example, a user switches from standard (level 2) subscription to premium (level 1) subscription as shown on the picture below. A user is refunded for the remainder of his current subscription (remainder of the weekly subscription) in case of upgrade. And the new monthly subscription price is charged. The upgrade is applied immediately.
![](https://framerusercontent.com/images/cRYoEMEx58CbowgBRChO3REWLY.png)
Subscription levels
Another example of an upgrade (using Apple Music app) would be switching from Premium Apple Music to Family Premium:
![](https://framerusercontent.com/images/TayApoagetMuMOBc2kN9ClxoLA.png)
Subscription upgrade
How to handle subscription upgrade in a user receipt?
When a user upgrades a subscription, the following two fields appear in transaction responseBody.Latest_receipt_info in user receipt:
is_upgraded
field equalstrue
.cancellation_date
field contains the date of the original subscription cancellation and it’s also the date of the partial refund for the original subscription.
You must check that both of these fields are provided. cancellation_date
field alone appears in case of a full refund not connected to an upgrade.
"latest_receipt_info": [ { "quantity": "1", "product_id": "product.99.trial.3d", "transaction_id": "10000000306492965", "original_transaction_id": "10000000306492965", "purchase_date": "2020-01-10 04:13:34 Etc/GMT", "purchase_date_ms": "1578629614000", "purchase_date_pst": "2020-01-09 20:13:34 America/Los_Angeles", "original_purchase_date": "2020-01-10 04:13:34 Etc/GMT", "original_purchase_date_ms": "1578629614000", "original_purchase_date_pst": "2020-01-09 20:13:34 America/Los_Angeles", "expires_date": "2020-01-17 04:13:34 Etc/GMT", "expires_date_ms": "1579234414000", "expires_date_pst": "2020-01-16 20:13:34 America/Los_Angeles", "cancellation_date": "2020-01-19 08:27:22 Etc/GMT", "cancellation_date_ms": "1579422442000", "cancellation_date_pst": "2020-01-19 01:27:22 America/Los_Angeles", "web_order_line_item_id": "100000246215806", "is_trial_period": "false", "is_in_intro_offer_period": "false", "in_app_ownership_type": "PURCHASED", "subscription_group_identifier": "1000000", "is_upgraded": "true" } ]
Copy
If you want to calculate the prorated refund value you have to divide the unused period of the subscription by the subscription duration and multiply it by subscription price. You can calculate the unused period as the time between the cancellation_date described above and the original subscription expiration date:
transaction_value / (expires_date_ms - purchase_date_ms) * (expires_date_ms - cancellation_date_ms)
Copy
where transaction_value
is the subscription price.
Subscription Downgrade
Downgrade happens when a user switches to a lower service level subscription from a higher service level subscription. The change is applied at the end of his current subscription period. The original subscription lapses at the time of his next subscription renewal, and the new lower service level subscription starts.
How to detect subscription downgrade in a user receipt?
You have to check the auto_renew_product_id
field in responseBody.Pending_renewal_info
The value of this field must be different from product_id
:
"pending_renewal_info": [ { "auto_renew_product_id": "product.99.trial.3d", "original_transaction_id": "10000000306492965", "product_id": "product.49", "auto_renew_status": "1" } ]
Copy
You can also use Apple’s server-to-server notifications to detect any planned subscription changes. This information is contained in the notification of type DID_CHANGE_RENEWAL_PREF
. You can check our article on handling Apple server-to-server notification for more details.
Subscription Cross-grades
Cross-grade happens when a user switches between in-app subscriptions with the same service level. Cross-grade can have different behavior depending on the durations of the subscriptions.
Same duration cross-grade
Cross-grade between subscriptions with the same duration is handled exactly the same as an upgrade.
Different duration cross-grade
Cross-grade between subscriptions with different durations is handled similar to downgrade. The original subscription is active until the next renewal date when a new subscription starts.
Handling in-app subscription events is time-consuming. You have to build a complex back-end logic on top of the server-side receipt validation. The good thing is that you can hand it over to Qonversion. Qonversion provides
an out-of-the-box server to validate user receipts
in-app subscription analytics
integrations to send accurate subscription data where you need it
It requires just a few lines of code to set everything up in your app.
iOS subscription levels and events like subscription upgrades and downgrades can cause a lot of confusion. This guide summarises everything you need to know on these subjects.
First, you need to understand the following two concepts used by Apple on the App Store Connect:
Subscription group
Service Level
![iOS Subscription upgrades](https://framerusercontent.com/images/q0ydnf29EyKr8Gq1HPkeEvulxM.jpg)
What is a subscription group?
What is a subscription service level?
In-app products unlock premium access on your app for your users. For example, in some well-known apps the product unlocks access to the following app service:
YouTube Premium
Netflix Standart, Netflix Premium
Duolingo Plus
You have to manage the logic of user access on your app on your own or let Qonversion Permissions handle that for you. But the App Store provides a subscription service level essentially to distinguish what level of premium access a user gets for each product. App Store needs to know a subscription service level for each product to understand how to handle a subscriber if he switches between the products. We’ll dive into that in a moment.
But first, let’s have a look at how to manage in-app product subscription levels on the App Store.
Navigate to Subscription Groups in your App Store Connect account. You can change the order of the in-app products and combine them by dragging and dropping. Have a look at the video below:
The number you see to the left of your products is a subscription level. So far we have shown that in-app products within the subscription group may have different service levels. After a user purchases any of the in-app products he can make an upgrade, downgrade, or cross-grade to a different product within this subscription group. A user can navigate to his subscription settings and see all of the available subscription options within the subscription group of his current subscription.
Subscription Upgrade
Subscription upgrade happens when a user choses a subscription with higher service level than his current subscription. For example, a user switches from standard (level 2) subscription to premium (level 1) subscription as shown on the picture below. A user is refunded for the remainder of his current subscription (remainder of the weekly subscription) in case of upgrade. And the new monthly subscription price is charged. The upgrade is applied immediately.
![](https://framerusercontent.com/images/cRYoEMEx58CbowgBRChO3REWLY.png)
Subscription levels
Another example of an upgrade (using Apple Music app) would be switching from Premium Apple Music to Family Premium:
![](https://framerusercontent.com/images/TayApoagetMuMOBc2kN9ClxoLA.png)
Subscription upgrade
How to handle subscription upgrade in a user receipt?
When a user upgrades a subscription, the following two fields appear in transaction responseBody.Latest_receipt_info in user receipt:
is_upgraded
field equalstrue
.cancellation_date
field contains the date of the original subscription cancellation and it’s also the date of the partial refund for the original subscription.
You must check that both of these fields are provided. cancellation_date
field alone appears in case of a full refund not connected to an upgrade.
"latest_receipt_info": [ { "quantity": "1", "product_id": "product.99.trial.3d", "transaction_id": "10000000306492965", "original_transaction_id": "10000000306492965", "purchase_date": "2020-01-10 04:13:34 Etc/GMT", "purchase_date_ms": "1578629614000", "purchase_date_pst": "2020-01-09 20:13:34 America/Los_Angeles", "original_purchase_date": "2020-01-10 04:13:34 Etc/GMT", "original_purchase_date_ms": "1578629614000", "original_purchase_date_pst": "2020-01-09 20:13:34 America/Los_Angeles", "expires_date": "2020-01-17 04:13:34 Etc/GMT", "expires_date_ms": "1579234414000", "expires_date_pst": "2020-01-16 20:13:34 America/Los_Angeles", "cancellation_date": "2020-01-19 08:27:22 Etc/GMT", "cancellation_date_ms": "1579422442000", "cancellation_date_pst": "2020-01-19 01:27:22 America/Los_Angeles", "web_order_line_item_id": "100000246215806", "is_trial_period": "false", "is_in_intro_offer_period": "false", "in_app_ownership_type": "PURCHASED", "subscription_group_identifier": "1000000", "is_upgraded": "true" } ]
Copy
If you want to calculate the prorated refund value you have to divide the unused period of the subscription by the subscription duration and multiply it by subscription price. You can calculate the unused period as the time between the cancellation_date described above and the original subscription expiration date:
transaction_value / (expires_date_ms - purchase_date_ms) * (expires_date_ms - cancellation_date_ms)
Copy
where transaction_value
is the subscription price.
Subscription Downgrade
Downgrade happens when a user switches to a lower service level subscription from a higher service level subscription. The change is applied at the end of his current subscription period. The original subscription lapses at the time of his next subscription renewal, and the new lower service level subscription starts.
How to detect subscription downgrade in a user receipt?
You have to check the auto_renew_product_id
field in responseBody.Pending_renewal_info
The value of this field must be different from product_id
:
"pending_renewal_info": [ { "auto_renew_product_id": "product.99.trial.3d", "original_transaction_id": "10000000306492965", "product_id": "product.49", "auto_renew_status": "1" } ]
Copy
You can also use Apple’s server-to-server notifications to detect any planned subscription changes. This information is contained in the notification of type DID_CHANGE_RENEWAL_PREF
. You can check our article on handling Apple server-to-server notification for more details.
Subscription Cross-grades
Cross-grade happens when a user switches between in-app subscriptions with the same service level. Cross-grade can have different behavior depending on the durations of the subscriptions.
Same duration cross-grade
Cross-grade between subscriptions with the same duration is handled exactly the same as an upgrade.
Different duration cross-grade
Cross-grade between subscriptions with different durations is handled similar to downgrade. The original subscription is active until the next renewal date when a new subscription starts.
Handling in-app subscription events is time-consuming. You have to build a complex back-end logic on top of the server-side receipt validation. The good thing is that you can hand it over to Qonversion. Qonversion provides
an out-of-the-box server to validate user receipts
in-app subscription analytics
integrations to send accurate subscription data where you need it
It requires just a few lines of code to set everything up in your app.
iOS subscription levels and events like subscription upgrades and downgrades can cause a lot of confusion. This guide summarises everything you need to know on these subjects.
First, you need to understand the following two concepts used by Apple on the App Store Connect:
Subscription group
Service Level
![iOS Subscription upgrades](https://framerusercontent.com/images/q0ydnf29EyKr8Gq1HPkeEvulxM.jpg)
What is a subscription group?
What is a subscription service level?
In-app products unlock premium access on your app for your users. For example, in some well-known apps the product unlocks access to the following app service:
YouTube Premium
Netflix Standart, Netflix Premium
Duolingo Plus
You have to manage the logic of user access on your app on your own or let Qonversion Permissions handle that for you. But the App Store provides a subscription service level essentially to distinguish what level of premium access a user gets for each product. App Store needs to know a subscription service level for each product to understand how to handle a subscriber if he switches between the products. We’ll dive into that in a moment.
But first, let’s have a look at how to manage in-app product subscription levels on the App Store.
Navigate to Subscription Groups in your App Store Connect account. You can change the order of the in-app products and combine them by dragging and dropping. Have a look at the video below:
The number you see to the left of your products is a subscription level. So far we have shown that in-app products within the subscription group may have different service levels. After a user purchases any of the in-app products he can make an upgrade, downgrade, or cross-grade to a different product within this subscription group. A user can navigate to his subscription settings and see all of the available subscription options within the subscription group of his current subscription.
Subscription Upgrade
Subscription upgrade happens when a user choses a subscription with higher service level than his current subscription. For example, a user switches from standard (level 2) subscription to premium (level 1) subscription as shown on the picture below. A user is refunded for the remainder of his current subscription (remainder of the weekly subscription) in case of upgrade. And the new monthly subscription price is charged. The upgrade is applied immediately.
![](https://framerusercontent.com/images/cRYoEMEx58CbowgBRChO3REWLY.png)
Subscription levels
Another example of an upgrade (using Apple Music app) would be switching from Premium Apple Music to Family Premium:
![](https://framerusercontent.com/images/TayApoagetMuMOBc2kN9ClxoLA.png)
Subscription upgrade
How to handle subscription upgrade in a user receipt?
When a user upgrades a subscription, the following two fields appear in transaction responseBody.Latest_receipt_info in user receipt:
is_upgraded
field equalstrue
.cancellation_date
field contains the date of the original subscription cancellation and it’s also the date of the partial refund for the original subscription.
You must check that both of these fields are provided. cancellation_date
field alone appears in case of a full refund not connected to an upgrade.
"latest_receipt_info": [ { "quantity": "1", "product_id": "product.99.trial.3d", "transaction_id": "10000000306492965", "original_transaction_id": "10000000306492965", "purchase_date": "2020-01-10 04:13:34 Etc/GMT", "purchase_date_ms": "1578629614000", "purchase_date_pst": "2020-01-09 20:13:34 America/Los_Angeles", "original_purchase_date": "2020-01-10 04:13:34 Etc/GMT", "original_purchase_date_ms": "1578629614000", "original_purchase_date_pst": "2020-01-09 20:13:34 America/Los_Angeles", "expires_date": "2020-01-17 04:13:34 Etc/GMT", "expires_date_ms": "1579234414000", "expires_date_pst": "2020-01-16 20:13:34 America/Los_Angeles", "cancellation_date": "2020-01-19 08:27:22 Etc/GMT", "cancellation_date_ms": "1579422442000", "cancellation_date_pst": "2020-01-19 01:27:22 America/Los_Angeles", "web_order_line_item_id": "100000246215806", "is_trial_period": "false", "is_in_intro_offer_period": "false", "in_app_ownership_type": "PURCHASED", "subscription_group_identifier": "1000000", "is_upgraded": "true" } ]
Copy
If you want to calculate the prorated refund value you have to divide the unused period of the subscription by the subscription duration and multiply it by subscription price. You can calculate the unused period as the time between the cancellation_date described above and the original subscription expiration date:
transaction_value / (expires_date_ms - purchase_date_ms) * (expires_date_ms - cancellation_date_ms)
Copy
where transaction_value
is the subscription price.
Subscription Downgrade
Downgrade happens when a user switches to a lower service level subscription from a higher service level subscription. The change is applied at the end of his current subscription period. The original subscription lapses at the time of his next subscription renewal, and the new lower service level subscription starts.
How to detect subscription downgrade in a user receipt?
You have to check the auto_renew_product_id
field in responseBody.Pending_renewal_info
The value of this field must be different from product_id
:
"pending_renewal_info": [ { "auto_renew_product_id": "product.99.trial.3d", "original_transaction_id": "10000000306492965", "product_id": "product.49", "auto_renew_status": "1" } ]
Copy
You can also use Apple’s server-to-server notifications to detect any planned subscription changes. This information is contained in the notification of type DID_CHANGE_RENEWAL_PREF
. You can check our article on handling Apple server-to-server notification for more details.
Subscription Cross-grades
Cross-grade happens when a user switches between in-app subscriptions with the same service level. Cross-grade can have different behavior depending on the durations of the subscriptions.
Same duration cross-grade
Cross-grade between subscriptions with the same duration is handled exactly the same as an upgrade.
Different duration cross-grade
Cross-grade between subscriptions with different durations is handled similar to downgrade. The original subscription is active until the next renewal date when a new subscription starts.
Handling in-app subscription events is time-consuming. You have to build a complex back-end logic on top of the server-side receipt validation. The good thing is that you can hand it over to Qonversion. Qonversion provides
an out-of-the-box server to validate user receipts
in-app subscription analytics
integrations to send accurate subscription data where you need it
It requires just a few lines of code to set everything up in your app.
iOS subscription levels and events like subscription upgrades and downgrades can cause a lot of confusion. This guide summarises everything you need to know on these subjects.
First, you need to understand the following two concepts used by Apple on the App Store Connect:
Subscription group
Service Level
![iOS Subscription upgrades](https://framerusercontent.com/images/q0ydnf29EyKr8Gq1HPkeEvulxM.jpg)
What is a subscription group?
What is a subscription service level?
In-app products unlock premium access on your app for your users. For example, in some well-known apps the product unlocks access to the following app service:
YouTube Premium
Netflix Standart, Netflix Premium
Duolingo Plus
You have to manage the logic of user access on your app on your own or let Qonversion Permissions handle that for you. But the App Store provides a subscription service level essentially to distinguish what level of premium access a user gets for each product. App Store needs to know a subscription service level for each product to understand how to handle a subscriber if he switches between the products. We’ll dive into that in a moment.
But first, let’s have a look at how to manage in-app product subscription levels on the App Store.
Navigate to Subscription Groups in your App Store Connect account. You can change the order of the in-app products and combine them by dragging and dropping. Have a look at the video below:
The number you see to the left of your products is a subscription level. So far we have shown that in-app products within the subscription group may have different service levels. After a user purchases any of the in-app products he can make an upgrade, downgrade, or cross-grade to a different product within this subscription group. A user can navigate to his subscription settings and see all of the available subscription options within the subscription group of his current subscription.
Subscription Upgrade
Subscription upgrade happens when a user choses a subscription with higher service level than his current subscription. For example, a user switches from standard (level 2) subscription to premium (level 1) subscription as shown on the picture below. A user is refunded for the remainder of his current subscription (remainder of the weekly subscription) in case of upgrade. And the new monthly subscription price is charged. The upgrade is applied immediately.
![](https://framerusercontent.com/images/cRYoEMEx58CbowgBRChO3REWLY.png)
Subscription levels
Another example of an upgrade (using Apple Music app) would be switching from Premium Apple Music to Family Premium:
![](https://framerusercontent.com/images/TayApoagetMuMOBc2kN9ClxoLA.png)
Subscription upgrade
How to handle subscription upgrade in a user receipt?
When a user upgrades a subscription, the following two fields appear in transaction responseBody.Latest_receipt_info in user receipt:
is_upgraded
field equalstrue
.cancellation_date
field contains the date of the original subscription cancellation and it’s also the date of the partial refund for the original subscription.
You must check that both of these fields are provided. cancellation_date
field alone appears in case of a full refund not connected to an upgrade.
"latest_receipt_info": [ { "quantity": "1", "product_id": "product.99.trial.3d", "transaction_id": "10000000306492965", "original_transaction_id": "10000000306492965", "purchase_date": "2020-01-10 04:13:34 Etc/GMT", "purchase_date_ms": "1578629614000", "purchase_date_pst": "2020-01-09 20:13:34 America/Los_Angeles", "original_purchase_date": "2020-01-10 04:13:34 Etc/GMT", "original_purchase_date_ms": "1578629614000", "original_purchase_date_pst": "2020-01-09 20:13:34 America/Los_Angeles", "expires_date": "2020-01-17 04:13:34 Etc/GMT", "expires_date_ms": "1579234414000", "expires_date_pst": "2020-01-16 20:13:34 America/Los_Angeles", "cancellation_date": "2020-01-19 08:27:22 Etc/GMT", "cancellation_date_ms": "1579422442000", "cancellation_date_pst": "2020-01-19 01:27:22 America/Los_Angeles", "web_order_line_item_id": "100000246215806", "is_trial_period": "false", "is_in_intro_offer_period": "false", "in_app_ownership_type": "PURCHASED", "subscription_group_identifier": "1000000", "is_upgraded": "true" } ]
Copy
If you want to calculate the prorated refund value you have to divide the unused period of the subscription by the subscription duration and multiply it by subscription price. You can calculate the unused period as the time between the cancellation_date described above and the original subscription expiration date:
transaction_value / (expires_date_ms - purchase_date_ms) * (expires_date_ms - cancellation_date_ms)
Copy
where transaction_value
is the subscription price.
Subscription Downgrade
Downgrade happens when a user switches to a lower service level subscription from a higher service level subscription. The change is applied at the end of his current subscription period. The original subscription lapses at the time of his next subscription renewal, and the new lower service level subscription starts.
How to detect subscription downgrade in a user receipt?
You have to check the auto_renew_product_id
field in responseBody.Pending_renewal_info
The value of this field must be different from product_id
:
"pending_renewal_info": [ { "auto_renew_product_id": "product.99.trial.3d", "original_transaction_id": "10000000306492965", "product_id": "product.49", "auto_renew_status": "1" } ]
Copy
You can also use Apple’s server-to-server notifications to detect any planned subscription changes. This information is contained in the notification of type DID_CHANGE_RENEWAL_PREF
. You can check our article on handling Apple server-to-server notification for more details.
Subscription Cross-grades
Cross-grade happens when a user switches between in-app subscriptions with the same service level. Cross-grade can have different behavior depending on the durations of the subscriptions.
Same duration cross-grade
Cross-grade between subscriptions with the same duration is handled exactly the same as an upgrade.
Different duration cross-grade
Cross-grade between subscriptions with different durations is handled similar to downgrade. The original subscription is active until the next renewal date when a new subscription starts.
Handling in-app subscription events is time-consuming. You have to build a complex back-end logic on top of the server-side receipt validation. The good thing is that you can hand it over to Qonversion. Qonversion provides
an out-of-the-box server to validate user receipts
in-app subscription analytics
integrations to send accurate subscription data where you need it
It requires just a few lines of code to set everything up in your app.
Start Now for Free
Or book a demo with our team to learn more about Qonversion
Start Now for Free
Or book a demo with our team to learn more about Qonversion
Start Now for Free
Or book a demo with our team to learn more about Qonversion
Read more
Read more
![Trash Panda App partners with Qonversion](https://framerusercontent.com/images/fIjbGE1BlBzu0OZK7vCihIvo.webp)
Trash Panda Maximizes App Revenue after Setting the Best Subscription Price with A/B Tests
Jul 8, 2024
Jul 8, 2024
![StyleDNA with Qonversion](https://framerusercontent.com/images/0CYKPTzYfOn6vdokDrwSoFR4c.webp)
How StyleDNA Saved 20% Development Time and Unlocked New Features
Jun 19, 2024
Jun 19, 2024
![WWDC 24 updates](https://framerusercontent.com/images/OFmq7UmE6o7QKdnnbRBNKtgo.png)
WWDC24 Updates for App Developers | What's new in Storekit 2 and App Store Server API?
Jun 17, 2024
Jun 17, 2024
![Parenting by Iben Sandahl uses Qonversion](https://framerusercontent.com/images/qJ2twjlmMxXqQ2MggeZqrVbB580.webp)
How A/B Testing with Qonversion Helped Iben Sandahl’s Parenting App Double Their Sales
Jun 13, 2024
Jun 13, 2024
![Trash Panda App partners with Qonversion](https://framerusercontent.com/images/fIjbGE1BlBzu0OZK7vCihIvo.webp)
Trash Panda Maximizes App Revenue after Setting the Best Subscription Price with A/B Tests
Jul 8, 2024
Jul 8, 2024
![StyleDNA with Qonversion](https://framerusercontent.com/images/0CYKPTzYfOn6vdokDrwSoFR4c.webp)
How StyleDNA Saved 20% Development Time and Unlocked New Features
Jun 19, 2024
Jun 19, 2024
![WWDC 24 updates](https://framerusercontent.com/images/OFmq7UmE6o7QKdnnbRBNKtgo.png)
WWDC24 Updates for App Developers | What's new in Storekit 2 and App Store Server API?
Jun 17, 2024
Jun 17, 2024