In the verifyReceipt API response, there is a "is_trial_period" field. As detailed in WWDC 2023 the verifyReceipt is deprecated, how to fetch the fact that the subscription is during the free trial period via recommended App Store server APIs?
How to identify free trial subscription transaction
Both the JWSRenewalInfoDecodedPayload and JWSTransactionDecodedPayload have an offerType field, which if it is set to 1 means the transaction/renewal will be an Introductory offer, and a free trial is a kind of introductory offer.
But, is there no way to distinguish between a free trial and a paid, reduced price introductory period for a subscription? The verifyReceipt API provided separate is_in_intro_offer_period and is_trial_period, which allowed our server to distinguish between these types of purchases, and now I see no way to do that without relying on some external information (such as maintaining a separate configuration on our server for what product_id correspond to either a free trial or intro price.
Is there any way to distinguish between a free trial and a non-free introductory price period with the App Store Server API?
We need this as well, any updates on this?
any updates?
A free trial will be indicated by JWSTransactionDecodedPayload.offerType == OfferType.INTRODUCTORY_OFFER and JWSTransactionDecodedPayload.price == 0
Correction: a more simple, reliable, or extra check would be JWSTransactionDecodedPayload.offerDiscountType == OfferDiscountType.FREE_TRIAL
In the JWS transaction payload (the one you get from Transaction.currentEntitlements client-side, or from Get Transaction Info server-side), there are two fields that together tell you unambiguously:
- offerType: an integer. 1 = introductory offer, 2 = promotional offer, 3 = offer code. Free trials are a form of introductory offer.
- offerDiscountType: a string enum. Values are FREE_TRIAL, PAY_AS_YOU_GO, or PAY_UP_FRONT. This is the one you probably actually want. If it equals FREE_TRIAL you're definitively in a trial.
Important caveat: these fields are only populated while the transaction is in the promotional or intro period. Once the trial converts to paid, the subsequent renewal transaction won't have offerType set at all. So you can only detect "currently in free trial" from the currently-active transaction, not by looking at historical renewal transactions.
If you need this server-side (not on device):
- Call the App Store Server API Get Transaction Info endpoint for the transactionId in question.
- Or parse the signedTransactionInfo JWS from your App Store Server Notifications webhook. The SUBSCRIBED notification with offerDiscountType = FREE_TRIAL on initial subscribe is your signal.
Strong recommendation: use the App Store Server Library (available for Swift, Java, Python, Node, Go). It handles JWS verification and decoding for you, rather than rolling your own JWT parse which is easy to get subtly wrong around certificate chain validation.
WWDC22 "Explore App Store server APIs" and WWDC23 "Meet StoreKit 2" both cover this.