Introducing a new subscription offer: win-back offers

Today, on June 10th, WWDC 2024 commenced. Given that StoreKit is a primary Framework I interact with regularly, I was eager to watch the What’s New in StoreKit and In-App Purchase session. The video lasted about 23 minutes, and what particularly caught my attention was the introduction of a new offer type.

Benefits of win-back offers:

  • Re-engage churned subscribers.
  • Customizable eligibility rules.
  • StoreKit Message automatic merchandising.
  • Promoted on the App Store.

Before dub-dub 24, we had the following subscription offers:

  • Introductory offer
  • Promotional offer
  • Offer codes

With the new addition of win-back, the list has been updated:

  • Introductory offer
  • Promotional offers
  • Offer codes, and
  • Win-back offer

These are the new properties you need to be aware of when supporting win-back:

  • winBack: A win-back offer for an auto-renewable subscription.
  • eligibleWinBackOfferIDs: An array of strings that represent the offer identifiers of the win-back offers that the customer is eligible to redeem.
  • winBackOffers: An array of all win-back offers available for the auto-renewable subscription that you configure in App Store Connect.
  • winBackOffer(_:): Sets a win-back offer to apply to the purchase.

Testing win-back offers using StoreKit configuration

Prerequisites for testing win-back on iOS 18+:

There is now a new entry in your StoreKit configuration file.

Click on the “+” to configure a new win-back offer similar to the image below.

Now that your win-back offer is configured, you’re ready to test using your StoreKit configuration file. Make sure to select the file in your Xcode scheme editor.

To ensure you have a faster renewal rate navigate to the Xcode menu -> Editor -> Subscription Renewal Rate and set it to let’s say 5 minutes.

The logic for retrieving offers on a specific product instance may resemble the code snippet below:

// assuming we have only one offer
product.subscription?.winBackOffers.first

Also, to retrieve the win-back offer IDs, you can use the snippet below:

// The `eligibleWinBackOfferIDs` is found on the `renewalInfo`
renewalInfo.eligibleWinBackOfferIDs

Now to test we can do the following:

  • Make a standard purchase of your subscription.
  • Cancel the subscription.
  • When the given transaction has expired (assuming you set the renewal rate to 5 minutes) the subscriber will be eligible for the win-back offer.
  • Once the expiration time has passed and appropriate UI adjustments have been made to accommodate standard purchasing and win-back, your offer should be visible in the product view UI.

To make a win-back purchase you need the following snippet in your purchasing logic:

let options = Set(
    [
        Product.PurchaseOption.appAccountToken(appAccountToken),
        Product.PurchaseOption.winBackOffer(subscriptionOffer)
    ]
)
let result = try await subscription.product.purchase(options: options)

If you’re acquainted with StoreKit and have implemented purchasing, your users should regain access to the paid content they’re entitled to. Happy coding.

Resources

Leave a comment