Reputation: 465
Google has updated its billing system and there is no full information how to deal with it.
Thus, instead of SkyDetails
we have class ProductDetails
. This object we can receive in callback of billingClient.queryProductDetailsAsync()
. Then we can call getSubscriptionOfferDetails()
on this object and get access to list of ProductDetails.PricingPhases
. For example, if product has 2 offers(base and trial offer) we get list of 2 ProductDetails.PricingPhases
.
Then when user want to buy a product we use this(from official doc):
val offerToken = productDetails.offerDetails(selectedOfferIndex).offerToken
What is selectedOfferIndex
? Should we always select first item or it depends?
Thanks everyone in advance.
Upvotes: 10
Views: 4324
Reputation: 724
The selectedOfferIndex
depends on the offer the developer want to give to the users.
We have to loop through the total offers(getSubscriptionOfferDetails()) and use the token for the offer we want to give.
ProductDetails productDetails;
String offerToken = "";
if (productDetails.getSubscriptionOfferDetails() != null) {
for(int i = 0; i < productDetails.getSubscriptionOfferDetails().size();i++) {
offerToken = productDetails.getSubscriptionOfferDetails().get(i).getOfferToken();
if(!offerToken.isEmpty()){
break;
}
}
}
if there is only base plan then only one token is returned.
if there is base plan and free tril offer then getSubscriptionOfferDetails().size()
will return 2
With Base + trial, when I pass 0th index token
With Base + trial, when I pass 1st index token
See my other answer for more additional info on V5 billing
https://stackoverflow.com/a/73650172/7923782
Upvotes: 4
Reputation: 61019
Example you have 2 subscriptions (2 products) like this
[
ProductDetails{
parsedJson={
"productId": "...",
"subscriptionOfferDetails": [
{
"offerIdToken": "...token_1...",
"pricingPhases": [
{
"priceAmountMicros": 631000000000,
"priceCurrencyCode": "VND",
"formattedPrice": "₫631,000",
"billingPeriod": "P6M",
}
]
}
]
}
},
ProductDetails{
parsedJson={
"productId": "...",
"subscriptionOfferDetails": [
{
"offerIdToken": "...token_2...",
"pricingPhases": [
{
"priceAmountMicros": 0,
"priceCurrencyCode": "VND",
"formattedPrice": "Free",
"billingPeriod": "P1M",
"recurrenceMode": 2,
"billingCycleCount": 1
},
{
"priceAmountMicros": 112000000000,
"priceCurrencyCode": "VND",
"formattedPrice": "₫112,000",
"billingPeriod": "P6M",
}
],
{
"offerIdToken": "...token_3...",
"pricingPhases": [
{
"priceAmountMicros": 631000000000,
"priceCurrencyCode": "VND",
"formattedPrice": "₫631,000",
"billingPeriod": "P6M",
}
]
}
}
]
}
}
]
Example to buy the 1st plan (with 1 month free trial) on 2nd subscription (ProductDetails)
val productDetails2 = ...
val offerToken = "...token_2..."
// val offerToken = productDetails2.subscriptionOfferDetails.get(0).offerToken
// in json response, it name is offerIdToken but after parse it's offerToken
val productDetailsParamsList =
listOf(
BillingFlowParams.ProductDetailsParams.newBuilder()
.setProductDetails(productDetails2)
.setOfferToken(offerToken)
.build()
)
val billingFlowParams = BillingFlowParams.newBuilder()
.setProductDetailsParamsList(productDetailsParamsList)
.build()
billingClient.launchBillingFlow(this, billingFlowParams)
Upvotes: 3