I added the latest Google Play Billing library:
implementation 'com.android.billingclient:billing:2.0.1'
If I make a purchase with a "slow testing card, which always be approved after a couple of minutes" (this is a testing card from Google to test in-app purchases):
val params = BillingFlowParams
.newBuilder()
.setSkuDetails(skuId)
.build()
billingClient.launchBillingFlow(activity, params)
Everything goes fine, until I try to acknowledge or to consume the product:
val consumeParams = ConsumeParams
.newBuilder()
.setPurchaseToken(purchase.purchaseToken)
.build()
billingClient.consumeAsync(consumeParams, this)
I'm getting the following error in the callback:
/**
* Invalid arguments provided to the API. This error can also indicate that the application was
* not correctly signed or properly set up for In-app Billing in Google Play, or does not have
* the necessary permissions in its manifest
*/
int DEVELOPER_ERROR = 5;
I also get a debug message saying that the purchase has an invalid state (PENDING). Probably I can't consume/acknowledge purchases which doesn't have the "SUCCESS" state.
According to Google, I have 3 days to consume or to acknowledge the purchase, otherwise it will be refunded.
But how am I supposed to consume or acknowledge the purchase if they won't allow me to make it right after the purchase was made?
- I don't own a server, the consumption/acknowledge should be made on mobile
- I can't keep the user with a loading progress dialog/view in the app while the purchase will be validated (getting the
SUCCESSstate. With a testing account, within 5 - 6 minutes I'm getting the new "SUCCESS" state viaonPurchasesUpdated(billingResult: BillingResult?, purchases: MutableList<Purchase>?))
I'm using the MVVM architecture (Activity - ViewModel) and within the Activity I'm keeping the Billing Client library (because the library needs a Context) and in the ViewModel the business logic.
It looks like Google doesn't want us to "bind" the billing client library to an activity/viewmodel and instead use it in a Service and instantiate it in the Application class. Probably communicating with Observers or BroadcastReceivers and listen for purchase updates. And once the Purchase is validated or rejected I should update the user's profile. This already can cause a problem, because I can't start a Service without having a non-dismissable sticky notification because this is a foreground service and I should notify the user that the app is running in the background. This will scare the hell out of the users.
This new purchase flow breaks multiple things. This shouldn't be asynchronous. In real life situation when I purchase something, I give the money to the cashier then I receive my product/service not after 5 minutes! How am I supposed to deal with this? The user makes a purchase, then I notify the user he/she will get the product within 5 minutes after confirmation from Google? This should be instantaneous.
How do you deal with in-app purchases?