iOS Subscription Offers
Implementing iOS Subscription Offers with Purchases SDK
This guide assumes you already have your iOS products set up in App Store Connect.
Subscription Offers allow developers to apply custom pricing and trials to new customers and to existing and lapsed subscriptions.
Subscription Offers are supported in the Purchases SDK, but require some additional setup first in App Store Connect and the RevenueCat dashboard.
Types of Subscription Offers
Offer Type | Applies To | Subscription Key Required | Notes | Auto-Renewal |
---|---|---|---|---|
Introductory Offers | New Users | Not required | Applied to eligible purchases automatically. How to check eligibility. | ✅ |
Promotional Offers | Existing and Lapsed Users | 🔑 Required | Not applied automatically, see implementation guide below | ✅ |
Offer Codes | New and Existing Users | 🔑 Required | Requires iOS SDK 3.8.0+, see implementation guide below | ✅ |
⚠️ Not recommended In-App Purchase Promo Codes | New and Existing Users | Not Required | Treated as a regular purchase, revenue will not be accurate in Charts and Integrations due to Apple/StoreKit limitations. Codes don't auto-renew, aren't compatible with presentCodeRedemptionSheet , restricted to non-commercial use, and restricted to 1,000 codes every 6 months. | ❌ |
In-App Purchase Keys
For RevenueCat to securely authenticate and validate a Subscription Offer request with Apple, you'll need to upload an In-App Purchase Key following our guide.
Introductory Offers
An In-App Purchase Key is not required for Introductory Offers, only for Promotional Offers and Offer Codes. The Purchases SDK will automatically apply an introductory offer to a purchase. Documentation for reference.
Promotional Offers
In iOS 12.2, Apple announced a new feature for subscription developers called “Promotional Offers.”
1. Configure the Offer in App Store Connect
Promotional Offers are created from within App Store Connect and are included as a pricing option to an existing subscription product. When you click the "+" option next to Subscription Prices, you'll see an option to Create Promotional Offer.
To create the offer there are two fields that you need to specify: Reference Name, which is just used for your reference, and the Promotional Offer Product Code, which is what you will actually use to activate a specific offer in your app.
On the next screen you'll select the type of offer you wish to provide. Just like introductory offers, there are three types of Promotional Offers:
- Pay-up-front — The customer pays once for a period of time, e.g. $0.99 for 3 months. Allowed durations are 1, 2, 3, 6 and 12 months.
- Pay-as-you-go — The customer pays a reduced rate, each period, for a number of periods, e.g. $0.99 per month for 3 months. Allowed durations are 1-12 months. Can only be specified in months.
- Free — This is analogous to a free trial, the user receives 1 of a specified period free. The allowed durations are 3 days, 1 week, 2 weeks, 1 month, 2 months, 3 months, 6 months, and 1 year.
Don't forget to click Save in the upper right after you configure the offer.
2. Show the Promotional Offer to Desired Users
It's up to you to decide which users you want to present a Promotional Offer to. The only eligibility requirements are that the user had (or currently has) an active subscription. Apple automatically enforces this requirement for you - if it's not met users will be shown the regular product regardless of the offer you try to present.
Fetch the PromoOffer
Before you can present a Promotional Offer to a user, you first need to fetch the PromoOffer
. This is done by passing the StoreProduct
and a StoreProductDiscount
to the .getPromotionalOffer
method, which uses the Subscription Key from above to validate the discount and to provide a valid PromoOffer
:
if let discount = package.storeProduct.discounts.first {
Purchases.shared.getPromotionalOffer(forProductDiscount: discount,
product: package.storeProduct) { (promoOffer, error) in
if let promoOffer {
// Promotional Offer validated, show terms of your offer to your customers
} else {
// Promotional Offer was not validated, default to normal package terms
}
}
}
// OR: if using async/await
let promoOffers = await package.storeProduct.getEligiblePromotionalOffers()
[RCPurchases.sharedPurchases getPromotionalOfferForProductDiscount:product.discounts[0]
withProduct:product
withCompletion:^(RCPromotionalOffer * _Nullable discount, NSError * _Nullable error) {
if (discount) {
// Payment discount fetched
}
}];
const paymentDiscount = await Purchases.getPromotionalOffer(product, product.discounts[0]);
if (paymentDiscount) {
// Payment discount fetched
}
Purchase the Product with the Promotional Offer
After successfully fetching the PromoOffer
, you can now display the Promotional Offer to the user however you'd like. If the user chooses to purchase, pass a Package
and PromoOffer
to the .purchase(package:promotionalOffer:)
method.
Purchases.shared.purchase(package: package,
promotionalOffer: promoOffer) { transaction, customerInfo, error, userCancelled in
if customerInfo?.entitlements.all[<your_entitlement_id>]?.isActive == true {
// Unlock that entitlements content
}
}
[RCPurchases.sharedPurchases purchasePackage:package withDiscount:discount
completionBlock:^(RCStoreTransacction * _Nullable transaction, RCCustomerInfo * _Nullable purchaserInfo, NSError * _Nullable error, BOOL userCancelled) {
if (purchaserInfo.entitlements[<your_entitlement_id>].isActive) {
// Unlock that great "pro" content
}
}];
const purchaseMade = await Purchases.purchaseDiscountedPackage(package, paymentDiscount);
Offer Codes
With iOS 14, Apple announced a new feature for subscription developers called “Offer Codes.” Offer Codes allow developers to offer custom pricing and trials, in the form of a redeemable code, to their customers.
1. Configuring an Offer Code
Offer Codes are configured similarly to Subscription Offers in App Store Connect.
2. Redeeming an Offer Code
Option 1: In-app Redemption Sheet
Note
Since launch, Apple's in-app Offer Code redemption sheet has proven to be extremely unstable. For example, the sheet may not connect, may not dismiss after a successful redemption, and may not accept valid codes. Additionally, sandbox and TestFlight behavior has been seen to be inconsistent.
A workaround may be to instead redirect customers to the App Store app to redeem codes as described below.
To allow your users to redeem Offer Codes, you'll need to present the Offer Code redemption sheet. In Purchases SDK 3.8.0, you can call the presentCodeRedemptionSheet
method.
Purchases.shared.presentCodeRedemptionSheet()
Apple does not provide a callback to determine if the code redemption was successful. Since the Purchases SDK will automatically pick up on new transactions that enter the underlying transaction queue, you should implement the receivedUpdated
delegate or listener to respond to changes in CustomerInfo
. Once we sync the Offer Code transaction, we'll automatically refresh CustomerInfo.
The Offer Code redemption sheet may not display on a device if you haven't yet launched the App Store app and accepted the terms agreement.
Option 2: Redirect to App Store app
You can link to the App Store with a prefilled code for redemption with the following URL format:
https://apps.apple.com/redeem?ctx=offercodes&id={apple_app_id}&code={code}
You can find your Apple App ID in your app settings in App Store Connect (General -> App Information).
When users click your link within your app to redeem the offer code, it will take them outside of the app to complete the purchase. It is important to call syncPurchases when the user returns back to your app to retrieve their purchase. This may be done by recording when the user leaves the app due to the link, and calling syncPurchases
when the user returns to the app. If not, the user may need to trigger a restore within your app when they come back.
Considerations
- In order for RevenueCat to accurately track revenue for offer codes, you will need to upload an in-app purchase key. See our guide on In-App Purchase Key Configuration for step-by-step instructions.
Next Steps
- For a guided walkthrough of implementing Subscription Offers into a Swift app check out our blog
Updated 7 days ago