There are many events that lead to a subscription expiration. They all need to be handled by your subscription stack:
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.
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.
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.
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:
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.All the S2S are listed in the Apple documentation.
One of the new S2S notification that was introduced is EXPIRED
. It will have different substates to know the expiration's cause: VOLUNTARY
, BILLING_RETRY
and PRICE_INCREASE
.
So, whenever you receive this S2S, you know you can revoke the accesses to your user.
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 definedgracePeriodExpiresDate
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 definedgrace_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.
Google sends S2S when you have to revoke accesses to a user:
SUBSCRIPTION_EXPIRED
: more info hereSUBSCRIPTION_REVOKED
: more info hereSUBSCRIPTION_PAUSED
: more info here
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 😂):