Search Unity

Google payments are being automatically refunded.

Discussion in 'Unity IAP' started by besttopjoong1, Jan 4, 2021.

  1. JeffDUnity3D

    JeffDUnity3D

    Joined:
    May 2, 2017
    Posts:
    14,446
    Yes, good catch and is likely the cause.
     
  2. roointan

    roointan

    Joined:
    Jan 8, 2018
    Posts:
    78
    Please refer to this URL:
    https://developer.android.com/google/play/billing/integrate#pending

    "To enable pending purchases, call enablePendingPurchases() as part of initializing your app."

    Can we disable pending purchases for Unity IAP in any way?
    I prefer to have it disabled until it's available in a reliable and non-exploitable manner.

    (And why does Google call it pending purchases :( )
     
    Last edited: Mar 15, 2021
  3. JeffDUnity3D

    JeffDUnity3D

    Joined:
    May 2, 2017
    Posts:
    14,446
    No, we already checked. It is required. Do you have the deferred callback? What exploit are you seeing? Have you implemented the deferred listener?
     
  4. roointan

    roointan

    Joined:
    Jan 8, 2018
    Posts:
    78
  5. JeffDUnity3D

    JeffDUnity3D

    Joined:
    May 2, 2017
    Posts:
    14,446
    The exploit is when the developer has a "Please wait" dialog up, waiting on ProcessPurchase and the user exits the app (is my understanding) with the dialog up. So if you receive the deferred callback, you know not to display the message. This should bypass the exploit. If you have no such dialog, my suspicion is users are legitimately attempting a deferred purchase but then not paying in the 3 days allowed. In addition to the Consume checkbox mentioned previously, if you are using Codeless.
     
  6. unity_aratnon

    unity_aratnon

    Joined:
    Nov 15, 2017
    Posts:
    2
    I didn't touch Unity IAP for years (didn't update the code or update the version of the library), but recently I got a warning from Google to update the billing library to version 3. So, I decided to update In App Purchasing to 3.0.2. After releasing my game with this In App Purchasing version, I got the auto refund problem.

    I came to this thread and saw @JeffDUnity3D replied that In App Purchasing 2.2.2 and Unity IAP 2.2.7 should fix this problem. I downgraded the library to these version and I'm still waiting to see the result, but I'm not that confident about it though.
     
  7. JeffDUnity3D

    JeffDUnity3D

    Joined:
    May 2, 2017
    Posts:
    14,446
    If you are using Codeless, ensure that you select the Consume checkbox for the IAP Button property in the Inspector. Also, please provide your device logs. Place Debug.Log statements throughout your purchasing code to follow your logic, they will show in the device logs https://forum.unity.com/threads/how-to-capturing-device-logs-on-android.528680/ . And "waiting to see the result", what are you waiting on?
     
  8. myrodin

    myrodin

    Joined:
    May 4, 2018
    Posts:
    5
    I'm back.

    Recently, while uploading the Unity version, the App Purchasing library version was also uploaded.
    - Unity 2021.1.4f1
    - App Purchasing library 3.1.0

    In the 3.x version, it was stated in the manual that the Unity IAP (Asset Store plugin) should be deleted, so the Assets/Plugins/UnityPurchasing folder was removed. After updating to this state, the automatic refund problem started to occur again.

    The package manager indicated the recommended version of In App Purchasing as 3.0.2. Is there any problem with this version? It is difficult to test the game in service again, so I think I will have to lower the version of the library again right now.
     
  9. JeffDUnity3D

    JeffDUnity3D

    Joined:
    May 2, 2017
    Posts:
    14,446
    Without steps to reproduce, the device logs, or seeing your code, unfortunately there isn't much I can suggest. It works correctly in the Sample IAP Project v2 https://forum.unity.com/threads/sample-iap-project.529555/#post-6950270
     
  10. Iap2017User

    Iap2017User

    Joined:
    May 20, 2019
    Posts:
    1
    I am using IAP 2.2.7, and I'm experiencing an issue in testing where if I do a "Slow test card. Declines after a few minutes" purchase and exit the app (by closing it normally). When I re-enter the app my profile gets credited with the currency from the purchase that should have failed whether or not I wait 5-10 minutes before exiting the application. The products I am testing purchasing with are set to be consumable.

    My intended result from this test purchase is to have no money charged and no currency granted.

    I have also found that if I'm to try and get a purchase receipt at the time of the deferred purchase listener it either comes back as " " or a previously successful.
     
  11. JeffDUnity3D

    JeffDUnity3D

    Joined:
    May 2, 2017
    Posts:
    14,446
    Yes, this looks to be a Google issue, slow decline does not look to work correctly.
     
  12. AppneticSoftware

    AppneticSoftware

    Joined:
    Jul 17, 2021
    Posts:
    2
    Hey JeffDUnity3D,

    I got the same 72Hour Non Consumable Problem as discussed above.
    I ve checked on all things (Inspector - Consume Product Check Box is Checked, Automatically Init UnityPurchasing is checked)

    Here is my code: (did I missed something in order for Google to recognize that the user received the non consumable)

    Code (CSharp):
    1. public void onPurchaseComplete(Product product)
    2.     {
    3.         if (product.definition.id == adFree)
    4.         {
    5.             //remove ads
    6.             PlayerPrefs.SetInt("adFree", 1);
    7.             PlayerPrefs.Save();
    8.             PurchaseCompleted();
    9.  
    10.         }
    11.         else
    12.         {
    13.             Debug.Log("Shouldnt be visiable ");
    14.  
    15.         }
    16.     }
    17.  
    18.     public void onPurchaseFailed(Product product, PurchaseFailureReason reason)
    19.     {
    20.         Debug.Log("Purchase Failed: " + reason);
    21.     }
    22.  
    23.     private void DisableRestoreBtn()
    24.     {
    25.         if (Application.platform != RuntimePlatform.IPhonePlayer)
    26.         {
    27.             restoreBtn.SetActive(false);
    28.         }
    29.     }
    30.  
    31.     private void PurchaseCompleted()
    32.     {
    33.         buyBtn.SetActive(false);
    34.         thankYouText.gameObject.SetActive(true);
    35.         if (Application.systemLanguage == SystemLanguage.German)
    36.         {
    37.             thankYouText.text = "Danke für den Kauf!";
    38.         }
    39.     }
    upload_2021-8-17_9-22-14.png
     
  13. JeffDUnity3D

    JeffDUnity3D

    Joined:
    May 2, 2017
    Posts:
    14,446
    Yes, we've heard similar reports with Codeless, I believe we may have a bug, it hasn't been properly updated in some time. I would recommend instead to use Scripted IAP like in the Sample IAP Project v2
     
  14. AppneticSoftware

    AppneticSoftware

    Joined:
    Jul 17, 2021
    Posts:
    2
    ok I will do so, thanks for fast reply. In Case you know that the bug is fixed - please reply to this answer.
    Thanks a lot and have a nice day!
     
  15. Hansel41

    Hansel41

    Joined:
    Mar 15, 2020
    Posts:
    10
    I have the same exact problem @JeffDUnity3D all the purchases got refunded after 3 days automatically, I'm using the latest IAP and those products are marked as consumable in the codeless IAP. But the other problem here is may be related that I'm not able to buy the consumable products again as google play billing shows that i already own this product. and I'm overall confused. Please Help.
     
  16. PeachyPixels

    PeachyPixels

    Joined:
    Feb 17, 2018
    Posts:
    704
    Hi @JeffDUnity3D,

    I was testing Google Play purchases yesterday and accidently came across this 'issue' by instigating a slow credit card purchase then quitting my app (whilst a wait ui was showing)

    I assumed that if I purchased, then closed the app then waited (say 10 minutes) the ProcessPurchase method would be called when initialising IAP (the next time the app was restarted) but that didn't appear to happen.

    Should it have? Or should I be checking transactions\receipts on init and activating in-game content as well?

    What was received was an mail from Google (after 5 minutes) saying...

    This test purchase was cancelled because it was not acknowledged. You should ensure that all purchases are acknowledged so that they are not subject to refunds. For more information, see https://developer.android.com/google/play/billing/integrate#process

    So after a little investigation, I saw this thread and realised the deferred listener has not been implemented, which I'm just doing now.

    Are you saying that best practice is to close the waiting ui? Or warn users that the purchase is slow and to wait?

    PS: This is using scripted Unity IAP 3.2.3
     
  17. JeffDUnity3D

    JeffDUnity3D

    Joined:
    May 2, 2017
    Posts:
    14,446
    You cannot close the waiting UI, that is a system dialog. And warn which users, you mean your testers using the slow credit card option? You would not know the credit card was "slow". Are you seeing the deferred listener being called?
     
  18. PeachyPixels

    PeachyPixels

    Joined:
    Feb 17, 2018
    Posts:
    704
    Thanks Jeff.

    Yes sorry, I meant the game (purchase) ui.

    It looks like I wasn't handling the GoogleReceipt.purchaseState == 4 correctly in ProcessPurchase (receipt validation). But implemented both listener and state check now and looks like all is working as expected on an internal test track.

    Is it under consideration to push requirements like these (purchaseState == 4) to the Unity API by any chance? It would certainly help us devs greatly.

    I've just seen Unity IAP V4 which appears to have a huge number of improvements\changes, some along those lines. So maybe it already has been.
     
  19. JeffDUnity3D

    JeffDUnity3D

    Joined:
    May 2, 2017
    Posts:
    14,446
    We are still discussing purchaseState = 4 handling
     
    PeachyPixels likes this.
  20. PeachyPixels

    PeachyPixels

    Joined:
    Feb 17, 2018
    Posts:
    704
    I've just been working through deferred purchases on iOS and as far as I can tell, Apple's billing system doesn't call ProcessPurchase until the transaction has completed (i.e. monies received). Which makes more sense to me.

    So if it were possible, Unity IAP supressing the ProcessPurchase call for Google (when the state is deferred - 4) until it's completed (1?) would get a vote from me.

    That way we just need to handle the deferred payment message in the deferred purchase event and that's it. It's a simpler and more consistent approach.

    Anyway, that's just my two cents worth :)
     
    Voxel-Busters likes this.
  21. JeffDUnity3D

    JeffDUnity3D

    Joined:
    May 2, 2017
    Posts:
    14,446
    That's actually a good idea. But keep in mind that developers are already coding for the current flow and such changes would break their flow. To be clear, that is not a "good reason" to keep it as it is! We have been discussing this and similar issues here, and how to best handle it.
     
    PeachyPixels likes this.
  22. PeachyPixels

    PeachyPixels

    Joined:
    Feb 17, 2018
    Posts:
    704
    Thanks @JeffDUnity3D

    That's a fair point.

    But assuming developers are checking either purchaseState == 4 or using IsPurchasedProductDeferred then I don't believe it will break that workflow. In-effect that code will never end up being called. Unity IAP will intercept (set the state to pending) then discard the ProcessPurchase and call the deferred event.

    Anyway, appreciate that you have it under consideration whatever the resolution. Thank you :)
     
  23. JeffDUnity3D

    JeffDUnity3D

    Joined:
    May 2, 2017
    Posts:
    14,446
    In your example, developers would never see purchaseState = 4. But agreed, I guess the code wouldn't break, it would just never be called.
     
  24. Voxel-Busters

    Voxel-Busters

    Joined:
    Feb 25, 2015
    Posts:
    1,963
    We do exactly the same in our plugin's IAP billing feature. This is to match with iOS and no doubt, this suggestion is a great one to have.
     
    PeachyPixels likes this.
  25. wechat_os_Qy03mMbtRbKS5D_ob_YZXDWBg

    wechat_os_Qy03mMbtRbKS5D_ob_YZXDWBg

    Joined:
    Jan 19, 2022
    Posts:
    1
    there is any solution for purchaseState = 4 now?
     
  26. Baroni

    Baroni

    Joined:
    Aug 20, 2010
    Posts:
    3,260
    The solution is to check the state in the ProcessPurchase method and do nothing when the Google receipt's purchaseState value = 4.
     
    Arnaud_Gorain likes this.
  27. QcyqApps

    QcyqApps

    Joined:
    Jun 12, 2020
    Posts:
    2
    @JeffDUnity3D is this fixed in 4.6.0 codeless implementation? Im facing this issue in my new game rn... Can you imagine the loss of income this generates? It's not funny on this level of app development.
     
  28. Arnaud_Gorain

    Arnaud_Gorain

    Unity Technologies

    Joined:
    Jun 28, 2022
    Posts:
    182
    Hi @QcyqApps,
    There is no other work related to this included in 4.6.0, the current solution is still:
     
  29. QcyqApps

    QcyqApps

    Joined:
    Jun 12, 2020
    Posts:
    2
    Thank you agorain. I need to check it, but what if the state value is not equal to 4?
    And what exactly means this 4 and other states? There is any docs for this?
     
  30. Arnaud_Gorain

    Arnaud_Gorain

    Unity Technologies

    Joined:
    Jun 28, 2022
    Posts:
    182
    Hi,
    Purchase state is to specify the purchase state of the order.
    You can find the android doc here.

    The purchase state of the order. Possible values are: 0. Purchased 1. Canceled 2. Pending
    4 is meant for "Deferred" purchases.
     
  31. PeachyPixels

    PeachyPixels

    Joined:
    Feb 17, 2018
    Posts:
    704
    FWIW

    It looks like Unity has finally addressed this 'issue' in 4.6.0, from the changelog...
    • GooglePlay - `Deferred` purchases are, by default, no longer sent to `IStoreListener.ProcessPurchase` when fetching purchases. This avoids the possibility of granting products that were not paid for. These purchases will only be processed once they become `Purchased`. This can be reverted with `IGooglePlayConfiguration.SetFetchPurchasesExcludeDeferred(bool exclude)` to not exclude them, but `Deferred` purchases will need to be handled in `IStoreListener.ProcessPurchase`.
    I've not tested this though.

    But it also looks like 4.6.0 has a number of breaking changes, so it's worth being mindful of that.
     
  32. PortalArcher

    PortalArcher

    Joined:
    Sep 9, 2020
    Posts:
    8
    I just lost ~1000$ value of automatically refunded items. Shame. Still figuring out what happened, but I guess it's Unity.
     
  33. PortalArcher

    PortalArcher

    Joined:
    Sep 9, 2020
    Posts:
    8
    False alarm. Issue was - if right after transaction happens error, IAP can't tell bank that item was successfully bought. And it causes refund.
     
    Last edited: Aug 2, 2023
    muhammad_ali_safdar likes this.