Getting the ProductDetails price in android-billing-5.0
Asked Answered
R

3

38

I have upgraded my Kotlin app to android-billing 5.0 from 4.0, and as such, SkuDetails is now deprecated so I am migrating to using ProductDetails using the migration instructions.

Previously I displayed the purchase price for in-app purchases to the user using SkuDetails.price, but I cannot find a similar method in ProductDetails.

In Google Play Billing Library 5.0, is there a non-deprecated way to retrieve the price for an in-app purchase or subscription?

Rotow answered 13/5, 2022 at 22:34 Comment(0)
H
41

Based on the documentation you can call getOneTimePurchaseOfferDetails() on ProductDetails to return a ProductDetails.OneTimePurchaseOfferDetails object, which has a getFormattedPrice() method to return the price for in-app purchases.

For subscriptions you can call getSubscriptionOfferDetails() which returns a list of ProductDetails.SubscriptionOfferDetails objects, which have a getPricingPhases() method to return different pricing phases. The pricing phase objects have a getFormattedPrice() method to get the price from.

UPDATE

To better explain what this new approach allows, you can now create multiple "base plans" for a given subscription product. For example, you could create an "unlimited" product, then create an "unlimited-annual" plan for $50/year and an "unlimited-monthly" plan for $5/month.

The ProductDetails returned for a configuration like that would look like this - where you have a single productId with multiple payment rates/plans. If you add a promotion (e.g. discount for the first year) that shows up with a non-null offerId under an existing base plan ID.

{
  productId: "unlimited",

  subscriptionOfferDetails: 
  [
    {
      basePlanId: "unlimited-monthly",
      offerId: null,
      pricingPhases:
      [
        {formattedPrice: "$5", billingPeriod: P1M, recurrence: 1}
      ]
    },

    {
      basePlanId: "unlimited-annual",
      offerId: null,
      pricingPhases:
      [
        {formattedPrice: "$50", billingPeriod: P1Y, recurrence: 1}
      ]
    },

    {
      basePlanId: "unlimited-annual",
      offerId: "unlimited-annual-promotion",
      pricingPhases:
      [
        {formattedPrice: "$30", billingPeriod: P1Y, recurrence: 2}
        {formattedPrice: "$50", billingPeriod: P1Y, recurrence: 1}
      ]
    }
  ],
 
  oneTimePurchaseOfferDetails: null
}

There are also details from Google here about the new format.

Hock answered 14/5, 2022 at 14:9 Comment(4)
... why would they change a perfectly fine & simple method into something so unnecessarily complicated??Lumpen
No idea... I need to do this migration myself still but am putting it off for now...Hock
Read qonversion.io/blog/google-play-billing-library-5-0 to see the idea behind the curtainMarcimarcia
@Big_Chair, no kidding, the API in version 4 was already insanely complicated, and they decided to add a new layer of complexity.Conference
C
18

In Kotlin you can call this on the product

subscriptionOfferDetails?.get(0)?.pricingPhases?.pricingPhaseList?.get(0)?.formattedPrice
Carranza answered 13/9, 2022 at 22:12 Comment(4)
It works, But ... OMG I can't believe that's the thing we have to write just to get the price .... !!! ???Steinke
@Steinke it used to be easier, but I guess google didn't think soCarranza
This will fail when the subscription base plan has multiple offers. subscriptionOfferDetails?.get(0)? -> from what I can see, it is not guaranteed that the base plan is at position 0Simonides
If we look the documentation, I', afraid, this oneliner is the simplest way to handle this, if we have one product with one time period. With many product with many time periods it is even more complicated.Arequipa
U
5

In java you can get the price as a string (complete with the appropriate currency sign) thusly:

product.get(i).getOneTimePurchaseOfferDetails().getFormattedPrice()

where product is a List<ProductDetails> from the onProductDetailsResponse listener

(I understand the question was for kotlin, but this is one of the first hits you find when search for this solution so a Java answer is worth including as well).

Unbalanced answered 11/3, 2023 at 22:59 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.