Android Question GooglePlayBilling - Change subscription type

DavideTr94

Member
Good morning everyone,
in my App there are 5 different types of subscription, each with different prices but all lasting one month.

I should make a function that allows the user to upgrade a service by purchasing a different subscription:

To go from "pui_cloud_lvl1" (1.99 €) to "pui_cloud_lvl2" (2.99 €) I think I have to find a way to cancel the "lvl1" subscription and buy the "lvl2" subscription but I have no idea how to do it ...

Has anyone already had a need of this type? How can I solve this problem? Thank you all :)
 

DavideTr94

Member
Hi, thanks for the reply

In the meantime I found this thread: https://www.b4x.com/android/forum/threads/howto-googleplaybilling-subscription-up-downgrade.111090/

I have attempted to replicate this code
Test for change subscription type:
Sub ElementsBox1_TitleLabel1_Click
    'Connetti al Google Play Store
    Log("Tento di connettermi al Play Store...")
    Wait For (BillingManager.ConnectIfNeeded) BillingManager_Connected (Result As BillingResult)
    If Result.IsSuccess = True Then
        'get the sku details
        Log("Connesso, verifico dettagli SKU...")
        Dim sf As Object = BillingManager.QuerySkuDetails("subs", Array(iControl.SUBS_TYPE_ID & SelectedButtonID)) 'Cambiare con ID corrente
        Wait For (sf) BillingManager_SkuQueryCompleted (Result As BillingResult, SkuDetails As List)
        If Result.IsSuccess And SkuDetails.Size = 1 Then
            Log("Dettagli SKU: " & SkuDetails.Get(0))
        End If
        Try
            LaunchBillingFlow(SkuDetails.Get(0), iControl.SUBS_TYPE_ID & "5")
        Catch
            Log(LastException)
        End Try
    Else
        Log("Connessione al Play Store non riuscita!")
    End If
End Sub

'should be called from the activity
Private Sub LaunchBillingFlow(sku As SkuDetails, OldSku As String) As BillingResult
    Dim jo As JavaObject = BillingManager
    Dim BillingClient As JavaObject = jo.GetField("client")
    Dim context As JavaObject
    context.InitializeContext
    Dim BillingFlowParams As JavaObject
    BillingFlowParams = BillingFlowParams.InitializeStatic("com.android.billingclient.api.BillingFlowParams") _
               .RunMethodJO("newBuilder", Null).RunMethodJO("setSkuDetails", Array(sku)) _
               .RunMethodJO("setOldSku", Array(OldSku)).RunMethod("build", Null)
    Return BillingClient.RunMethod("launchBillingFlow", Array(context, BillingFlowParams))
End Sub

but the Log gives me this message:

Log output:
** Activity (subscriptionmanageractivity) Resume **
Animazione barra avviata
** Activity (subscriptionmanageractivity) Pause, UserClosed = false **
** Activity (subscriptionbuyactivity) Create, isFirst = true **
** Activity (subscriptionbuyactivity) Resume **
Valore: 700
Tento di connettermi al Play Store...
Connesso, verifico dettagli SKU...
Dettagli SKU: SkuDetails: {"productId":"pui_cloud_lvl_3","type":"subs","price":"3,99 €","price_amount_micros":3990000,"price_currency_code":"EUR","title":"Professional UI - 700GB (Professional UI)","description":"Continua ad utilizzare Professional UI ed ottieni 700GB di spazio sul Cloud","subscriptionPeriod":"P1M","skuDetailsToken":"AEuhp4IF6o6JDLMAiClak_T1Sxkynd-DOSSvQQLEi_g2ec4x45JpTI2nc_GLyFpXHrNO"}
(RuntimeException) java.lang.RuntimeException: Method: setOldSku not matched.

--> (RuntimeException) java.lang.RuntimeException: Method: setOldSku not matched.

I'm probably doing something wrong, can someone help me? Thanks to all
 
Upvote 0

Erel

B4X founder
Staff member
Licensed User
You are correct. It is possible to do from the client.

It requires a new parameter:
B4X:
Sub LaunchBillingFlow(sku As SkuDetails, OldSku As String, PurchaseToken As String) As BillingResult
    Dim jo As JavaObject = Starter.billing
    Dim BillingClient As JavaObject = jo.GetField("client")
    Dim context As JavaObject
    context.InitializeContext
    Dim BillingFlowParams As JavaObject
    BillingFlowParams = BillingFlowParams.InitializeStatic("com.android.billingclient.api.BillingFlowParams") _
                .RunMethodJO("newBuilder", Null).RunMethodJO("setSkuDetails", Array(sku)) _
                .RunMethodJO("setOldSku", Array(OldSku, PurchaseToken)).RunMethod("build", Null)
    Return BillingClient.RunMethod("launchBillingFlow", Array(context, BillingFlowParams))
End Sub

Note that at some point the library will be updated and this code will require an update as well.
 
Upvote 0

DavideTr94

Member
You are correct. It is possible to do from the client.

It requires a new parameter:
B4X:
Sub LaunchBillingFlow(sku As SkuDetails, OldSku As String, PurchaseToken As String) As BillingResult
    Dim jo As JavaObject = Starter.billing
    Dim BillingClient As JavaObject = jo.GetField("client")
    Dim context As JavaObject
    context.InitializeContext
    Dim BillingFlowParams As JavaObject
    BillingFlowParams = BillingFlowParams.InitializeStatic("com.android.billingclient.api.BillingFlowParams") _
                .RunMethodJO("newBuilder", Null).RunMethodJO("setSkuDetails", Array(sku)) _
                .RunMethodJO("setOldSku", Array(OldSku, PurchaseToken)).RunMethod("build", Null)
    Return BillingClient.RunMethod("launchBillingFlow", Array(context, BillingFlowParams))
End Sub

Note that at some point the library will be updated and this code will require an update as well.

Hi, I tried the changes you proposed, the problem is that I can't complete the operation: my intent is to switch the user from one subscription to another of the same App..

I tried to do the following:
Test for change subscription type:
Sub ElementsBox1_TitleLabel1_Click
    'Connetti al Google Play Store
    Log("Tento di connettermi al Play Store...")
    Wait For (BillingManager.ConnectIfNeeded) BillingManager_Connected (Result As BillingResult)
    If Result.IsSuccess = True Then
        'get the sku details
        Log("Connesso, verifico dettagli SKU...")
        Dim sf As Object = BillingManager.QuerySkuDetails("subs", Array(iControl.SUBS_TYPE_ID & SelectedButtonID)) 'Cambiare con ID corrente
        Wait For (sf) BillingManager_SkuQueryCompleted (Result As BillingResult, SkuDetails As List)
        If Result.IsSuccess And SkuDetails.Size = 1 Then
            Log("Dettagli SKU: " & SkuDetails.Get(0))
        End If
        Wait For (BillingManager.QueryPurchases("subs")) BillingManager_PurchasesQueryCompleted (Result As BillingResult, Purchases As List)
        Log("Query completed: " & Result.IsSuccess)
        If Result.IsSuccess Then
            For Each p As Purchase In Purchases
                If p.Sku = iControl.SUBS_TYPE_ID & SelectedButtonID Then 
                    Try
                        ChangeSubType(SkuDetails.Get(0), "pui_cloud_lvl_5", p.PurchaseToken)
                    Catch
                        Log(LastException)
                    End Try
                End If
            Next
        End If
    Else
        Log("Connessione al Play Store non riuscita!")
    End If
End Sub


Private Sub ChangeSubType(CurrentSku As SkuDetails, NewSku As String, PurchaseToken As String) As BillingResult
    Dim jo As JavaObject = BillingManager
    Dim BillingClient As JavaObject = jo.GetField("client")
    Dim context As JavaObject
    context.InitializeContext
    Dim BillingFlowParams As JavaObject
    BillingFlowParams = BillingFlowParams.InitializeStatic("com.android.billingclient.api.BillingFlowParams") _
                .RunMethodJO("newBuilder", Null).RunMethodJO("setSkuDetails", Array(CurrentSku)) _
                .RunMethodJO("setOldSku", Array(NewSku, PurchaseToken)).RunMethod("build", Null)
    Return BillingClient.RunMethod("launchBillingFlow", Array(context, BillingFlowParams))
End Sub

In the "CurrentSku" parameter I give the current value corresponding to the currently active subscription (pui_cloud_lvl_3) which corresponds to
B4X:
Dettagli SKU: SkuDetails: {"productId":"pui_cloud_lvl_3","type":"subs","price":"3,99 €","price_amount_micros":3990000,"price_currency_code":"EUR","title":"Professional UI - 700GB (Professional UI)","description":"Continua ad utilizzare Professional UI ed ottieni 700GB di spazio sul Cloud","subscriptionPeriod":"P1M","skuDetailsToken":"AEuhp4JsDT7JainU-dU6QH61qboqwsyWkcni7eZelaTP0stcxrqmWhXHQoQ6s-OzFprF"}

in "NewSku" I give the string parameter (pui_cloud_lvl_5) and in "PurchaseToken" I give the current token.

The result I'm trying to get in the test is to switch from lvl3 subscription to lvl5, I read here ( Google Play Billing Library release notes (android.com) ) that to update the current subscription I should use "setSubscriptionUpdateParams" but I don't understand how to do it .. Thanks so much
 
Upvote 0
Top