Update to Billing Library 3

A common mistake is to set the type of item you want to be purchased repeatedly in sdkbox_config.json to non_consumable.
Is it set to consumable?

Exactly. But this is not the case. It’s a consumable product and I can buy it several times in a row, but one in three times it gives the error. But then it starts working again.

Oh okay, I get it now. In my case, it’s a non_consumable product.

is there a fix for the “7: You already owned this item” problem?

I’m still having this issue reported by my users and it’s easy to repro on my side. just have to buy again an item marked as consumable. on the logs its shows as consumed…

Can you post the logs and we can ask @htlxyz to help out

@htlxyz can you please help? the first purchase of a consumable product goes ok, but on the consume part of the transaction, this appears on the logs every time:

SDKBoxIABBillingClient: Acknowledga product response code:0
Preformatted textBillingClient: Error consuming purchase with token. Response code: 6
SDKBoxIABBillingClient: consume product response code:6

if later the user tries to buy the same item, the user gets the error 7 item already owned, and this appears on the logs:

BillingHelper: Couldn't find purchase lists, trying to find single data.
BillingHelper: Received a bad purchase data.
BillingHelper: Couldn't find single purchase data as well.
SDKBoxIABBillingClient: handlePurchaseResult:7 

any idea on how this can be fixed?

The error value 6, which means that the comsume is fail.

Do you have steps that can reproduce this issue.

Yes. It’s very easy. Buy a consumable item for the second time. Happens all the time.
There are many other posts of users reporting this same problem here in the forum.

Yes, it is true that someone has got the consume issue.

Everyone’s situation is different.

Your problem is that you consume failed. so, can’t purchase same item again.

According to what you said, it can be reproduced by direct purchase. I tested it with sdkbox-sample-cpp317/iap, but it didn’t reproduce.

maybe you can share me a test project.

thanks for looking into this.
I created a test project with the latest version of your plugin (2.7.5.0) and sharing it. included cocos 4.0 to be faster for you:
1 - download the sample project from https://1drv.ms/u/s!AiuQ2l1EMumQicQtmitBG_JHAUfLSw?e=GSxoMz
2 - open proj.android/gradle.settings and fill the RELEASE_STORE_FILE and the other key related properties. add the correct JDK path to org.gradle.java.home
3 - fill your app package name on the manifest file
4 - open proj.android/app/build.gradle and fill your applicationId with the package name you entered on the last step.
5 - fill your iap item details on sdkbox_config.json
6 - on the helloWorldScene.cpp fill your IAP item name
7 - build and install with gradlew installDebug
8 - buy and item and try to buy it for the second time.

i tried purchase many times with your sample.

some times will consume failed after purchase, then will get item already owned issue.

you can consume again after auto consume failed.

thanks. that will do as a workaround. is there a way to fix this properly in your API?
I’m just afraid that with this workaround if the user loses internet in the middle of the consume, there will be an infinite loop as the sdkbox::IAP::finishTransaction will be calling again later the onConsumed with error.

What about Cocos Creator? The item already owned problem exists there too.
Plugin 2.7.5.0.

Thanks for the quick fix.
I think this might be the problem caused code 6 error.

Another possibility for receiving response code 6 is the developer payload string is empty. You can remove the .setDeveloperPayload(purchase.getDeveloperPayload()) line as specifying a developer payload is optional for ConsumeParams.
If you want to send a developer payload, make sure that purchase.getDeveloperPayload() is not returning an empty string.

in fact, setDeveloperPayload is deprecated in billingclient.
and We don’t support developer payload.

2 Likes

Yes, in some cases (such as no network), this will be an infinite loop.
You can set the maximum number of attempts to cosume.

Actually, there is no essential difference between the code of SDKBox and your code, so at present, what SDKBox can do is the same as what you can do.

We will do some reserach to check whether there have a better solution do it in SDKBox.

1 Like

Hi, I have just updated SDKbox to the latest available version v2.7.6.1. Unfortunately after purchasing/restoring I am getting following error and then crash:

06-07 23:37:18.039  4021  4056 E AndroidRuntime: java.lang.NoSuchMethodError: No virtual method getSku()Ljava/lang/String; in class Lcom/android/billingclient/api/Purchase; or its super classes (declaration of 'com.android.billingclient.api.Purchase' appears in base.apk)
06-07 23:37:18.039  4021  4056 E AndroidRuntime:        at com.sdkbox.plugin.SDKBoxIABBillingClient.purchaseVerifiAndNotify(SDKBoxIABBillingClient.java:772)
06-07 23:37:18.039  4021  4056 E AndroidRuntime:        at com.sdkbox.plugin.SDKBoxIABBillingClient.handlePurchaseResult(SDKBoxIABBillingClient.java:621)
06-07 23:37:18.039  4021  4056 E AndroidRuntime:        at com.sdkbox.plugin.SDKBoxIABBillingClient.access$1800(SDKBoxIABBillingClient.java:37)
06-07 23:37:18.039  4021  4056 E AndroidRuntime:        at com.sdkbox.plugin.SDKBoxIABBillingClient$11.run(SDKBoxIABBillingClient.java:944)
06-07 23:37:18.039  4021  4056 E AndroidRuntime:        at android.opengl.GLSurfaceView$GLThread.guardedRun(GLSurfaceView.java:1500)
06-07 23:37:18.039  4021  4056 E AndroidRuntime:        at android.opengl.GLSurfaceView$GLThread.run(GLSurfaceView.java:1270)

Am I missing something? I did auto update of sdkbox. No manual integration.

Thanks,
kds

does gradle depedency upgrade to billingclient 3.0.2?

check file proj.android/app/build.gradle

dependencies {
    ...
    implementation 'com.android.billingclient:billing:3.0.2'
}

Thank you @htlxyz. It works, finally :slight_smile:

Here are the steps you will need to do if you migrate your project from old google billing (yeah, I had some more issues :P).

Do it before calling “sdkbox update”.

  1. Clear android build.
  2. Remove billing-2.0.1.jar from cocos2d/cocos/platform/android/java/libs.
  3. Remove com.android.vending.BILLING permission from AndroidManifest.
  4. Remove com.android.billingclient.api.ProxyBillingActivity activity from AndroidManifest.
  5. Add implementation ‘com.android.billingclient:billing:3.0.2’ to your app/build.gradle.
  6. Call sdkbox update.
  7. Build your cool project.

Works with cocos2dx v3.15.1.

Best,
kds

Hi there, I’m updating an old game to be compliant with billing library 3 but since I have upgraded sdkbox (iap version is 2.7.6.1) the game crashes on startup with this stacktrace:

09-20 13:07:49.321 5399 5399 E AndroidRuntime: java.lang.IllegalArgumentException: Support for pending purchases must be enabled. Enable this by calling ‘enablePendingPurchases()’ on BillingClientBuilder.
09-20 13:07:49.321 5399 5399 E AndroidRuntime: at com.android.billingclient.api.BillingClient$Builder.build(com.android.billingclient:billing@@3.0.2:3)
09-20 13:07:49.321 5399 5399 E AndroidRuntime: at com.sdkbox.plugin.SDKBoxIABBillingClient$1.run(SDKBoxIABBillingClient.java:68)
09-20 13:07:49.321 5399 5399 E AndroidRuntime: at android.os.Handler.handleCallback(Handler.java:938)
09-20 13:07:49.321 5399 5399 E AndroidRuntime: at android.os.Handler.dispatchMessage(Handler.java:99)
09-20 13:07:49.321 5399 5399 E AndroidRuntime: at android.os.Looper.loop(Looper.java:223)
09-20 13:07:49.321 5399 5399 E AndroidRuntime: at android.app.ActivityThread.main(ActivityThread.java:7664)
09-20 13:07:49.321 5399 5399 E AndroidRuntime: at java.lang.reflect.Method.invoke(Native Method)
09-20 13:07:49.321 5399 5399 E AndroidRuntime: at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:592)
09-20 13:07:49.321 5399 5399 E AndroidRuntime: at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:947)

@htlxyz, any ideas of what is happening?

Thx in advance! :slight_smile:
fryderyk