Search Unity

  1. Unity 2018.3 is now released.
    Dismiss Notice
  2. The Unity Pro & Visual Studio Professional Bundle gives you the tools you need to develop faster & collaborate more efficiently. Learn more.
    Dismiss Notice
  3. We've updated our Terms of Service. Please read our blog post from Unity CTO and Co-Founder Joachim Ante here
    Dismiss Notice
  4. Want to provide direct feedback to the Unity team? Join the Unity Advisory Panel.
    Dismiss Notice
  5. Improve your Unity skills with a certified instructor in a private, interactive classroom. Watch the overview now.
    Dismiss Notice

UWP, IAP 1.20.1, non-consumable (durable)

Discussion in 'Unity IAP' started by seven_, Jan 8, 2019.

  1. seven_

    seven_

    Joined:
    Sep 30, 2014
    Posts:
    23
    I am working on an UWP version of our app. In-app purchases have generally been setup, a test app version has been published, in-app purchase details are queried for and in-app purchases can (with problems, see below) be bought. So, the setup seems fine.

    When buying a non-consumable (durable), we are calling ConfirmPendingPurchase (as this also needs to be called for non-consumables according to out interpretation of the Unity docs). However, this results in an ServerError (see logs).

    The transaction is then continuously processed by Unity and tried to be fulfilled. This results in another error, as Unity now somehow uses a fake transactionId when fulfilling the transaction (see logs).

    Does anyone have any ideas what is going on? Is this "simply" a bug in UnityIAP?

    As a side note: buying a consumable for the first time works fine. Buying it the seconds time without restarting the app lets Unity deliver this second purchase twice (by calling ProcessPurchase with the ids of the second purchase). This might be related to the non-consumable having a problem, but might be an independent bug as well.

    Here is some shortened log from the non-consumable purchase:

    purchase({0}): IAP_ID
    UnityEngine.Purchasing.PurchasingManager:InitiatePurchase(Product, String)
    UnityEngine.Purchasing.PurchasingManager:InitiatePurchase(String, String)

    UnityIAPWin8: Purchase IAP_STORE_ID status:Succeeded
    UnityEngine.Purchasing.<>c__DisplayClass16_0:<log>b__0()
    System.Action:Invoke()
    UnityEngine.Purchasing.Extension.UnityUtil:Update()

    PURCHASE SUCCEEDED!:{0}: 2
    UnityEngine.Purchasing.<>c__DisplayClass19_0:<OnPurchaseSucceeded>b__0()
    System.Action:Invoke()
    UnityEngine.Purchasing.Extension.UnityUtil:Update()

    Just for your information. The Receipt:
    {"Store":"WinRT","TransactionID":"9a1378c9-a6fd-45d8-b1a2-86d5eae20f93","Payload":"
    <?xml version=\"1.0\"?>
    <Receipt Version=\"2.0\" CertificateId=\"XXX" xmlns=\"http://schemas.microsoft.com/windows/2012/store/receipt\">
    <ProductReceipt PurchasePrice=\"EUR0\" PurchaseDate=\"2019-01-08T08:22:36.301Z\" Id=\"9a1378c9-a6fd-45d8-b1a2-86d5eae20f93\" AppId=\"XXXX\" ProductId=\"IAP_STORE_ID\" ProductType=\"Durable\" PublisherUserId=\"XXX\" MicrosoftProductId=\"XXX\" MicrosoftAppId=\"XXX\" ExpirationDate=\"2019-01-09T08:22:32.817Z\" OfferId=\"\" />
    <Signature xmlns=\"http://www.w3.org/2000/09/xmldsig#\">...</Signature></Receipt>"}

    UnityIAPWin8:Fulfilment result for IAP_STORE_ID - 9a1378c9-a6fd-45d8-b1a2-86d5eae20f93 : ServerError
    UnityEngine.Purchasing.<>c__DisplayClass16_0:<log>b__0()
    System.Action:Invoke()
    UnityEngine.Purchasing.Extension.UnityUtil:Update()

    Unity now tries to fulfil and fulfil:

    UnityIAPWin8:Fake transactionID: Set transactionMap[IAP_STORE_ID] = 190501192
    UnityEngine.Purchasing.<>c__DisplayClass16_0:<log>b__0()
    System.Action:Invoke()
    UnityEngine.Purchasing.Extension.UnityUtil:Update()

    Fulfilling transaction 190501192
    UnityEngine.Purchasing.<>c__DisplayClass16_0:<log>b__0()
    System.Action:Invoke()
    UnityEngine.Purchasing.Extension.UnityUtil:Update()

    (Filename: C:\buildslave\unity\build\Runtime/Export/Debug.bindings.h Line: 45)

    ProductID IAP_STORE_ID
    UnityEngine.Purchasing.<>c__DisplayClass16_0:<log>b__0()
    System.Action:Invoke()
    UnityEngine.Purchasing.Extension.UnityUtil:Update()

    (Filename: C:\buildslave\unity\build\Runtime/Export/Debug.bindings.h Line: 45)

    UnityIAPWin8:Consuming: IAP_STORE_ID
    UnityEngine.Purchasing.<>c__DisplayClass16_0:<log>b__0()
    System.Action:Invoke()
    UnityEngine.Purchasing.Extension.UnityUtil:Update()

    (Filename: C:\buildslave\unity\build\Runtime/Export/Debug.bindings.h Line: 45)

    UnityIAPWin8:Exception consuming IAP_STORE_ID : Guid should contain 32 digits with 4 dashes (xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx). (non-fatal)
    UnityEngine.Purchasing.<>c__DisplayClass16_0:<log>b__0()
    System.Action:Invoke()
    UnityEngine.Purchasing.Extension.UnityUtil:Update()
     
  2. JeffDUnity3D

    JeffDUnity3D

    Unity Technologies

    Joined:
    May 2, 2017
    Posts:
    3,130
    There should be no need to call ConfirmPendingPurchase in your code. You cannot re-purchase a non-consumable, as the name implies.
     
  3. seven_

    seven_

    Joined:
    Sep 30, 2014
    Posts:
    23
    From my understanding of the Unity docs, ConfirmPendingPurchase finishes the transaction and must be called whenever the app finished processing/recording of the purchase. Otherwise, the transaction is delivered again and again.

    Finishing is required for all Apple transactions. For Google Play, UnityIAP decides whether to consume the purchase (for consumables) or not (for non-consumables). This is the reason why UnityIAP gets the ProductType when adding products. It is working fine, as expected, and documented for Google, Amazon, and iOS.

    Not sure why UWP should be any different. We can see what is happening when ConfirmPendingPurchase is not called or results in an error -- the transaction is delivered to the application again and again, as it was not confirmed.
     
  4. JeffDUnity3D

    JeffDUnity3D

    Unity Technologies

    Joined:
    May 2, 2017
    Posts:
    3,130
    No, that is not correct. You return Complete from ProcessPurchase to finish the transaction. ConfirmPendingPurchase is optional, and only needed if you return Pending from ProcessPurchase.
     
  5. seven_

    seven_

    Joined:
    Sep 30, 2014
    Posts:
    23
    Yes, that is correct. We return Pending, as we verify the purchase on our server before. Not sure why this should be triggering the issue I described.

    UPDATE: I can confirm that exactly the same happens (including the log outputs) when skipping our server verification and not calling ConfirmPendingPurchase, and returning Complete instead of Pending.
     
    Last edited: Jan 9, 2019
  6. JeffDUnity3D

    JeffDUnity3D

    Unity Technologies

    Joined:
    May 2, 2017
    Posts:
    3,130
    So you are claiming that ALL IAP transactions on the UWP platform are failing with the error "UnityIAPWin8:Exception consuming IAP_STORE_ID : Guid should contain 32 digits with 4 dashes"? It seems we would have heard from other users as well, if this is the case. Can you share your code? Alternatively, can you test with the sample project here? https://forum.unity.com/threads/sample-iap-project.529555/
     
  7. seven_

    seven_

    Joined:
    Sep 30, 2014
    Posts:
    23
    It is only durable items. Consumables are working fine.
    I will try to get the sample project running and will get back then.
     
  8. seven_

    seven_

    Joined:
    Sep 30, 2014
    Posts:
    23
    I have now used the sample project you provided and did not change the iap version (so it is using the older version 1.18).
    The problems I have reported are still the same. I have attached the logs (having replaced the store ids). The sample is set to return Complete (not Pending). I use Unity 2018.3.0 (public version on Win10 in this case).
    I have commented the log using slashes:

    //Log 1: fresh app start, DURABLE1 was previously bought, DURABLE2 is now being bought

    Complete = True
    UnityIAPWin8:Begin PollForProducts() persistent = True, delay = 0, productsOnly = False
    UnityIAPWin8:Building full product list with existing purchases
    UnityIAPWin8:Fake transactionID: Set transactionMap[DURABLE1] = -1349125067
    Unavailable product subscription2 -subscription2
    OnInitialized: PASS
    Already recorded transaction -1349125067
    Fulfilling transaction -1349125067
    ProductID DURABLE1
    UnityIAPWin8:Consuming: DURABLE1
    UnityIAPWin8:Exception DURABLE1 : Guid should contain 32 digits with 4 dashes
    (xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx). (non-fatal)

    //start buying process DURABLE2

    Purchasing product:DURABLE2
    purchase({0}): DURABLE2
    UnityIAPWin8:Purchase DURABLE2 status:Succeeded
    PURCHASE SUCCEEDED!:{0}: 0
    ProcessPurchase: Complete. Product:DURABLE2 - 91fe567c-f81d-44d0-90df-980c782e372a
    Fulfilling transaction 91fe567c-f81d-44d0-90df-980c782e372a
    ProductID DURABLE2
    UnityIAPWin8:Consuming: DURABLE2
    UnityIAPWin8:Fulfilment result for DURABLE2 - 91fe567c-f81d-44d0-90df-980c782e372a : ServerError

    //Log 2: new app start, DURABLE1 and DURABLE2 previously bought durables

    Complete = True
    UnityIAPWin8:Begin PollForProducts() persistent = True, delay = 0, productsOnly = False
    UnityIAPWin8:Fake transactionID: Set transactionMap[DURABLE1] = -1349125067
    UnityIAPWin8:Fake transactionID: Set transactionMap[DURABLE2] = 190501192
    Unavailable product subscription2 -subscription2
    OnInitialized: PASS
    Already recorded transaction 190501192
    Already recorded transaction -1349125067
    Fulfilling transaction 190501192
    ProductID DURABLE2
    UnityIAPWin8:Consuming: DURABLE2
    UnityIAPWin8:Exception consuming DURABLE2 : Guid should contain 32 digits with 4 dashes
    (xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx). (non-fatal)
    Fulfilling transaction -1349125067
    ProductID DURABLE1
    UnityIAPWin8:Consuming: DURABLE1
    UnityIAPWin8:Exception consuming DURABLE1 : Guid should contain 32 digits with 4 dashes
    (xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx). (non-fatal)

    //Log 3: I told in the side note that consumables are processed twice when buying them for the second time without restarting
    //new app start (deleted starting logs now), CONSUMABLE is now tried to be fulfilled twice
    //buying CONSUMABLE for the first time .. all fine

    Purchasing product:CONSUMABLE
    purchase({0}): CONSUMABLE
    UnityIAPWin8:Purchase CONSUMABLE status:Succeeded
    PURCHASE SUCCEEDED!:{0}: 0
    ProcessPurchase: Complete. CONSUMABLE - d71b2baf-5992-4c1a-9f84-6fc915798a40
    Fulfilling transaction d71b2baf-5992-4c1a-9f84-6fc915798a40
    ProductID CONSUMABLE
    UnityIAPWin8:Consuming: CONSUMABLE
    UnityIAPWin8:Fulfilment result for CONSUMABLE - d71b2baf-5992-4c1a-9f84-6fc915798a40 : Succeeded

    //buying CONSUMABLE for the second time --> the consumable is tried to be fulfilled twice

    Purchasing product:CONSUMABLE
    purchase({0}): CONSUMABLE
    UnityIAPWin8:Purchase CONSUMABLE status:Succeeded
    PURCHASE SUCCEEDED!:{0}: 1
    ProcessPurchase: Complete. Product:CONSUMABLE - 273376c5-4e57-4285-8405-3a94bf5950e5
    Fulfilling transaction 273376c5-4e57-4285-8405-3a94bf5950e5
    ProductID CONSUMABLE
    UnityIAPWin8:Consuming: CONSUMABLE
    UnityIAPWin8:Fake transactionID: Set transactionMap[DURABLE1] = -1349125067
    UnityIAPWin8:Fake transactionID: Set transactionMap[DURABLE2] = 190501192
    Already recorded transaction 273376c5-4e57-4285-8405-3a94bf5950e5
    Already recorded transaction 190501192
    Already recorded transaction -1349125067
    Fulfilling transaction 273376c5-4e57-4285-8405-3a94bf5950e5
    ProductID CONSUMABLE
    UnityIAPWin8:Consuming: CONSUMABLE
    Fulfilling transaction 190501192
    ProductID DURABLE2
    UnityIAPWin8:Consuming: DURABLE2
    UnityIAPWin8:Exception consuming DURABLE2 : Guid should contain 32 digits with 4 dashes
    (xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx). (non-fatal)
    Fulfilling transaction -1349125067
    ProductID DURABLE1
    UnityIAPWin8:Consuming: DURABLE1
    UnityIAPWin8:Exception consuming DURABLE1 : Guid should contain 32 digits with 4 dashes
    (xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx). (non-fatal)
    UnityIAPWin8:Fulfilment result for CONSUMABLE - 273376c5-4e57-4285-8405-3a94bf5950e5 : NothingToFulfill
    UnityIAPWin8:Fulfilment result for CONSUMABLE - 273376c5-4e57-4285-8405-3a94bf5950e5 : Succeeded
     
    Last edited: Jan 10, 2019
  9. JeffDUnity3D

    JeffDUnity3D

    Unity Technologies

    Joined:
    May 2, 2017
    Posts:
    3,130
    @seven_ Does this also occur when using 1.20.1 ?
     
  10. seven_

    seven_

    Joined:
    Sep 30, 2014
    Posts:
    23
    I just updated the test project to the latest IAP version 1.20.1.
    The behaviour is still the same.
     
  11. JeffDUnity3D

    JeffDUnity3D

    Unity Technologies

    Joined:
    May 2, 2017
    Posts:
    3,130
    Understood, this is on my list to investigate, but unfortunately not any time soon.