How to use RevenueCat Experiments to A/B test in-app paywall design elements 

Test and visualize the impacts of both price and design variables using this workaround.

RevenueCat Experiments
Dan Pannasch

Dan Pannasch

February 28, 2023

We built Experiments to help you easily run, analyze, and draw conclusions from A/B price testing with the full subscription lifecycle in mind.

If you’re using Offerings to configure which products you offer in your app, you’re already set up to use Experiments through RevenueCat. Just set up the two Offerings you want to test against each other, turn on your experiment, and we’ll start splitting customers evenly between those two variants (more details here).

Experiments is loved by our developers for its ability to help visualize your experiments’ impact on lifetime value through a number of key metrics spanning the categories of initial conversion, paid customers, and revenue. 

When you run a price test in RevenueCat, we’ll show you how each metric within the customer journey has changed over time, so you can quickly see which trends are consistent, which ones are volatile, and where to dig deeper.

While Experiments is currently designed to make it easy to test pricing variables, some may want to also measure the impact of other paywall changes to lifetime value. This article will outline a workaround to testing non-pricing elements of your paywall, like design, color, or copy, as well as how to visualize and track those results within the Experiments dashboard. 

A workaround for testing non-pricing variables

Experiments uses Offerings to represent the hypothesis that’s being tested (the group of products that will be offered to your customers). An Offering is a collection of Packages that contain Products from each store you’re looking to serve that Offering on.

So to run an experiment with RevenueCat, you’ll need to create a new Offering that contains the Products you want to test.

When you run an experiment with RevenueCat, our SDK will call the getOfferings endpoint whenever you want to trigger a paywall to a customer. Based on the experiment variant the customer has been enrolled in, RevenueCat then changes what is provided as the default Offering in the response. 

That means if you’re looking to change and test another element of the user experience beyond pricing, you can leverage our getOfferings response and design your app to show a different purchase design if the default Offering that is returned in RevenueCat equals the Offering you’ve assigned to your experiment. 

Here’s an example of what an Offering response looks like today. You can see the first thing that gets attached is the current offering id, and then there’s a list of every other offering identifier that’s available for you.

2   "current_offering_id":"default",
3   "offerings":[
4      {
5         "description":"Standard monthly and annual plans",
6         "identifier":"default",
7         "packages":[
8            {
9               "identifier":"$rc_annual",
10               "platform_product_identifier":"ios_annual_9999"
11            },
12            {
13               "identifier":"$rc_monthly",
14               "platform_product_identifier":"ios_monthly_999"
15            }
16         ]
17      },
18      {
19         "description":"Duplicate offering for paywall testing",
20         "identifier":"experiment_offering",
21         "packages":[
22            {
23               "identifier":"$rc_annual",
24               "platform_product_identifier":"ios_annual_9999"
25            },
26            {
27               "identifier":"$rc_monthly",
28               "platform_product_identifier":"ios_monthly_999"
29            }
30         ]
31      }
32   ]

If you don’t have an experiment running, the current_offering_id will be the Offering you’ve marked as the current Offering in the Dashboard.

When you have an experiment running that current Offering ID will instead show the Offering in the experiment that this subscriber has been enrolled to.

We override the current Offering ID value to show the Offering ID for your experiment instead. The Offering for your experiment will already be part of your list of different Offerings.

Since this request for the relevant Offerings needs to get made every time that you’re fetching a paywall to inform which products to show, you could key off of that slightly different response so that when the current Offering ID equals that of your experiment Offering, it will trigger other changes to elements of your paywall design.

With this principle in mind, you could set up two different Offerings that have the exact same product Offering in them, but tether a non-pricing variable to trigger when one of the two Offerings is displayed. Isolating for that design, copy (or other) element.

1struct RevenueCatView: View {
2    @State private var offering: Offering?
4    var body: some View {
5        VStack {
6            if let offering {
7                if == "experiment_offering" {
8                    ExperimentPaywall()
9                } else {
10                    Paywall()
11                }
12            } else {
13                ProgressView()
14            }
15        }.task {
16            do  {
17                self.offering = try await Purchases.shared.offerings().current
18            } catch {
19                // Oops
20            }
21        }
22    }

We hope this workaround can enable you to leverage Experiments to test new variables and uncover growth for your app. If you’re looking for other inspiration on what to test with Experiments, check out this blog post on the topic: 10 price test ideas for your subscription app. Happy testing!

In-App Subscriptions Made Easy

See why thousands of the world's tops apps use RevenueCat to power in-app purchases, analyze subscription data, and grow revenue on iOS, Android, and the web.

Related posts

We launched easier cohort comparisons in RevenueCat Charts

We launched improved cohort comparisons in ‘Charts’

These additions to RevenueCat Charts make it even easier to analyze data over time

Dan Pannasch

Dan Pannasch

March 13, 2023

RevenueCat now supports Unity Package Manager

RevenueCat now supports Unity Package Manager

To make our Unity SDK even easier to use, it's now available using UPM — but the asset package is still available.

Toni Rico

Toni Rico

February 23, 2023

How we migrated our docs to DocC at RevenueCat

How we migrated our SDK docs to DocC at RevenueCat

The transition wasn't difficult and we've seen a great improvement.

Andy Boedo

Andy Boedo

February 15, 2023

Want to see how RevenueCat can help?

RevenueCat enables us to have one single source of truth for subscriptions and revenue data.

Olivier Lemarie, PhotoRoomOlivier Lemarie, PhotoRoom
Read case study