Search Unity

IAP failed purchase, but it actually went through on google play

Discussion in 'Unity IAP' started by mrm83, Sep 15, 2020.

  1. mrm83

    mrm83

    Joined:
    Nov 29, 2014
    Posts:
    345
    We are noticing a problem where google iap validation is failing.
    Some of these transactions were already processed days or weeks ago but showing up again, some of these transactions were new and never processed.

    Seems to be happening here.. google.packageName is blank:
    Code (CSharp):
    1.      
    2. var validator = new CrossPlatformValidator(GooglePlayTangle.Data(), AppleTangle.Data(), Application.identifier);
    3.         try {
    4.             var result = validator.Validate(args.purchasedProduct.receipt);
    5.             foreach (IPurchaseReceipt productReceipt in result) {
    6.                 GooglePlayReceipt google = productReceipt as GooglePlayReceipt;
    7.                 if (null != google) {
    8.        ---->         if (!String.Equals(google.packageName, Application.identifier, StringComparison.Ordinal)) {
    9.  
    Unity 2019.4.8f1 IAP 1.23.4

    Is this a known issue?
     
    Last edited: Sep 15, 2020
  2. SamOYUnity3D

    SamOYUnity3D

    Unity Technologies

    Joined:
    May 12, 2019
    Posts:
    626
    I didn't see this problem, could you be able to reproduce it? Could you provide reproduction steps and the device logs? Thanks.
     
  3. mrm83

    mrm83

    Joined:
    Nov 29, 2014
    Posts:
    345
    Can't reproduce. This is found in our production logs.. Happening quite frequent.
     
  4. SamOYUnity3D

    SamOYUnity3D

    Unity Technologies

    Joined:
    May 12, 2019
    Posts:
    626
    OK, do you have any device logs available?
     
  5. mrm83

    mrm83

    Joined:
    Nov 29, 2014
    Posts:
    345
    No device logs.

    Only have the transaction's receipt data.
     
  6. JeffDUnity3D

    JeffDUnity3D

    Joined:
    May 2, 2017
    Posts:
    14,446
    We would need specific steps to reproduce before we could take any action, thanks.
     
  7. mrm83

    mrm83

    Joined:
    Nov 29, 2014
    Posts:
    345
    I don't know how to reproduce it, but I have reproduced it. This seems to occur after reinstalling / rebuilding the app.

    Unity IAP is printing out this in the logs:
    Already recorded transaction {the transaction's token}

    Searched some threads and this is for restoring purchase.
    The purchase is consumable, why is it trying to restore it?
    Even if it does try to restore it, why is the transid the token and not the trans id and why is the packageName from receipt missing?
     
    Last edited: Sep 25, 2020
  8. JeffDUnity3D

    JeffDUnity3D

    Joined:
    May 2, 2017
    Posts:
    14,446
    In your code, do you ever return Pending from ProcessPurchase? And when you say "new and never processed", can you elaborate? How could a transaction be new yet never processed? We have made changes in this area, I will check with the team here.
     
  9. mrm83

    mrm83

    Joined:
    Nov 29, 2014
    Posts:
    345
    Yes, all purchases are returned pending during ProcessPurchase.
    Once our server validates the purchase, it is marked completed via m_StoreController.ConfirmPendingPurchase(Product).

    We have received user complaint that purchase was not granted. We looked up our purchase log and noticed that this issue happened. there was no GPA transaction id and only the token was returned as the transId. We looked up the date/time from this log on Google Play and the purchase was successful (while it failed on client).
    The above only happened a few times.

    The other cases appears to be from reinstall (what I just reproduced)
     
  10. JeffDUnity3D

    JeffDUnity3D

    Joined:
    May 2, 2017
    Posts:
    14,446
    Are you watching for ProcessPurchase calls during IAP initialization? Are you saying that we now incorrectly intercept the pending transactions and ProcessPurchase is never fired during IAP initialization? Where is your ConfirmPendingPurchase code? For products still left in Pending, I would expect ProcessPurchase to be automatically called during IAP initialization for each of those products. You mentioned this is for evidence of attempting to restore a consumable, but also said the user didn't receive the product (a restore only happens after a successful purchase). So those don't seem consistent. I believe you are assuming restore for consumable just by the log entries, we should go by actual behavior instead. You'll want to ensure to place Debug.Log statements in all your IAP callbacks, which will show in the device logs during your testing. One thing to test is cancelling the purchase for a product (dismiss the purchase dialog), then try restarting the app. Monitor ProcessPurchase during IAP initialization via Debug.Log or step debugging from Visual Studio. Then also try reinstalling the app. We have heard reports that cancelled purchases may leave behind a pending transaction.
     
    Last edited: Sep 25, 2020
  11. mrm83

    mrm83

    Joined:
    Nov 29, 2014
    Posts:
    345
    All I am saying is that there is an issue where transactions are failing with no transaction id and the packagename is missing from receipt data when the actual purchase is SUCCESSFUL from Google Play. I reproduced this once accidentally just now by reinstalling the app (issue#1) and from user report (issue#2).

    Issue #1 (happening few times a day):
    Our server log shows failing IAP purchase because the package is null from the receipt data. (This is from the receipt code sample i provided above).
    These transactions DOES NOT have a transaction id (GPA.xxxx.xxxx.xxxx.xxxx) but instead have the token. I tried looking up some of these transactions on google play and the token is valid . All these transactions were in the past.
    I am suspecting these are from reinstalls as our database already have record of these transaction and because I have just reproduced this 40 minutes ago when the app was reinstalled from editor build and the purchase was from 2 weeks ago.

    Looked up one of the failing transaction and found this:
    13 Sep 2020 | 21:52:03,251 - user purchased, validates
    13 Sep 2020 | 21:58:54,853 - the transaction appears again in ProcessPurchase but without package in receipt, and the transaction id is missing.
    25 Sep 2020 | 11:49:02,787 - the same transaction appears again in ProcessPurchase but without package in receipt, and the transaction id is missing.
    All 3 instances, the transactions were marked completed. The first by our server call to ConfirmPendingPurchase. The 2nd and 3rd by return PurchaseProcessingResult.Complete; in ProcessPurchase due to exception.

    Issue #2 (rare):
    Users made purchase, never received it. Contacted our support team.
    We dug our server logs for purchase and found a matching failed purchase from the user's provided purchase time/date.
    This failed purchase DOES NOT have a transaction ID (GPA.xxxx) but instead have a token.
    Looked up the timestamp on google play and matched the token of failed purchase, the purchase was successful.
    This issue did not involve reinstalling.

    Code:
    All transactions that come into ProcessPurchase will be marked pending. The transaction data is sent to our server for validation and the client receives a callback from our server which marks the transaction as completed. ConfirmPendingPurchase is else where in the class and is triggered by our server code.

    Have already tested cancel, it behaves correctly, and no pending transactions.
     
    Last edited: Sep 25, 2020
  12. JeffDUnity3D

    JeffDUnity3D

    Joined:
    May 2, 2017
    Posts:
    14,446
    So when you say "failed purchase", it's because your server fails to validate the receipt, correct? I'm not clear in your #1, how could a purchase fail today if it was done 2 weeks ago? It was successful then, correct? Sorry if I'm not quite following. I'm guessing this is a restore that is failing? If so, you should be able to reproduce with 2 devices with the same account. Can you just ignore those transactions that have a blank package and not try to verify? You are aware that Google automatically restores purchases on reinstall.
     
  13. mrm83

    mrm83

    Joined:
    Nov 29, 2014
    Posts:
    345
    failed purchase = client failed to validate because receipt DOES NOT have package name.

    When I say "failed purchase", this is client failing to validate. All the transactions were successful in terms of payment.
     
  14. mrm83

    mrm83

    Joined:
    Nov 29, 2014
    Posts:
    345
    Can you just ignore those transactions that have a blank package and not try to verify?
    That is what we've been doing. Ignoring it. Until we get complaint for missing purchase (issue #2).

    If unity don't think this is an issue or it is a code issue on our side, thats fine.
    I only created this ticket to see if this is happening to other issues and potentially report it as a bug.
     
  15. mrm83

    mrm83

    Joined:
    Nov 29, 2014
    Posts:
    345
    I just noticed this in the IAP update. Our IAP version is 1.23.4, what does this note actually mean?

    ## [1.23.4] - 2020-07-13
    ### Added
    - Security - Supports receipts from GooglePlay which omit `packageName`. These as are seen from v1.23.2's purchase-recovery features.
    - The purchasing receipt's `packageName` is omitted by a GooglePlay historical purchase query APIs used by v1.23.2. When the RSASSA-PKCS1-v1_5 signature is valid and the receipt's `packageName` is not included, the `appBundleId` / `googleBundleId` input into `UnityEngine.Purchasing.Security.CrossPlatformValidator` is ignored. To avoid replay attacks we encourage developers continue heuristically scrutinizing the returned `purchaseTime` and `productId` values found in decoded receipts.

    Is this update the cause from what I am seeing with some of our purchases?
     
    JeffDUnity3D likes this.
  16. JeffDUnity3D

    JeffDUnity3D

    Joined:
    May 2, 2017
    Posts:
    14,446
    I discussed this with the IAP team today, and there does look to be a potential issue and is actively being worked on. I think we can expect an update sometime next week. In particular, some issues with the new aggressively recover lost purchases flag. We also plan to implement a consistent transaction identifier.
     
  17. mrm83

    mrm83

    Joined:
    Nov 29, 2014
    Posts:
    345
    I dug deeper into the same transaction I posted earlier and checked a couple more and here are my findings:

    Seems like this was the use case.
    Device A makes a purchase, ProcessPurchase returns pending. Transaction never got marked as completed and the device quitted the app. (our server receives the transaction with transid, and everything and purchase credited)

    Device B logs in to the same account, and the purchase from Device A gets restored. (our server receives the transaction saying it is an error because it is missing packagename and transid) <-- ISSUE#1

    Device A logs in to the same account again some time later ie: days, weeks, months, and the purchase gets restored. (our server receives the transaction saying it is an error because it is missing packagename and transid) <-- ISSUE#1

    The good news about this scenario is the user DOES get the purchase because our server captured it the first time.

    The bad scenario is this:
    Device A makes a purchase, ProcessPurchase returns pending. Transaction never got marked as completed and the device quitted the app before our server receives the purchase transaction.

    Device B logs in to the same account, and the purchase from Device A gets restored. (our server receives the transaction saying it is an error because it is missing packagename and transid) <-- ISSUE#2

    User does not get the purchase, refund happens, user uninstalls the app, leave a rating saying we are fraudster.
     
  18. JeffDUnity3D

    JeffDUnity3D

    Joined:
    May 2, 2017
    Posts:
    14,446
    Thanks for the details! This should help troubleshoot.
     
  19. bmorgan-ksg

    bmorgan-ksg

    Joined:
    Dec 13, 2016
    Posts:
    11
    Is it safe to assume that this issue been addressed in the v2.1.0 release?
     
  20. JeffDUnity3D

    JeffDUnity3D

    Joined:
    May 2, 2017
    Posts:
    14,446
    Well that's a pretty brave statement, but I would encourage you to test! We are making changes in this area.
     
  21. bmorgan-ksg

    bmorgan-ksg

    Joined:
    Dec 13, 2016
    Posts:
    11
    Sorry, I only worded it this way because a previous post of yours seemed to indicate the issue was being actively worked on and a fix would be available in the coming weeks.

    The problem we face is that, similar to the author of this thread, we were only made aware of it after rolling out an update to our production environment and seeing purchase failures caused by malformed/unexpected receipt data in our error logging.

    We've since rolled back to v1.23.1 and my instinct is to stay on this version if changes are still ongoing.
     
  22. JeffDUnity3D

    JeffDUnity3D

    Joined:
    May 2, 2017
    Posts:
    14,446
    Sorry, I misread your question as "has it been fixed" which you can never state with software. To your more general point, yes this latest release addresses the issue. You'll want to test in your scenario to confirm.