#BillTransaction Error

1 messages · Page 1 of 1 (latest)

stone elk
#

Problem:
A user is receiving an error message when attempting to make a purchase.

User Information:
Device Model: iPhone XR
iOS Version: 18.6.0

Log Information from Firebase:
Error Code: 0
BillingTransactionState: Failed

Log Details from Version 2.7.2:

{
"Transaction Error": {
"Domain": null,
"Code": 0,
"Description": "Error Domain=SKErrorDomain Code=0 "An unknown error occurred" UserInfo={NSLocalizedDescription=An unknown error occurred, NSUnderlyingError=0x13098e6a0 {Error Domain=ASDServerErrorDomain Code=2037 "Your purchase could not be completed" UserInfo={NSLocalizedFailureReason=Your purchase could not be completed}}}"
}
}
Note: The user had one successful transaction on this version before encountering this error.

Log Details from Version 3.2.1:
The user continues to receive errors after updating to a new version.
{
"BillingTransactionState": "Failed",
"Transaction Error": {
"Domain": null,
"Code": 0,
"Description": "The request could not be completed."
}
}

Questions:
1.What are the possible causes for this type of SKErrorDomain Code=0 and ASDServerErrorDomain Code=2037 error?
2.Are there specific logs or data points we should be checking for further investigation?
3.For this type of persistent purchase failure across versions, could the version switch or update have been a contributing factor?

bronze stratus
#

It's an error from apple due to payment configuration and it's user specfic. Did you check this?

#

We are using latest store kit 2 and so far it's the version that's recommended by Apple.

#

However, the error seems to be an issue on the user end.

stone elk
#

Thank you very much for the information.
We will ask the user to check their relevant settings.

The reason we raised this question is because, based on the user's Firebase logs, we found a successful payment record.
So we didn’t initially consider it to be an issue with the user’s settings.

bronze stratus
#

I see. No worries. Will keep this thread open. Please post here once you have an update.

stone elk
#

We have another question.

On the Android platform, some users have reported receiving the following message when attempting to purchase an item:

Transaction Error: {"Domain":"[Essential Kit] Billing Services","Code":11,"Description":"The purchase failed because the item is already owned."}

We would like to confirm:
Does this error code 11 correspond to Android's ITEM_ALREADY_OWNED = 7?
Or is it mapped to a different error code?

Reference:
https://developer.android.com/reference/com/android/billingclient/api/BillingClient.BillingResponseCode#NETWORK_ERROR()

bronze stratus
#

ProductOwned is 11

#

Yes, it maps to ITEM_ALREADY_OWNED internally.

#

BillingServicesErrorCode is an abstraction to both platforms. so you just need to look into BillingServicesErrorCode.cs for the error codes.

stone elk
#

Got it, thank you very much.🤩
Regarding ITEM_ALREADY_OWNED, we will follow up with the Google Play team to confirm the situation,
as we are quite certain that the player does not have any unfinished purchases.😵‍💫

bronze stratus
#

Ok!

stone elk
#

Hello, I have a few follow-up questions.

When we reached out to Google Play, they suggested checking the following:

  1. During initialization, execute BillingClient.queryPurchasesAsync()
    → May I ask if this should be called after BillingServices.InitializeStore()?

  2. Implement consumeAsync() and ConsumeResponseListener to ensure the user can repurchase later
    → Does BillingServices include an implementation of consumeAsync?
    → Should this be called after BillingServices.FinishTransactions()?

Thank you.🥺

bronze stratus
#

We handle consume internally, automatically.

#

Once you call FinishTransactions, thats when we do internally consume.

#

Just run our BillingServicesDemo scene. I can guide you on what steps to do.

bronze stratus
#

Any update on this?

stone elk
#

After inquiring with Google Play, they indicated that the ITEM_ALREADY_OWNED error occurred because the user’s purchase was not properly consumed.

They suggested implementing Purchases.products:consume to consume the purchase.

On the server side, you should check the consumptionState field returned by the purchases.products.get API to confirm the consumption status.
On the client side, you should use queryPurchasesAsync() to verify whether the purchase has already been consumed before attempting to consume it again.

Additionally, they explained that the ITEM_ALREADY_OWNED error is generally uncommon, and strongly recommended calling queryPurchasesAsync() to identify purchased items that were not successfully consumed, and then calling consumeAsync() again to resolve the issue.

#

I’m currently discussing with our server team.
We’ll first implement a simple API to perform the check, so we can quickly confirm whether this can directly resolve the user’s issue.

bronze stratus
#

Ok let me explain what we do internally so that you have complete context.

  1. When you make a purchase, we send you the billing transaction event
  2. Once the event callback is triggered, we check if the product is consumable - If so we fire consume api internally.
  3. In-case if there is no internet in this situation or consume api fails, the product will be still in the restorable purchases list.
  4. If user opens/restarts app later or tries to purchase another product - We check all restorable purchases and check if any consumable products in it. If so we first consume api again -> This makes sure we handle the consume api for failed attempts earlier. The same we do when intiializing BillingServices as well.

However, if you have manual transaction handling workflow, we expect you to call FinishTransactions once you have any pending Transactions in GetTransactions.

stone elk
#

Got it.
Thank you for the information.

We also expected that if there were any unhandled orders, we would receive pending data when the app was reopened. However, we did not receive any pending order data from the platform or in HandleOnTransactionStateChange. The player's Google Play order data also showed "processed and completed."

Our initial guess was that a version upgrade might have affected the Google Play cache or data flow, which would explain why only a small number of players were affected, not a large group.

Next, we will ask our server team to implement the checking process recommended by Google Play to identify the problematic orders. We will then manually handle these orders and continue to monitor for any future occurrences.

stone elk
#

Hello, I’d like to ask a question.

Is it possible that the result received in
HandleOnTransactionStateChange(BillingServicesTransactionStateChangeResult result)
might differ from the data returned by BillingServices.GetTransactions()?

When receiving the result change in HandleOnTransactionStateChange(BillingServicesTransactionStateChangeResult result),
is it not recommended to use BillingServices.GetTransactions() for order processing?

bronze stratus
#

Is it possible that the result received in
HandleOnTransactionStateChange(BillingServicesTransactionStateChangeResult result)
might differ from the data returned by BillingServices.GetTransactions()?
I just double checked - They rely on same Purchase object. We maintain a list of purchases which are not acknowledged yet (we ack only after you call finish transactions - as you have disabled auto finish transactions)

stone elk
#

Hello, sorry to bother you again.🥺

We are currently using version 3.2.1, and the latest version is 3.5.0.
Although I have already checked the release notes, I would like to double confirm:
Were there any adjustments related to FinishTransactions or consume between versions 3.2.1 and 3.5.0?

bronze stratus
#

There are no changes related to this workflow but I would highly recommend to upgrade to 3.5.0 as it uses latest billing client.

#

Also, would recommend to upgrade in a clone to try

stone elk
#

Thank you very much for your help in confirming.

I’d like to ask, when you mention the billing client, does it mean that there were adjustments to the workflow, or changes to the underlying architecture integration?

I want to evaluate the main differences before adjusting our development schedule (to avoid our QA team being overwhelmed during Christmas).

bronze stratus
#

No changes in workflow. Just internal library version changes only.

stone elk
#

Got it 👍
thank you very much for the suggestion. 🤩
We’re planning to roll out the update after the Mid-Autumn Festival (roughly after October).

bronze stratus
#

By that time you will have 3.6.0 with v8 billing client - It's possible to show offers for consumables/non-consumables too!

stone elk
#

Hello, I’d like to report our latest handling approach.🥳

We’ve updated our flow so that the server now performs the consume operation at the time of verification.
On the client side, FinishTransactions also triggers the consume process via VoxelBusters.

This allows us to achieve double verification on both frontend and backend.

We’ve already confirmed with Google Play that the error rate has now decreased and stabilized.

Currently, we’re working on upgrading to version 3.5.0,
but we’ve encountered a build error on Xcode for iOS.
I’ll open a new discussion thread to consult with you about that separately.

Thanks again for all your help! 🤩

stone elk
#

Hi, I would like to check something regarding the following item in the release notes:

[Fix] Fixed consuming orphan/stuck transactions in edge cases [Billing Services][Android]

May I confirm whether this fix is related to the issue I encountered previously where:

The user’s purchase was not properly consumed,

Which resulted in the ITEM_ALREADY_OWNED error?

If this fix addresses the same underlying problem, I would also like to clarify:

After updating to 3.6.1,
➡️ Will previously unconsumed transactions (from older versions) be automatically processed and consumed correctly?
or
➡️ Does the fix only apply to newly created transactions after upgrading to 3.6.1?

Thank you!

bronze stratus
stone elk
#

Ah, sorry — I was referring to the fix in 3.6.0, not 3.6.1.

[Fix] Fixed consuming orphan/stuck transactions in edge cases [Billing Services][Android]

I accidentally wrote the wrong version earlier.

bronze stratus
#

ok. Before answering that, I want to know if you have used promo codes redemption earlier?

stone elk
#

Never.