Search Unity

  1. Check out the Unite LA keynote for updates on the Visual Effect Editor, the FPS Sample, ECS, Unity for Film and more! Watch it now!
    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. Improved Prefab workflow (includes Nested Prefabs!), 2D isometric Tilemap and more! Get the 2018.3 Beta now.
    Dismiss Notice
  4. Want more efficiency in your development work? Sign up to receive weekly tech and creative know-how from Unity experts.
    Dismiss Notice
  5. Improve your Unity skills with a certified instructor in a private, interactive classroom. Watch the overview now.
    Dismiss Notice
  6. Want to see the most recent patch releases? Take a peek at the patch release page.
    Dismiss Notice

FetchAdditionalProducts

Discussion in 'Unity IAP' started by ncortesp, Nov 7, 2018.

  1. ncortesp

    ncortesp

    Joined:
    Oct 28, 2016
    Posts:
    27
    Hi Unity,

    I don't know how to handle this situation (I'll show you 3 escenarios).

    First Case: Pending Purchase with connection lost.
    1. Open the app
    2. Get into the shop.
    3. Click on a consumible item (I want to purchase it).
    4. The Android popup appears (where i shows the product title, description, prize...).
    5. I Tap to Buy and when it says "Payment Successful" I take off my Wireless connection.
    6. The user has been charged, and the purchase is in PendingPurchase statement.
    7. Now an internal "Connection error" popup is shown (We throw this).
    8. After a reconnection (we call FetchAdditionalProducts in order to check if there is any product in PendingPurchase statement in order to close that transaction).
    This is what I'm getting after FetchingAdditionalProducts (This is the log from Terminal);

    Code (CSharp):
    1. I/Unity   (32522): <b><color=yellow>[08:31:20]</color></b> cofre_oro_troya - Cofre de Oro (Troya - Máquina Tragaperras Gratis Online) - Un cofre de oro que contiene un montón de monedas - EUR - 49.99 -49.99 -  -
    2. I/Unity   (32522):
    3. I/Unity   (32522): (Filename: ./Runtime/Export/Debug.bindings.h Line: 43)
    4. I/Unity   (32522):
    5. I/Unity   (32522): <b><color=yellow>[08:31:20]</color></b> cofre_plata_troya - Cofre de Plata (Troya - Máquina Tragaperras Gratis Online) - Un cofre de plata que contiene un montón de monedas - EUR - 24.99 -24.99 -  -
    6. I/Unity   (32522):
    7. I/Unity   (32522): (Filename: ./Runtime/Export/Debug.bindings.h Line: 43)
    8. I/Unity   (32522):
    9. I/Unity   (32522): <b><color=yellow>[08:31:20]</color></b> cofre_bronce_troya - Cofre de Bronce (Troya - Máquina Tragaperras Gratis Online) - Un cofre de bronce que contiene un montón de monedas - EUR - 9.99 -9.99 -  -
    10. I/Unity   (32522):
    11. I/Unity   (32522): (Filename: ./Runtime/Export/Debug.bindings.h Line: 43)
    12. I/Unity   (32522):
    13. I/Unity   (32522): <b><color=yellow>[08:31:20]</color></b> caldero_troya - Caldero (Troya - Máquina Tragaperras Gratis Online) - Un caldero con un montón de monedas - EUR - 4.99 -4.99 -  -
    14. I/Unity   (32522):
    15. I/Unity   (32522): (Filename: ./Runtime/Export/Debug.bindings.h Line: 43)
    16. I/Unity   (32522):
    17. I/Unity   (32522): <b><color=yellow>[08:31:20]</color></b> marmita_troya - Marmita (Troya - Máquina Tragaperras Gratis Online) - Marmita que contiene un montón de monedas - EUR - 1.99 -1.99 -  - {"Store":"GooglePlay","TransactionID":"GPA.3344-2367-3411-10065","Payload":"{\"json\":\"{\\\"orderId\\\":\\\"GPA.3344-2367-3411-10065\\\",\\\"packageName\\\":\\\"com.slot.spins.casino.machine.bar.tragaperras.troya.tragamonedas\\\",\\\"productId\\\":\\\"marmita_troya\\\",\\\"purchaseTime\\\":1541575706661,\\\"purchaseState\\\":0,\\\"developerPayload\\\":\\\"{\\\\\\\"developerPayload\\\\\\\":\\\\\\\"YWMxNGY1ZjEtYzI3OS00NjA1LWFkYWItMTkwYTZjYzdhN2Nl\\\\\\\\n\\\\\\\",\\\\\\\"is_free_trial\\\\\\\":false,\\\\\\\"has_introductory_price_trial\\\\\\\":false,\\\\\\\"is_updated\\\\\\\":false}\\\",\\\"purchaseToken\\\":\\\"jppiopckadecjjjckmhnobbb.AO-J1OyTpodhURkiGtFo9ufTgwigV-UE7Fz6LEim-dJjCJ7GbMJRUov9oqQQvRbiPbycuGlZWIoZffxH9C8gh2OKPJQ-7Dj1FjiI-RwJQD_t27V5rRx54a6BmxAVAIiQ0cEOhta8S-u5SRyBQKJa4gwhI2iKoztQe90nRpOYfSD4Evo86Ln0mQQ\\\"}\",\"signa
    18. I/Unity   (32522): <b><color=yellow>[08:31:20]</color></b> bolsita_troya - Bolsita (Troya - Máquina Tragaperras Gratis Online) - Una bolsita con un montón de monedas - EUR - 0.99 - €0.99 -  -
    19.  
    What we can see here is that there is a receipt attached to marmita_troya, but I don't see any GPA.

    Second Case: Purchase successful.
    1. Open the app
    2. Get into the shop.
    3. Click on a consumible item (I want to purchase it).
    4. The Android popup appears (where i shows the product title, description, prize...).
    5. I Tap to Buy and when it says "Payment Successful" I set the product to PendingPurchase.
    6. A Successful Payment purchase is shown (we throw this after our Backend validation).
    7. We call ConfirmPendingPurchase (in order to close the finish with the PendingPurchase).
    8. After that we call FetchAdditionalProducts in order to check if there is any product in PendingPurchase.
    This is what I'm getting after FetchingAdditionalProducts (This is the log from Terminal);

    Code (CSharp):
    1. I/Unity   (32522): <b><color=yellow>[08:31:20]</color></b> cofre_oro_troya - Cofre de Oro (Troya - Máquina Tragaperras Gratis Online) - Un cofre de oro que contiene un montón de monedas - EUR - 49.99 -49.99 -  -
    2. I/Unity   (32522):
    3. I/Unity   (32522): (Filename: ./Runtime/Export/Debug.bindings.h Line: 43)
    4. I/Unity   (32522):
    5. I/Unity   (32522): <b><color=yellow>[08:31:20]</color></b> cofre_plata_troya - Cofre de Plata (Troya - Máquina Tragaperras Gratis Online) - Un cofre de plata que contiene un montón de monedas - EUR - 24.99 -24.99 -  -
    6. I/Unity   (32522):
    7. I/Unity   (32522): (Filename: ./Runtime/Export/Debug.bindings.h Line: 43)
    8. I/Unity   (32522):
    9. I/Unity   (32522): <b><color=yellow>[08:31:20]</color></b> cofre_bronce_troya - Cofre de Bronce (Troya - Máquina Tragaperras Gratis Online) - Un cofre de bronce que contiene un montón de monedas - EUR - 9.99 -9.99 -  -
    10. I/Unity   (32522):
    11. I/Unity   (32522): (Filename: ./Runtime/Export/Debug.bindings.h Line: 43)
    12. I/Unity   (32522):
    13. I/Unity   (32522): <b><color=yellow>[08:31:20]</color></b> caldero_troya - Caldero (Troya - Máquina Tragaperras Gratis Online) - Un caldero con un montón de monedas - EUR - 4.99 -4.99 -  -
    14. I/Unity   (32522):
    15. I/Unity   (32522): (Filename: ./Runtime/Export/Debug.bindings.h Line: 43)
    16. I/Unity   (32522):
    17. I/Unity   (32522): <b><color=yellow>[08:31:20]</color></b> marmita_troya - Marmita (Troya - Máquina Tragaperras Gratis Online) - Marmita que contiene un montón de monedas - EUR - 1.99 -1.99 -  - {"Store":"GooglePlay","TransactionID":"GPA.3344-2367-3411-10065","Payload":"{\"json\":\"{\\\"orderId\\\":\\\"GPA.3344-2367-3411-10065\\\",\\\"packageName\\\":\\\"com.slot.spins.casino.machine.bar.tragaperras.troya.tragamonedas\\\",\\\"productId\\\":\\\"marmita_troya\\\",\\\"purchaseTime\\\":1541575706661,\\\"purchaseState\\\":0,\\\"developerPayload\\\":\\\"{\\\\\\\"developerPayload\\\\\\\":\\\\\\\"YWMxNGY1ZjEtYzI3OS00NjA1LWFkYWItMTkwYTZjYzdhN2Nl\\\\\\\\n\\\\\\\",\\\\\\\"is_free_trial\\\\\\\":false,\\\\\\\"has_introductory_price_trial\\\\\\\":false,\\\\\\\"is_updated\\\\\\\":false}\\\",\\\"purchaseToken\\\":\\\"jppiopckadecjjjckmhnobbb.AO-J1OyTpodhURkiGtFo9ufTgwigV-UE7Fz6LEim-dJjCJ7GbMJRUov9oqQQvRbiPbycuGlZWIoZffxH9C8gh2OKPJQ-7Dj1FjiI-RwJQD_t27V5rRx54a6BmxAVAIiQ0cEOhta8S-u5SRyBQKJa4gwhI2iKoztQe90nRpOYfSD4Evo86Ln0mQQ\\\"}\",\"signa
    18. I/Unity   (32522): <b><color=yellow>[08:31:20]</color></b> bolsita_troya - Bolsita (Troya - Máquina Tragaperras Gratis Online) - Una bolsita con un montón de monedas - EUR - 0.99 - €0.99 -  -
    19.  

    Third Case: Finishing the purchase after relaunching the game.

    1. Open the app
    2. Get into the shop.
    3. Click on a consumible item (I want to purchase it).
    4. The Android popup appears (where i shows the product title, description, prize...).
    5. I Tap to Buy and when it says "Payment Successful" I close the app (from background).
    6. The user has been charged, and the purchase is in PendingPurchase statement.
    7. I relaunch my app, and this is what I see.
    Code (CSharp):
    1. I/Unity   (32522): <b><color=yellow>[08:31:20]</color></b> cofre_oro_troya - Cofre de Oro (Troya - Máquina Tragaperras Gratis Online) - Un cofre de oro que contiene un montón de monedas - EUR - 49.99 -49.99 -  -
    2. I/Unity   (32522):
    3. I/Unity   (32522): (Filename: ./Runtime/Export/Debug.bindings.h Line: 43)
    4. I/Unity   (32522):
    5. I/Unity   (32522): <b><color=yellow>[08:31:20]</color></b> cofre_plata_troya - Cofre de Plata (Troya - Máquina Tragaperras Gratis Online) - Un cofre de plata que contiene un montón de monedas - EUR - 24.99 -24.99 -  -
    6. I/Unity   (32522):
    7. I/Unity   (32522): (Filename: ./Runtime/Export/Debug.bindings.h Line: 43)
    8. I/Unity   (32522):
    9. I/Unity   (32522): <b><color=yellow>[08:31:20]</color></b> cofre_bronce_troya - Cofre de Bronce (Troya - Máquina Tragaperras Gratis Online) - Un cofre de bronce que contiene un montón de monedas - EUR - 9.99 -9.99 -  -
    10. I/Unity   (32522):
    11. I/Unity   (32522): (Filename: ./Runtime/Export/Debug.bindings.h Line: 43)
    12. I/Unity   (32522):
    13. I/Unity   (32522): <b><color=yellow>[08:31:20]</color></b> caldero_troya - Caldero (Troya - Máquina Tragaperras Gratis Online) - Un caldero con un montón de monedas - EUR - 4.99 -4.99 -  -
    14. I/Unity   (32522):
    15. I/Unity   (32522): (Filename: ./Runtime/Export/Debug.bindings.h Line: 43)
    16. I/Unity   (32522):
    17. I/Unity   (32522): <b><color=yellow>[08:31:20]</color></b> marmita_troya - Marmita (Troya - Máquina Tragaperras Gratis Online) - Marmita que contiene un montón de monedas - EUR - 1.99 -1.99 - GPA.3344-2367-3411-10065 - {"Store":"GooglePlay","TransactionID":"GPA.3344-2367-3411-10065","Payload":"{\"json\":\"{\\\"orderId\\\":\\\"GPA.3344-2367-3411-10065\\\",\\\"packageName\\\":\\\"com.slot.spins.casino.machine.bar.tragaperras.troya.tragamonedas\\\",\\\"productId\\\":\\\"marmita_troya\\\",\\\"purchaseTime\\\":1541575706661,\\\"purchaseState\\\":0,\\\"developerPayload\\\":\\\"{\\\\\\\"developerPayload\\\\\\\":\\\\\\\"YWMxNGY1ZjEtYzI3OS00NjA1LWFkYWItMTkwYTZjYzdhN2Nl\\\\\\\\n\\\\\\\",\\\\\\\"is_free_trial\\\\\\\":false,\\\\\\\"has_introductory_price_trial\\\\\\\":false,\\\\\\\"is_updated\\\\\\\":false}\\\",\\\"purchaseToken\\\":\\\"jppiopckadecjjjckmhnobbb.AO-J1OyTpodhURkiGtFo9ufTgwigV-UE7Fz6LEim-dJjCJ7GbMJRUov9oqQQvRbiPbycuGlZWIoZffxH9C8gh2OKPJQ-7Dj1FjiI-RwJQD_t27V5rRx54a6BmxAVAIiQ0cEOhta8S-u5SRyBQKJa4gwhI2iKoztQe90nRpOYfSD4Evo86Ln0mQQ\\\"}\",\"signa
    18. I/Unity   (32522): <b><color=yellow>[08:31:20]</color></b> bolsita_troya - Bolsita (Troya - Máquina Tragaperras Gratis Online) - Una bolsita con un montón de monedas - EUR - 0.99 - €0.99 -  -
    19.  
    In this case there is a GPA attached to the product in PendingPurchase statement. Now I do finish that transaction and I do FecthProducts again, what I see is that I keep getting that receipt on that product, but without GPA.

    I don't know how can I handle this because if the user loses it's connection, he won't finish his pending purchase until he relaunches the application.

    How are you guys handling this? I would like to receive an empty receipt for each product if the transaction has been closed. And if it's open, I would like to receive a GPA attached to.

    Greetings,
    Nacho.
     
  2. JeffDUnity3D

    JeffDUnity3D

    Unity Technologies

    Joined:
    May 2, 2017
    Posts:
    2,643
    Yes, it would be expected that the user would finish pending purchases upon app relaunch, you should receive a ProcessPurchase just after IAP initialization. And can you elaborate on the problem statement? In the last scenario, you mention "finish the transaction" so I assume you award the user the product at that point, correct? Where are you saving user purchases, on the device or to the cloud? Are you calling FetchAdditionalProducts just to refresh the receipts, and not actually to retrieve other/additional products? Is your goal to avoid having the user restart the app?
     
  3. ncortesp

    ncortesp

    Joined:
    Oct 28, 2016
    Posts:
    27
    In the last scenario, you mention "finish the transaction" so I assume you award the user the product at that point, correct? Yes once the transaction is finished we award the user with free coins.

    Where are you saving user purchases, on the device or to the cloud? Cloud

    Are you calling FetchAdditionalProducts just to refresh the receipts, and not actually to retrieve other/additional products? Yes I just want to update the product receipts and check this way If there is any pending transaction.

    Is your goal to avoid having the user restart the app? Yes, I don't want to force my users to restart the app in order to fix this situation, which just happens when they lose the connection once the payment is done but he hasn't get his reward.
     
  4. JeffDUnity3D

    JeffDUnity3D

    Unity Technologies

    Joined:
    May 2, 2017
    Posts:
    2,643
    Understood, you are describing an edge case. Currently the expected flow is upon app restart, but I will bring this up to the IAP team.
     
  5. unityjingyao

    unityjingyao

    Unity Technologies

    Joined:
    Feb 20, 2017
    Posts:
    196
    Hi @ncortesp ,
    Which version of Unity IAP are you using?
    Where did you print your log?
    How do you determine a transaction is in pending state?
    I'm using Unity IAP 1.20.1, and I can get 'Product.transactionID' after calling 'FetchAdditionalProducts'.
    Here are my steps:
    1. Buy a Consumable product and return 'PurchaseProcessingResult.Pending' in ProcessPurchase callback.
    2. Call 'FetchAdditionalProducts' and print out 'Product.transactionID' of all my owned products in the success callback.

    Meanwhile, I saw you could still get the receipt in the first scenario. So you can parse the transaction id from the receipt manually.
    The receipt is a Json string and the target field is 'TransactionID'.
     
  6. ncortesp

    ncortesp

    Joined:
    Oct 28, 2016
    Posts:
    27
    Here you can see how do I call FetchAdditionalProducts.

    Code (CSharp):
    1. _itemsHashSet = new HashSet<ProductDefinition>();
    2. m_StoreController.FetchAdditionalProducts(_itemsHashSet, OnProductsFetched, OnInitializeFailed);
    Code (CSharp):
    1. public void OnProductsFetched ()
    2.     {
    3.         SGO_Debug.Log("OnProductsFetched...");
    4.  
    5.         foreach (var item in m_StoreController.products.all)
    6.         {
    7.             if (item.availableToPurchase)
    8.             {
    9.                 SGO_Debug.Log(string.Join(" - ", new[] {
    10.                     item.definition.id,
    11.                     item.metadata.localizedTitle,
    12.                     item.metadata.localizedDescription,
    13.                     item.metadata.isoCurrencyCode,
    14.                     item.metadata.localizedPrice.ToString (),
    15.                     item.metadata.localizedPriceString,
    16.                     item.transactionID,
    17.                     item.receipt
    18.                 }));
    19.             }
    20.         }
    21.  
    22.         SGO_Debug.Log("Count: " + _itemsHashSet.Count);
    23.     }
    What I see here is that _itemsHashSet it's always empty.

    And the item.transactionID from m_StoreController.products.all it's empty too.

    Am I doing something wrong?

    That's true, but then I can't close the transaction (ConfirmPendingPurchase) because the transactionID is read only so I can't set the TransactionID.
     
  7. unityjingyao

    unityjingyao

    Unity Technologies

    Joined:
    Feb 20, 2017
    Posts:
    196
    It's weird. I used the same code to do 'FetchAdditionalProducts' but I couldn't reproduce this issue.
    I can always get Product.transactionID.
    Could you please open a ticket and send me your apk file? I'd like to test it on my side. Thank you.
    https://analytics.cloud.unity3d.com/support/
     
  8. ncortesp

    ncortesp

    Joined:
    Oct 28, 2016
    Posts:
    27
    Are you testing this on Android or iOS? Because the behaviour is diferent
     
  9. unityjingyao

    unityjingyao

    Unity Technologies

    Joined:
    Feb 20, 2017
    Posts:
    196
    I was testing it on Android with targeting Google Play store.