OfferInfo

data class OfferInfo(val productId: String, val basePlanId: String?, val offerId: String?, val offerToken: String, val offerTags: List<String>, val pricingPhases: List<ProductDetails.PricingPhase>, val isFreeTrial: Boolean, val trialPeriod: String?, val trialPhase: ProductDetails.PricingPhase?, val hasIntroPrice: Boolean, val introPrice: String?, val introPriceMicros: Long, val introPeriod: String?, val introCycleCount: Int, val introPhase: ProductDetails.PricingPhase?, val basePrice: String, val basePriceMicros: Long, val billingPeriod: String?, val currencyCode: String, val basePhase: ProductDetails.PricingPhase?, val installmentPlanDetails: ProductDetails.InstallmentPlanDetails? = null)

Typed view over a subscription ProductDetails.SubscriptionOfferDetails, surfacing the trial / intro / base pricing phases as flat fields for easy UI binding.

Each Play subscription offer can have up to three pricing phases:

  • free trialpriceAmountMicros == 0, RecurrenceMode.FINITE_RECURRING

  • introductorypriceAmountMicros > 0, RecurrenceMode.FINITE_RECURRING

  • baseRecurrenceMode.INFINITE_RECURRING

Use AppPurchase.getOffers, AppPurchase.getTrialOffer, or AppPurchase.getBaseOffer to obtain instances — do not construct directly.

Since

3.5.7

Constructors

Link copied to clipboard
constructor(productId: String, basePlanId: String?, offerId: String?, offerToken: String, offerTags: List<String>, pricingPhases: List<ProductDetails.PricingPhase>, isFreeTrial: Boolean, trialPeriod: String?, trialPhase: ProductDetails.PricingPhase?, hasIntroPrice: Boolean, introPrice: String?, introPriceMicros: Long, introPeriod: String?, introCycleCount: Int, introPhase: ProductDetails.PricingPhase?, basePrice: String, basePriceMicros: Long, billingPeriod: String?, currencyCode: String, basePhase: ProductDetails.PricingPhase?, installmentPlanDetails: ProductDetails.InstallmentPlanDetails? = null)

Types

Link copied to clipboard
object Companion

Properties

Link copied to clipboard
val basePhase: ProductDetails.PricingPhase?

Raw base phase, or null.

Link copied to clipboard

Base plan id from Play Console (null on legacy or simple offers).

Link copied to clipboard

Locale-formatted base price (e.g. "$9.99"); empty if no base phase exists.

Link copied to clipboard

Base price in micros, or 0.

Link copied to clipboard

ISO-8601 base billing cycle (e.g. "P1M", "P1Y"), or null.

Link copied to clipboard

billingPeriod parsed into components, or null when absent/unparseable. Use BillingPeriod.unit and BillingPeriod.count to render a localized label such as "per month".

Link copied to clipboard

ISO-4217 currency code (e.g. "USD"); falls back to intro/trial currency if base is absent.

Link copied to clipboard

Locale-formatted counterpart of firstCyclePriceMicros — the trial phase's formatted price (usually a localized "Free"), the intro price, or the base price. Empty when no phase is available.

Link copied to clipboard

The price the user actually pays for the first billing cycle, in micros: 0 during a free trial, the intro price when one applies, otherwise the base price. Use this to render the "you pay now" line of a paywall.

Link copied to clipboard

true when the offer has a paid finite-recurring (intro) phase.

Link copied to clipboard

true when this offer carries any promotional phase (trial or intro price). The inverse of isBaseOffer.

Link copied to clipboard

Number of payments the user commits to when first purchasing an installments plan, or 0 when this is not an installments plan.

Link copied to clipboard
val installmentPlanDetails: ProductDetails.InstallmentPlanDetails?

Installment plan details when this base plan is a Play installments subscription, or null for standard auto-renewing plans.

Link copied to clipboard

Number of payments the user commits to on each renewal of an installments plan, or 0 when this is not an installments plan.

Link copied to clipboard

Number of billing cycles the intro phase covers, or 0.

Link copied to clipboard

Whole-percent discount of the introductory price against the recurring price, normalized per month so a "3 months for the price of 1" offer scores correctly against a monthly base.

Link copied to clipboard

ISO-8601 intro period (e.g. "P1M"), or null.

Link copied to clipboard

introPeriod parsed into components, or null when this offer has no intro phase. Note this is the length of a single intro cycle — multiply by introCycleCount for the full promotional window, or use introTotalDays.

Link copied to clipboard
val introPhase: ProductDetails.PricingPhase?

Raw intro phase, or null.

Link copied to clipboard

Locale-formatted intro price (e.g. "$1.99"), or null.

Link copied to clipboard

Intro price in micros (price × 1,000,000), or 0.

Link copied to clipboard

Total length of the introductory window in days — one intro cycle multiplied by introCycleCount. Returns 0 when there is no intro phase.

Link copied to clipboard

true when this offer has no promotional phase — neither a free trial nor an introductory price — i.e. the user pays the recurring price from day one.

Link copied to clipboard

true when the offer has a free-trial phase.

Link copied to clipboard

true when this offer is an installments base plan — the user commits to a number of payments up front. See installmentCommitmentPayments.

Link copied to clipboard

Offer id from Play Console (null when this row represents the base plan itself).

Link copied to clipboard

Free-form tags configured for the offer in Play Console.

Link copied to clipboard

Opaque token passed to com.android.billingclient.api.BillingFlowParams when launching purchase.

Link copied to clipboard

Recurring price normalized to one average month, in micros. Lets a paywall compare a yearly plan against a monthly one on equal terms, and render "only $4.16/month, billed yearly".

Link copied to clipboard

Recurring price normalized to one week, in micros. Returns 0 when the base price or billing period is unavailable.

Link copied to clipboard
val pricingPhases: List<ProductDetails.PricingPhase>

Raw phase list — use the typed trial* / intro* / base* fields where possible.

Link copied to clipboard

Play product id this offer belongs to.

Link copied to clipboard

Length of the free trial in days, or 0 when there is no trial.

Link copied to clipboard

ISO-8601 trial duration (e.g. "P7D"), or null.

Link copied to clipboard

trialPeriod parsed into components, or null when this offer has no trial.

Link copied to clipboard
val trialPhase: ProductDetails.PricingPhase?

Raw trial phase, or null.

Functions

Link copied to clipboard
fun hasTag(tag: String): Boolean

true when this offer carries the given Play Console offer tag. Tags are the supported way to mark an offer for a specific paywall slot (e.g. tag "popular" and look it up with AppPurchase.getOffersByTag).