How to detect an expired subscription on the different app stores

Purchasely Platform Subscription Google Play Apple App Store Tech Backend Development

Managing subscribers lifecycle comprehensively is essential. You don't want to let subscribers out because you didn't activate their purchases and you don't want to let people enjoy it when they shouldn't.

In this article we will be discussing that last case and you will see that it is much more complicated than what you probably expect especially as Apple introduced new APIs.


What causes subscriptions expirations?

There are many events that lead to a subscription expiration. They all need to be handled by your subscription stack:

  • Renewal canceled by your customer
    This is the most common case, your customers goes to its settings and choses not to renew for the next period. At the end of the period, the subscription naturally expires.

  • Pause
    Some stores like the Google Play Store offer the possibility to pause a subscription. In that case you need to suspend the access to the features or content of your subscription.

  • Billing issues
    If the store cannot proceed with the payment (expired card, insufficient funds…) your user will churn. You can get him (and you) an extra chance by allowing a grace period and avoid having to convert him again. At the end of the billing period he will expire and you need to revoke the access.

  • Refund
    Every customer can ask the stores for a refund. Apple even introduced an API to ease that process. Customers need to justify it with the customer care and it can be unintentional but eventually they will get refunded and you don't want them to continue enjoying your content.

  • Price increase that was refused 
    As an app editor you can change the prices of a subscription (be really careful with that). This will send a price increase consent message to current subscribers. If they refuse they will churn (once again be really careful if you consider doing this).

  • Removal from a family sharing
    If you are in a family group and one of the family member purchases a family shareable In-App Subscription you will be able to use it as a regular subscriber. If you are removed from the family group (or any of the previous case apply to the owner) your subscription will be revoked.

Save developers’ valuable time and expertise with a two-step integration and just four lines of code and let them focus on product development instead of marketing support or installing updates.

Book a demo

Manage expirations with Purchasely

Nothing is easier than Purchasely: we send you a SUBSCRIPTION_EXPIRED Webhook containing the concerned user and plan, and you'll just have to remove the access. More info here.

Manage expirations with the Apple App Store

At the WWDC21, Apple has announced new server-to-server notifications (S2S) to help developers. Depending on the version you are supporting, the amount of development will be more or less important.

At the time of writing this article, Apple hasn't released these new notifications yet.


With the old S2S (pre-2021)


If you're not using the 2021-version of the S2S, it means you won't have direct S2S to know when a subscription expires and you'll have to work your way around. Here is what you'll have to do:

  • for anticipated cancellations (refund, upgrade), Apple sends specific S2S:
    • 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.
    • DID_FAIL_TO_RENEW: indicates a subscription that failed to renew due to a billing issue. It doesn't mean you should remove access to the user though (cf. previous explanation on grace period)
    • REFUND: Indicates that App Store successfully refunded a transaction.
    • REVOKE: Indicates that an in-app purchase the user was entitled to through Family Sharing is no longer available through sharing. StoreKit sends this notification when a purchaser disabled Family Sharing for a product, the purchaser (or family member) left the family group, or the purchaser asked for and received a refund.

  • for normal subscription cancellations, there is no S2S. You'll have to use the /verifyReceipt API (cf. "By Calling Apple servers" section)

All the S2S are listed in the Apple documentation.


With the new S2S v2 (2021)


One of the new S2S notification that was introduced is EXPIRED. It will have different substates to know the expiration's cause: VOLUNTARYBILLING_RETRY and PRICE_INCREASE.

So, whenever you receive this S2S, you know you can revoke the accesses to your user.


By calling Apple servers


If you want to manually pull a subscription status, you can request the /verifyReceipt API (or the new Subscription Status API).

For the new Subscription Status API, request it and check for the expiresDate / revocationDate / gracePeriodExpiresDate to determine the current status of your subscription.

You should revoke the subscription when:

  • revocationDate is defined
  • gracePeriodExpiresDate is in the past (more info on grace period here)
  • expiresDate is in the past AND gracePeriodExpiresDate is not defined


For the old /verifyReceipt API, you can check the equivalent properties to revoke a subscription:

  • cancellation_date is defined
  • grace_period_expires_date is in the past (more info on grace period here)
  • expired_date is in the past AND grace_period_expires_date is not defined


As you won't receive live notifications, you might have people enjoying their subscription longer than they should. For example, a refund can occurs 5 days after an initial purchase. Think about adapting the number of verifications and the frequency check instead of just checking at the expiration date. This is especially important for annual subscriptions!

Purchasely was developed specifically to empower App Editors to do business easily and efficiently.

Book a demo

Manage expirations with Google Play Store


With server-to-server


Google sends S2S when you have to revoke accesses to a user:


By calling Google servers


If you don't want to use the S2S, you can check a subscription's status by directly calling the Google Play developer API. It's not recommended though, since you could let free access to a user who asked for an early refund.




As you could see in this article, despite some efforts made by the stores it is still complicated to manage accesses and revoke them correctly.

If you miss one case you will let unauthorized customers enjoy your contents or services, and sometimes forever. The worst thing is that people love to explain how they could get that subscription for free to their friends and family and that this spreads.

Some recommendations (other than save time and troubles by using Purchasely 😂):

  • Unit-test your engine
  • Follow the store evolutions to be sure to support every new cases
  • Don't rely ONLY on the S2S notifications. They might not be sent or you might miss them because your servers aren't responding.
    You should pull-check the subscriptions regularly with the stores in case you missed a message.

Ready to increase your in-app revenue?