play-billing-samples icon indicating copy to clipboard operation
play-billing-samples copied to clipboard

Get info whether a subscription has free trial in 5.0.0

Open esathamzaj opened this issue 2 years ago • 20 comments

How do I check if a subscription has a free trial and how many days it lasts, as in the previous version I could do it by checking the "freeTrialPeriod" field.

esathamzaj avatar Jun 01 '22 13:06 esathamzaj

You can check for the free trial period like this:

  val pricingPhaseList =  productDetails.subscriptionOfferDetails?.firstOrNull()?.pricingPhases?.pricingPhaseList ?: return null
  ...              
  val freeTrial = pricingPhaseList.firstOrNull { it.priceAmountMicros == 0L }

jobernolte avatar Jun 03 '22 13:06 jobernolte

You could check priceAmountMicros like @jobernolte 's example above., or alternatively check formattedPrice

pricingPhasesList?.filter { it.formattedPrice.contains("Free", ignoreCase = true) }

murielg avatar Jul 15 '22 19:07 murielg

@murielg locale language ignore?

AlexeyGodyaev avatar Jul 29 '22 13:07 AlexeyGodyaev

@AlexeyGodyaev That is an excellent point 🤔 Then checking priceAmountMicros is definitely the way to go if you want to account for the locale. Other than that, maybe use tags and have a freetrial tag.

murielg avatar Jul 30 '22 15:07 murielg

Also, What's the best way to identify the intro price? Sharing the sample data below 👇

"subscriptionOfferDetails": [
  {
    "offerIdToken": "...",
    "pricingPhases": [
      {
        "priceAmountMicros": 0,
        "priceCurrencyCode": "EUR",
        "formattedPrice": "Free",
        "billingPeriod": "P1W",
        "recurrenceMode": 2,
        "billingCycleCount": 1
      },
      {
        "priceAmountMicros": 95880000,
        "priceCurrencyCode": "EUR",
        "formattedPrice": "€95.88",
        "billingPeriod": "P1Y",
        "recurrenceMode": 1
      }
    ],
    "offerTags": []
  },
  {
    "offerIdToken": "..",
    "pricingPhases": [
      {
        "priceAmountMicros": 86290000,
        "priceCurrencyCode": "EUR",
        "formattedPrice": "€86.29",
        "billingPeriod": "P1Y",
        "recurrenceMode": 2,
        "billingCycleCount": 1
      },
      {
        "priceAmountMicros": 95880000,
        "priceCurrencyCode": "EUR",
        "formattedPrice": "€95.88",
        "billingPeriod": "P1Y",
        "recurrenceMode": 1
      }
    ],
    "offerTags": []
  }

ryderz8 avatar Jul 31 '22 20:07 ryderz8

@ryderz8 i think you could either add an offer tag or you could create a function that gets the lowest pricing phase using priceAmountMicros

This is from the ClassyTaxiAppKotlin sample:

    private fun leastPricedOfferToken(
        offerDetails: List<ProductDetails.SubscriptionOfferDetails>
    ): String {
        var offerToken = String()
        var leastPricedOffer: ProductDetails.SubscriptionOfferDetails
        var lowestPrice = Int.MAX_VALUE

        if (!offerDetails.isNullOrEmpty()) {
            for (offer in offerDetails) {
                for (price in offer.pricingPhases.pricingPhaseList) {
                    if (price.priceAmountMicros < lowestPrice) {
                        lowestPrice = price.priceAmountMicros.toInt()
                        leastPricedOffer = offer
                        offerToken = leastPricedOffer.offerToken
                    }
                }
            }
        }
        return offerToken
}

murielg avatar Jul 31 '22 20:07 murielg

@ryderz8 I do it the following way:

...
val pricingPhaseList = productDetails.subscriptionOfferDetails?.firstOrNull()?.pricingPhases?.pricingPhaseList ?: return null
val pricingPhase = pricingPhaseList.lastOrNull() ?: return null
val introductory = pricingPhaseList.firstOrNull { it.priceAmountMicros > 0L && it !== pricingPhase }
val freeTrial = pricingPhaseList.firstOrNull { it.priceAmountMicros == 0L }
...

Note: the first pricing phase in the list is always the normal price of the product. Afterwards introductory and free trial pricing phases are listed.

jobernolte avatar Aug 01 '22 05:08 jobernolte

This thread gives a hint about identifying trial offer. But how to get its length?

Lingviston avatar May 05 '23 15:05 Lingviston

@Lingviston https://developer.android.com/reference/com/android/billingclient/api/ProductDetails.PricingPhase#getBillingPeriod()

jobernolte avatar May 05 '23 15:05 jobernolte

@jobernolte ok, how to get the billing period of the offer after trial expires?

Lets say I have a yearly offer with 2 weeks free trial. This field gives free trial period. How to get the 1 year billing period?

Lingviston avatar May 05 '23 16:05 Lingviston

BY the way, same is valid for price: how to know for the trial offer how much use will pay after trial expires?

Lingviston avatar May 05 '23 16:05 Lingviston

See my other comment: https://github.com/android/play-billing-samples/issues/540#issuecomment-1200721899

You have different pricing phases in the list, with the first one representing the normal price and period of the product.

jobernolte avatar May 05 '23 16:05 jobernolte

OMG, thanks. I misunderstood the concept of pricing phases.

Lingviston avatar May 05 '23 16:05 Lingviston

@jobernolte

Note: the first pricing phase in the list is always the normal price of the product. Afterwards introductory and free trial pricing phases are listed.

Did you mean last pricing phase is the normal price ?

Lingviston avatar May 05 '23 16:05 Lingviston

@Lingviston yes, you're right. The last pricing phase is the normal price.

jobernolte avatar May 05 '23 16:05 jobernolte

Cool, looks like it works like a waterfall then. I wonder, is it documented somewhere officially?

Lingviston avatar May 05 '23 16:05 Lingviston

It's a little bit hidden... from the official docs:

Pricing phases for purchasing an item through a offer. Pricing phases contains time ordered list of PricingPhase.

https://developer.android.com/reference/com/android/billingclient/api/ProductDetails.PricingPhases

jobernolte avatar May 05 '23 16:05 jobernolte

Thanks again, you saved my day :) I looked for the PricingPhase and OneTImeOfferDetails docs, but not the PricingPhases 🤦

Lingviston avatar May 05 '23 16:05 Lingviston

This behavior is inconsistent for me. For most users, I see only one item in the list of getPricingPhaseList (the real price, not free), and for some, I see 2 items on the list, and one of them is of free-trial.

As I didn't see it myself, I thought it should be the same for all, meaning just one item.

How could it be? How can I have consistent results? I've written about this here: https://github.com/android/play-billing-samples/issues/639

Also, about getBillingPeriod , should I parse it, or can I assume it's the same as on the website?

AndroidDeveloperLB avatar Sep 13 '23 07:09 AndroidDeveloperLB

after migration doesn't show price for free trial and also after 1 wek trial period ends, the next billing period not extending to 30days instead extends to another 7 days.

vidhyalakhmi avatar Apr 17 '24 04:04 vidhyalakhmi