StoreKit2 does not provide an update when subscription was cancelled

I am testing a situation when user cancels auto renewable subscription (via StoreKit->Manage Transactions window).

The problem is StoreKit2 does not provide an update when subscription was cancelled. I started using demo from apple

developer.apple.com/documentation/storekit/in-app_purchase/implementing_a_store_in_your_app_using_the_storekit_api

to test this behaviour in order to get rid of possible mistakes in my implementation, but result is the same - when user cancels subscription app does not receive any storekit events (change in renewal info, update in current entitlements, transaction status - nothing) and only after app's relaunch it fetches everything from scratch and finally updates UI.

I tried to wait for up to 20 minutes to check whether this update in transaction (subscription) status will be delivered to the app - still nothing.

So the problem, as I see it, is that if user cancels subscription and then does not relaunch the app he can continue to use the app for free for a long time.

In this regard I have several questions:

  1. is it expected behavior of StoreKit2? If yes - why?
  2. Does it happen in Test Flight mode or in production env as well?
  3. If it's not expected behavior then is it correct to fix it with checking (lets say once in an hour) user's current entitlements (I tried and it seems to work ok) or there are better solutions?
Answered by AnatoliyPodkladov in 887932022

Important points regarding transaction updates and subscription/purchase events:

  • Transaction.updates is primarily designed for new and updated transactions (purchases, successful renewals, refunds, revocations, purchases made on another device, etc.).
  • When a subscription simply expires (i.e., auto-renewal just didn't go through), Apple often doesn't generate a new transaction. As a result, a dedicated event in Transaction.updates may not arrive at all, or may come with a significant delay.
  • Many developers confirm this: relying solely on Transaction.updates to detect the moment a subscription expires is unreliable.

The best approach is to use a combination of:

  1. Transaction.updatesmandatory (for new transactions).
  2. Product.SubscriptionInfo.Status.updates — specifically for tracking subscription status changes (including .expired).
  3. Periodic / event-driven calls to refreshAll() — on app launch, when returning from the background, and when opening the paywall.

SubscriptionInfo.Status.updates is the closest thing to an "automatic event on expiration" available on the client side.

I'm using and getting the same error (no cancel event is received in the asynchronous sequence Transaction.updates, but subscription start/renewal events are received) at least in the sandbox environment. Is there any solution to this other than adding a timer and periodically querying the latest transactions (for example via Transaction.currentEntitlements) or using your own backend?

Important points regarding transaction updates and subscription/purchase events:

  • Transaction.updates is primarily designed for new and updated transactions (purchases, successful renewals, refunds, revocations, purchases made on another device, etc.).
  • When a subscription simply expires (i.e., auto-renewal just didn't go through), Apple often doesn't generate a new transaction. As a result, a dedicated event in Transaction.updates may not arrive at all, or may come with a significant delay.
  • Many developers confirm this: relying solely on Transaction.updates to detect the moment a subscription expires is unreliable.

The best approach is to use a combination of:

  1. Transaction.updatesmandatory (for new transactions).
  2. Product.SubscriptionInfo.Status.updates — specifically for tracking subscription status changes (including .expired).
  3. Periodic / event-driven calls to refreshAll() — on app launch, when returning from the background, and when opening the paywall.

SubscriptionInfo.Status.updates is the closest thing to an "automatic event on expiration" available on the client side.

StoreKit2 does not provide an update when subscription was cancelled
 
 
Q