Search Unity

  1. Welcome to the Unity Forums! Please take the time to read our Code of Conduct to familiarize yourself with the forum rules and how to post constructively.
  2. Dismiss Notice

Question Determining if "Payment Pending" - Google Play

Discussion in 'Unity IAP' started by andrew210, Jan 18, 2022.

  1. andrew210

    andrew210

    Joined:
    Apr 23, 2014
    Posts:
    241
    I have noticed recently a number of our users "buying" all consumable items in the game possible (one of each package available) via google play. On checking these transactions, it appears the same pattern everytime, in google play they show as "Payment Pending" for a couple of hours, and then "Cancelled". What is the proper way to catch this behaviour via Unity IAP. A valid receipt is in place and i can store this and check it against the google transaction, but I can't find what I can do in: "

    public PurchaseProcessingResult ProcessPurchase(PurchaseEventArgs e)"

    to see that their payment is invalid and the only action i can take is to ban the user once I notice them systematically cheating the system.
     
  2. JeffDUnity3D

    JeffDUnity3D

    Unity Technologies

    Joined:
    May 2, 2017
    Posts:
    14,446
    You should be able to parse the receipt via e.purchasedProduct.receipt and specifically look for purchaseState. You shouldn't need to ban them, when properly coded you would simply not award the product to the user.
     
  3. andrew210

    andrew210

    Joined:
    Apr 23, 2014
    Posts:
    241
    Perfect, thank you
     
  4. andrew210

    andrew210

    Joined:
    Apr 23, 2014
    Posts:
    241
    Code (CSharp):
    1. {"Payload":"{\"json\":\"{\\\"orderId\\\":\\\"GPA.XXXX-XXXX-2614-76916\\\",\\\"packageName\\\":\\\"me.blueomega.horseisland\\\",\\\"productId\\\":\\\"me.blueomega.horseisland.ads600\\\",\\\"purchaseTime\\\":1642241497252,\\\"purchaseState\\\":4,\\\"purchaseToken\\\":\\\"XXXXXXdebgafldpolfmdpbgg.AO-J1Ox-ulWzD65MZiqmBRJuNDxGqwZt1MZtvxmm0N7-J4g7aFe5tEuZlH0jiooTwGm7wOHKnTT0UPbHaTq1OumPc-dDCVzl4kkwvREMbeFPIcVweDPgWt0\\\",\\\"acknowledged\\\":false}\",\"signature\":\"XXXXBFI2/w3lrTSGmO146Q1OBlTYnoh34HP7G2NthMZWRdAIKgkyo1Vt3p7AyQEadT5HqjcwPxZsKOjRFK/30/TVv2SnVj4/iMb70YSreSuTceIDXOIFFJn7e+J4NaAyguLTTuw8Ys3gyEfrr0jZRe0H7PL5+3apyRBKUOaYOtwTxD3yDC5HP5siRps6DQp0eSugntMn2tCRXWFvXAZTP02PNQAKFQT33S0y6I+XhRuhidA/WnuYTF7t/i+YfNDs0u8d+8jATUuWv1bAyRcPpAh5KukjvYAmyAq7RaqeWWpo6JLrmOC+r3G2KNCGJXQp7X/0azIopYlVw1AVmxPSgQ==\",\"skuDetails\":\"{\\\"productId\\\":\\\"me.blueomega.horseisland.ads600\\\",\\\"type\\\":\\\"inapp\\\",\\\"title\\\":\\\"600 Academy Dollars (Horse Academy - Equestrian MMO)\\\",\\\"name\\\":\\\"600 Academy Dollars\\\",\\\"price\\\":\\\"Rp\\u00a0690.000,00\\\",\\\"price_amount_micros\\\":690000000000,\\\"price_currency_code\\\":\\\"IDR\\\",\\\"description\\\":\\\"A package featuring 600 Academy Dollars for using in Horse Academy.\\\",\\\"skuDetailsToken\\\":\\\"AEuhp4L0ZPbaF-gB1DfcM317F0aoA0CzsA6C2anL-uP5IppjSuTgfhXTEq8shoHbSuKp\\\"}\"}","Store":"GooglePlay","TransactionID":"XXXXXdebgafldpolfmdpbgg.AO-J1Ox-ulWzD65MZiqmBRJuNDxGqwZt1MZtvxmm0N7-J4g7aFe5tEuZlH0jiooTwGm7wOHKnTT0UPbHaTq1OumPc-dDCVzl4kkwvREMbeFPIcVweDPgWt0"}
    Looking at the receipts for those people who have exploited this in the game, its hard to tell exactly which part of the receipt is the correct one, I looked at "purchaseState" but that appears to be 4 in this - which is not an expected value here: https://developer.android.com/reference/com/android/billingclient/api/Purchase.PurchaseState
     
  5. JeffDUnity3D

    JeffDUnity3D

    Unity Technologies

    Joined:
    May 2, 2017
    Posts:
    14,446
    Yep, that is a deferred purchase, not documented by Google yet. Only award the product when purchaseState = 1 (Purchased). Deferred purchases are a new purchase option by Google that allows the user to buy in-app products in the game, and then they have 3 days to pay at a physical store approved by Google or the transaction is cancelled if they don't pay. You don't want to ban these users, it's a legitimate purchase option. More information here https://forum.unity.com/threads/google-play-iap-problem.1140367/#post-7351220
     
    andrew210 likes this.
  6. andrew210

    andrew210

    Joined:
    Apr 23, 2014
    Posts:
    241
    Perfect, can't tell you how much I appreciate the speed of response you've given me here, thank you so much for your help.
     
    JeffDUnity3D likes this.
  7. andrew210

    andrew210

    Joined:
    Apr 23, 2014
    Posts:
    241
    Also just read what you said about not wanting to ban these users, the two main culprits had repeatedly done this and ended up with the payment status being "Cancelled" each time and ended up "making" payments over over a few thousand dollars that were never honored. Don't worry if any doubt I would attempt to reach out to the players first!
     
  8. JeffDUnity3D

    JeffDUnity3D

    Unity Technologies

    Joined:
    May 2, 2017
    Posts:
    14,446
    Can you describe how a payment is made but not honored? What was the payment method? Or do you mean they were never paid and all of them eventually were cancelled. It could be hackers attempting to see if you handle deferred purchases or (incorrectly) award the product. Once you handle this scenario, there is no need to ban users. How would you ban an individual user as you suggest? (for my own information)
     
  9. andrew210

    andrew210

    Joined:
    Apr 23, 2014
    Posts:
    241
    Heres the activity for one such player. Its suspicious behavior in that they buy every possible hard currency package once each, then repeat again a few days later or after they move into it being cancelled.

    As for banning the user, its an MMO so I just put their account on hold and give the user a chance to message me to explain what they're up to. Either way it seems a simple fix now of checking that receipt before awarding the product!

     
    Alima-Studios and JeffDUnity3D like this.
  10. Alima-Studios

    Alima-Studios

    Joined:
    Nov 12, 2014
    Posts:
    78
    I have a lot of this users too , help !
     
  11. JeffDUnity3D

    JeffDUnity3D

    Unity Technologies

    Joined:
    May 2, 2017
    Posts:
    14,446
    Have you confirmed these are not deferred purchases? Please share the code where you are checking the receipt or calling the extension method IsDeferredPurchase. There are indeed cheat apps out there that can fake a receipt. Server-side receipt validation is the best defense against this.
     
  12. aubreypuan

    aubreypuan

    Joined:
    Mar 30, 2017
    Posts:
    9
    Happened to me too, I confirmed they didn't moded the app nor deferred the purchases, a player showed me how they did it to other games

    A lot of players especially in Indonesia exploited this.
    This is what I tried to do to prevent the exploit, let's see how it goes
    Code (CSharp):
    1. public PurchaseProcessingResult ProcessPurchase(PurchaseEventArgs args)
    2.     {
    3.         bool validPurchase = true; // Presume valid for platforms with no R.V.
    4.  
    5.         // Unity IAP's validation logic is only included on these platforms.
    6. #if UNITY_ANDROID || UNITY_IOS || UNITY_STANDALONE_OSX
    7.         // Prepare the validator with the secrets we prepared in the Editor
    8.         // obfuscation window.
    9.         var validator = new CrossPlatformValidator(GooglePlayTangle.Data(),
    10.             AppleTangle.Data(), Application.identifier);
    11.  
    12.         try
    13.         {
    14.             // On Google Play, result has a single product ID.
    15.             // On Apple stores, receipts contain multiple products.
    16.             var result = validator.Validate(args.purchasedProduct.receipt);
    17.             // For informational purposes, we list the receipt(s)
    18.             // Debug.Log("Receipt is valid. Contents:");
    19.             foreach (IPurchaseReceipt productReceipt in result)
    20.             {
    21.                 Debug.Log(productReceipt.productID);
    22.                 Debug.Log(productReceipt.purchaseDate);
    23.                 Debug.Log(productReceipt.transactionID);
    24.                 if (productReceipt is GooglePlayReceipt google)
    25.                 {
    26.                     switch (google.purchaseState)
    27.                     {
    28.                         case GooglePurchaseState.Cancelled:
    29.                             Debug.Log("Canceled");
    30.                             validPurchase = false;
    31.                             break;
    32.                         case GooglePurchaseState.Refunded:
    33.                             Debug.Log("Refunded");
    34.                             validPurchase = false;
    35.                             break;
    36.                     }
    37.                     if ((int)google.purchaseState == 4)
    38.                     {
    39.                         Debug.Log("Pending");
    40.                         return PurchaseProcessingResult.Pending;
    41.                     }
    42.                 }
    43.  
    44.             }
    45.         }
    46.         catch (IAPSecurityException)
    47.         {
    48.             Debug.Log("Invalid receipt, not unlocking content");
    49.             validPurchase = false;
    50.         }
    51. #endif
    52.  
    53.         if (validPurchase)
    54.         {
    55.             processPurchaseComplete(args.purchasedProduct.definition.id, args.purchasedProduct.receipt);
    56.         }
    57.         return PurchaseProcessingResult.Complete;
    58.     }
     
  13. Kofiro

    Kofiro

    Joined:
    Feb 3, 2017
    Posts:
    29
    Hello, how did it go? @aubreypuan

    I also have a lot of pending purchases as well as cancelled ones.
     

    Attached Files: