Skip to main content

Variables

AIAsk AIChatGPTClaude

For some Paywall strings you may want to set values based on the package that's being displayed instead of hardcoding a single value, such as when quoting a price, or describing the duration of an Introductory Offer.

To make this easier and ensure accuracy, we recommend using Variables for these values that are package-specific.

For example, to describe a trial that offers "1 week free", you should use the {{ product.offer_period_with_unit }} variable to insert 1 week to ensure the string is accurate for any product you use, even if you make changes to the product or its introductory offer in the future.

Product variables

Product variables are available for any package on your paywall. Use the {{ variable_name }} syntax to insert them into any text field. They are organized into the following categories:

📘Localization

All product variables return localized values based on the customer's device language and region. Prices are formatted with the appropriate currency symbol and separators (e.g., "$9.99" vs "9,99 €"), period text like "month" or "weekly" is translated to the device language, and dates follow the local format.

Pricing

VariableDescriptionExample
product.priceThe localized price of the product.$9.99
product.price_per_periodPrice with the billing period (e.g., "$9.99/month"). Lifetime products show price only.$9.99/month
product.price_per_period_abbreviatedPrice with abbreviated billing period (e.g., "$9.99/mo"). Lifetime products show price only.$9.99/mo
product.price_per_dayPrice normalized to a daily equivalent rate. Returns the full price for lifetime products.$0.33
product.price_per_weekPrice normalized to a weekly equivalent rate. Returns the full price for lifetime products.$2.50
product.price_per_monthPrice normalized to a monthly equivalent rate. Returns the full price for lifetime products.$9.99
product.price_per_yearPrice normalized to an annual equivalent rate. Returns the full price for lifetime products.$119.88
⚠️Lifetime products

For lifetime (non-subscription) products, price normalization variables (price_per_day, price_per_week, etc.) return the full product price since there is no recurring period to normalize against. price_per_period and price_per_period_abbreviated return just the price without a period suffix.

Examples for all package types
VariableWeeklyMonthly2 Month3 Month6 MonthAnnualLifetime
product.price$2.99$9.99$17.99$24.99$39.99$69.99$119.99
product.price_per_period$2.99/week$9.99/month$17.99/2 months$24.99/3 months$39.99/6 months$69.99/year$119.99
product.price_per_period_abbreviated$2.99/wk$9.99/mo$17.99/2mo$24.99/3mo$39.99/6mo$69.99/yr$119.99
product.price_per_day$0.43$0.33$0.30$0.28$0.22$0.19$119.99
product.price_per_week$2.99$2.50$2.25$1.92$1.54$1.35$119.99
product.price_per_month$11.96$9.99$9.00$8.33$6.67$5.83$119.99
product.price_per_year$155.48$119.88$107.94$99.96$79.98$69.99$119.99

Subscription period

VariableDescriptionExample
product.periodHuman-readable billing period (e.g., "month", "annual"). Returns "lifetime" for lifetime products.month
product.period_abbreviatedAbbreviated billing period (e.g., "mo", "yr"). Returns "lifetime" for lifetime products.mo
product.periodlyAdverb form of the billing period (e.g., "monthly", "annually"). Returns "lifetime" for lifetime products.monthly
product.period_in_daysBilling period length in days. Returns an empty value for lifetime products.30
product.period_in_weeksBilling period length in weeks (rounded down). Returns an empty value for lifetime products.4
product.period_in_monthsBilling period length in months. Returns 0 for periods shorter than a month. Empty for lifetime.1
product.period_in_yearsBilling period length in years. Returns 0 for sub-annual periods. Empty for lifetime.0
product.period_with_unitPeriod with its unit spelled out (e.g., "1 month", "3 months"). Returns "lifetime" for lifetime products.1 month
⚠️Lifetime products

For lifetime products, numeric period variables (period_in_days, period_in_weeks, etc.) return an empty value since there is no recurring period. Text-based period variables (period, period_abbreviated, periodly, period_with_unit) return "lifetime".

Examples for all package types
VariableWeeklyMonthly2 Month3 Month6 MonthAnnualLifetime
product.periodweekmonth2 months3 months6 monthsannuallifetime
product.period_abbreviatedwkmo2mo3mo6moyrlifetime
product.periodlyweeklymonthly2 months3 months6 monthsannuallylifetime
product.period_in_days7306090180365N/A
product.period_in_weeks148131352N/A
product.period_in_months0123612N/A
product.period_in_years000001N/A
product.period_with_unit1 week1 month2 months3 months6 months1 yearlifetime

Currency

VariableDescriptionExample
product.currency_codeThe ISO 4217 currency code for the product's price.USD
product.currency_symbolThe currency symbol for the product's price.$

Offer

These variables reference the active offer on a product. This includes introductory offers (free trials, pay-as-you-go, and pay-up-front) and promotional offers (App Store only). When a promotional offer is configured on a package and the user is eligible, it takes priority over an introductory offer for offer_* variables, and those variables will show the promotional offer's values instead of the introductory offer's.

These variables are typically used in the Text field for an introductory offer property on text components so they are only shown to eligible customers. See Supporting offers for more details on configuring offer eligibility.

⚠️No offer

If a product has no active offer (no introductory offer, no promotional offer, or the customer is not eligible), offer_price and offer_price_per_* variables fall back to the regular product price (and its normalized equivalents). All other offer variables (offer_period*, offer_end_date) return an empty value. Because of this fallback, we recommend using the Text field for an introductory offer on text components when referencing offer variables, so offer-specific messaging is only shown to eligible customers.

📘Free trials

When a product has a free trial, offer_price returns the localized word "free" (not "$0.00"). This is automatically localized to the customer's device language.

📘Short offer periods

If the intro offer period is shorter than the requested normalization unit, that variable returns empty. For example, offer_price_per_month returns empty if the intro offer is only 1 week long, and offer_price_per_year returns empty if the intro offer is only 3 months, since normalizing a shorter offer to a longer period would be misleading.

VariableDescriptionExample
product.offer_priceThe localized offer price. Returns "free" for free trials. Falls back to regular price if no offer.$1.99
product.offer_price_per_dayOffer price normalized to a daily rate. Falls back to regular price if no offer.$0.07
product.offer_price_per_weekOffer price normalized to a weekly rate. Falls back to regular price if no offer, or empty if the offer period is shorter than a week.$0.50
product.offer_price_per_monthOffer price normalized to a monthly rate. Falls back to regular price if no offer, or empty if the offer period is shorter than a month.$1.99
product.offer_price_per_yearOffer price normalized to an annual rate. Falls back to regular price if no offer, or empty if the offer period is shorter than a year.$23.88
product.offer_periodHuman-readable intro offer period (e.g., "week", "month"). Empty if no intro offer.week
product.offer_period_abbreviatedAbbreviated intro offer period (e.g., "wk", "mo"). Empty if no intro offer.wk
product.offer_period_in_daysIntro offer period length in days. Empty if no intro offer.7
product.offer_period_in_weeksIntro offer period length in weeks. Empty if no intro offer.1
product.offer_period_in_monthsIntro offer period length in months. Empty if no intro offer.0
product.offer_period_in_yearsIntro offer period length in years. Empty if no intro offer.0
product.offer_period_with_unitIntro offer period with unit spelled out (e.g., "1 week"). Empty if no intro offer.1 week
product.offer_end_dateThe localized date when the intro offer ends. Empty if no intro offer.December 31, 2024
Examples for all package types
VariableWeeklyMonthly2 Month3 Month6 MonthAnnualLifetime
product.offer_price$1.99$1.99$1.99$1.99$1.99$1.99N/A
product.offer_price_per_day$0.07$0.07$0.07$0.07$0.07$0.07N/A
product.offer_price_per_week$0.50$0.50$0.50$0.50$0.50$0.50N/A
product.offer_price_per_month$1.99$1.99$1.99$1.99$1.99$1.99N/A
product.offer_price_per_year$23.88$23.88$23.88$23.88$23.88$23.88N/A
product.offer_periodweekweekweekweekweekweekN/A
product.offer_period_abbreviatedwkwkwkwkwkwkN/A
product.offer_period_in_days777777N/A
product.offer_period_in_weeks111111N/A
product.offer_period_in_months000000N/A
product.offer_period_in_years000000N/A
product.offer_period_with_unit1 week1 week1 week1 week1 week1 weekN/A
product.offer_end_dateDecember 31, 2024December 31, 2024December 31, 2024December 31, 2024December 31, 2024December 31, 2024N/A

Secondary offer

These variables reference the second phase of a multi-phase introductory offer, which is available on the Play Store when a product has both a free trial and a discounted intro price. Empty if no secondary offer exists.

VariableDescriptionExample
product.secondary_offer_priceThe price of the second offer phase. Empty if no secondary offer.$2.99
product.secondary_offer_periodHuman-readable period of the secondary offer. Empty if no secondary offer.week
product.secondary_offer_period_abbreviatedAbbreviated period of the secondary offer. Empty if no secondary offer.wk
Examples for all package types
VariableWeeklyMonthly2 Month3 Month6 MonthAnnualLifetime
product.secondary_offer_price$2.99$2.99$2.99$2.99$2.99$2.99N/A
product.secondary_offer_periodweekweekweekweekweekweekN/A
product.secondary_offer_period_abbreviatedwkwkwkwkwkwkN/A

Other

VariableDescriptionExample
product.relative_discountDiscount percentage compared to the most expensive package per period on the paywall. Empty for the most expensive package itself (it is the baseline).19%
product.store_product_nameThe product display name as configured in App Store Connect or Google Play Console.Pro Access
📘relative_discount

relative_discount compares each package's normalized monthly price against the most expensive package per month on the paywall. For example, if you're displaying a monthly package at $10/month and a yearly package at $80/year ($6.67/month), the relative discount for the annual package would be 33%. The most expensive package per month returns an empty value (it is the baseline), so we recommend only using this variable within packages that are not the most expensive per period.

Examples for all package types
VariableWeeklyMonthly2 Month3 Month6 MonthAnnualLifetime
product.relative_discount19%19%19%19%19%19%19%
product.store_product_namePro AccessPro AccessPro AccessPro AccessPro AccessPro AccessPro Access

Custom variables

In addition to the product variables listed above, you can create Custom variables to insert dynamic content that isn't tied to a specific product. This is useful for displaying values like user-specific information, app state, or promotional messaging that changes based on your app's context.

Creating and using custom variables in the editor

To create a custom variable:

  1. In the paywall editor, select the Variables tab from the left-hand sidebar
  2. Click "Create variable"
  3. Set the name of the variable - this will be how you reference it in your paywall
  4. Give it a default value - this is what will be displayed in the preview and used as a fallback if no value is provided

The default value you set applies across your entire project, ensuring consistency wherever the variable is used. Once created, you can insert the custom variable into any text field using the same {{ custom.variable_name }} syntax.

Passing custom variable values from your app

When displaying a paywall in your app, you'll need to pass actual values for any custom variables you've created. This allows you to provide dynamic, context-specific content based on the user's session or app state.

For details on how to pass custom variable values when presenting a paywall, see Displaying Paywalls.

Countdown variables

When using a Countdown component on your paywall, you can use countdown-specific variables within any text component inside that countdown. These variables display the time remaining until the countdown's target date.

VariableDescriptionExample
count_days_with_zeroDays remaining with leading zero07
count_days_without_zeroDays remaining without leading zero7
count_hours_with_zeroHours remaining with leading zero04
count_hours_without_zeroHours remaining without leading zero4
count_minutes_with_zeroMinutes remaining with leading zero09
count_minutes_without_zeroMinutes remaining without leading zero9
count_seconds_with_zeroSeconds remaining with leading zero03
count_seconds_without_zeroSeconds remaining without leading zero3

The values displayed by these variables depend on the Count From setting of your countdown component:

  • Days: Shows total days with remainder hours (0-23), minutes (0-59), and seconds (0-59)
  • Hours: Shows 0 days, total hours, remainder minutes (0-59), and seconds (0-59)
  • Minutes: Shows 0 days, 0 hours, total minutes, and seconds (0-59)

Countdown variables are only available within text components that are inside a countdown component. They cannot be used elsewhere on your paywall.

Variable preview values

The paywall preview is generated using our example values for each package listed above, and therefore will differ from the actual values for the product's you choose to present on your paywall.

To see a more accurate preview, we recommend running your application on your physical device or in the simulator, as this will present details based on the actual information for the products you're displaying on that device.

Variable modifiers

We support a handful of modifiers that can be used to format the variable values:

  • uppercase: Converts the value to uppercase.
  • lowercase: Converts the value to lowercase.
  • capitalize: Capitalizes the first letter of each word in the value.

These modifiers can be used with the | operator after the variable name, for example:

  • {{ product.price_per_period }} will yield $2.99/week
  • {{ product.price_per_period | uppercase }} will yield $2.99/WEEK
  • {{ product.price_per_period | capitalize }} will yield $2.99/Week