Search Unity

IAP Subscription Upgrade for Android and iOS documentation?

Discussion in 'Unity IAP' started by Adarkuccio, May 10, 2021.

  1. Adarkuccio

    Adarkuccio

    Joined:
    May 3, 2017
    Posts:
    4
    Hello,

    I'm having hard time finding a documentation with the process of upgrading subscriptions explained. I only found some old answers here but what I've tried on Android isn't working for me. Here's an example:

    Code (CSharp):
    1. Product oldProduct = m_Controller.products.WithID("oldProductID");
    2. Product newProduct = m_Controller.products.WithID("newProductID");
    3. Action<string, string> googlePlayCallback = new Action<string, string>(m_GooglePlayStoreExtensions.UpgradeDowngradeSubscription);
    4. SubscriptionManager.UpdateSubscription(newProduct, oldProduct, "sampleDeveloperPayload", null, googlePlayCallback);
    following an answer I found here: https://forum.unity.com/threads/google-play-subscription-upgrade-downgrade.528434/

    According to the explanation I found in the same thread, looks like you must have bought the first subscription, but not the second one (the upgrade), which makes me think I need to call SubscriptionManager.UpgradeSubscription without purchasing first. If I do that I get a purchase failure. If I call UpgradeSubscription after purchasing the sub, well it doesn't upgrade and I end up with two subs. Can anyone pointing me to a documentation that actually explain the whole flow for upgrading a subscription for both iOS and Android? apparently I'm using this API wrong.

    Thanks
     
  2. JeffDUnity3D

    JeffDUnity3D

    Joined:
    May 2, 2017
    Posts:
    14,446
    @Adarkuccio How are you checking if you still have 2 subscriptions after the upgrade? We do have an issue where the original receipt is still present in the product controller after the upgrade. What version of IAP are you using?
     
  3. Adarkuccio

    Adarkuccio

    Joined:
    May 3, 2017
    Posts:
    4
    Thanks for the quick reply. I'm using the Unity Purchasing 2.1.1, the way I checked is by going to my google account under subscriptions I see both active, I do test with the test account.
     
  4. JeffDUnity3D

    JeffDUnity3D

    Joined:
    May 2, 2017
    Posts:
    14,446
    You'll want to upgrade IAP, Google is requiring Google Billing Library v3 now, which we include. I'm not familiar with specific updates to this area, but you'll want to test. The latest IAP is 3.1.0 via Package Manager, you need Unity 2019.4 or higher.
     
  5. Adarkuccio

    Adarkuccio

    Joined:
    May 3, 2017
    Posts:
    4
    I'll try! I'm using Unity 2020, anyways is the upgrading flow I'm using correct? I'd like to understand the purchase flow in the case of the subscription upgrade, my IAP implementation with Initialization and ProcessPurchase works well, but when it comes to upgrade a subscription to another, I am not supposed to purchase the IAP via the same flow, right? unfortunately I can't find a full code example to look at.
     
  6. JeffDUnity3D

    JeffDUnity3D

    Joined:
    May 2, 2017
    Posts:
    14,446
    As the term upgrade implies, it is assumed that you already have a subscription. For example, the user might have an existing monthly subscription that they wish to upgrade to yearly.
     
    Last edited: May 11, 2021
  7. Adarkuccio

    Adarkuccio

    Joined:
    May 3, 2017
    Posts:
    4
    For anyone having the same difficulties upgrading subscriptions on iOS or Android, this is how you do it. Assume you want to upgrade subscription A into subscription B. On iOS they must be under the same group, for Android they can just be two different subscriptions.

    1. purchase subscription A like you purchase any other IAP
    2. do NOT purchase subscription B
    3. Call SubscriptionManager.UpdateSubscriptionInGooglePlayStore and
      SubscriptionManager.UpdateSubscriptionInAppleStore separately instead, do NOT use
      SubscriptionManager.UpdateSubscription
    for Android this is the code:

    in this example I will use

    subscription A = oldId
    subscription B = newId

    Code (CSharp):
    1.  Product oldProduct = m_StoreController.products.WithID("oldId");
    2.                 Product newProduct = m_StoreController.products.WithID("newId");
    3.        
    4.                 SubscriptionManager.UpdateSubscriptionInGooglePlayStore(oldProduct, newProduct,
    5.                     (productInfos, newProductId) =>
    6.                     {
    7.                         m_GooglePlayStoreExtensions.UpgradeDowngradeSubscription(oldProduct.definition.id, newProduct.definition.id);
    8.                     });
    9.  
    for iOS this is the code:

    Code (CSharp):
    1. Product newProduct = m_StoreController.products.WithID("newId");
    2.                
    3.            SubscriptionManager.UpdateSubscriptionInAppleStore(newProduct, "payload", (newProductArg, unknownArg) =>
    4.                     m_StoreController.InitiatePurchase(newProductArg));
    5.  
     
    AmrAutsera and JeffDUnity3D like this.
  8. ashishdevden

    ashishdevden

    Joined:
    Oct 5, 2020
    Posts:
    17
    Hi,
    I am working on upgrading /downgrading subscription
    but I don't know what is "m_GooglePlayStoreExtensions", and how can I access this?
     
  9. JeffDUnity3D

    JeffDUnity3D

    Joined:
    May 2, 2017
    Posts:
    14,446
    I would not recommend that code posted above. Note that they are calling the upgrade method twice, once from SubscriptionManager and another via extensions. You will want to look at the Sample IAP Project v2

    If the SubscriptionManager version isn't working, we will need to fix it. You are welcome to try with the extension however.

    Code (CSharp):
    1. public void OnInitialized(IStoreController controller, IExtensionProvider extensions)
    2.     {
    3.         MyDebug("OnInitialized: PASS");
    4.  
    5.         m_StoreController = controller;
    6.         m_StoreExtensionProvider = extensions;
    7.         m_AppleExtensions = extensions.GetExtension<IAppleExtensions>();
    8.         m_GoogleExtensions = extensions.GetExtension<IGooglePlayStoreExtensions>();
     
  10. ashishdevden

    ashishdevden

    Joined:
    Oct 5, 2020
    Posts:
    17
    so basically i am doing internal testing of my application,I have 3 months,6 months, and a 12-month subscription in my application
    I already have the subscription for 6 months and now I am trying to upgrade to 12 months subscription.
    I tried with the extension method but
    I am getting an error while using m_GooglePlayStoreExtensions.UpdateSubscription function saying
    "2021-06-17 10:34:09.811 26172 26232 Info Unity Error: the product that will be updated does not have a valid receipt: System.NullReferenceException: Object reference not set to an instance of an object."(this is from android logcat).
    i also used the m_GooglePlayStoreExtensions.UpgradeDowngradeSubscription function
    but getting the same error.

    what exactly is the issue and how can u fix it??
    unity version is 2019.4.18

    Thanx for the answer.
     
    Last edited: Jun 17, 2021
  11. JeffDUnity3D

    JeffDUnity3D

    Joined:
    May 2, 2017
    Posts:
    14,446
    Can you share your code? Have you tried switching the product order, it sounds like you may have them switched
     
  12. ashishdevden

    ashishdevden

    Joined:
    Oct 5, 2020
    Posts:
    17
    Code (CSharp):
    1.    public void Buy1YearSubscription()
    2.     {
    3.  
    4.         print("trying to buy 12 months of subscription");
    5.  
    6.  
    7.  
    8.  
    9.         bool alreadyHaveSomeSubscription = false;
    10.         Product oldProduct = m_StoreController.products.WithID(_1YearSubscription);
    11.  
    12.  
    13.         foreach (Product p in m_StoreController.products.all)
    14.         {
    15.             GooglePurchaseData data = new GooglePurchaseData(p.receipt);
    16.  
    17.             if (p.hasReceipt)
    18.             {
    19.                 alreadyHaveSomeSubscription = true;
    20.                 oldProduct = m_StoreController.products.WithID(data.json.productId);
    21.                 GooglePurchaseData data2 = new GooglePurchaseData(oldProduct.receipt);
    22.  
    23.                 print("Has the reciept of----->" + data2.json.productId);
    24.  
    25.                 break;
    26.             }
    27.         }
    28.  
    29.         if (!alreadyHaveSomeSubscription)
    30.         {
    31.             print("no previous subscription");
    32.             BuyProductID(_1YearSubscription);
    33.         }
    34.         else
    35.         {
    36.  
    37.             print("upgrading to 1year");
    38.             SubscriptionManager.UpdateSubscriptionInGooglePlayStore(oldProduct, m_StoreController.products.WithID(_1YearSubscription), (string msg1, string msg2) =>
    39.             {
    40.  
    41.                 IgoogleplayStoreExtention.UpdateSubscription(oldProduct, m_StoreController.products.WithID(_1YearSubscription), GooglePlayStoreProrationMode.ImmediateWithoutProration);
    42.             });
    43.  
    44.  
    45.         }
    46.     }

    here is the code

    here I am just checking if the user is subscribed to any of the plan by checking if there is any receipt.
    if he is not then I am calling BuyProductID(_1YearSubscription);
    else I am calling

    SubscriptionManager.UpdateSubscriptionInGooglePlayStore(oldProduct, m_StoreController.products.WithID(_1YearSubscription), (string msg1, string msg2) =>
    {

    IgoogleplayStoreExtention.UpdateSubscription(oldProduct, m_StoreController.products.WithID(_1YearSubscription), GooglePlayStoreProrationMode.ImmediateWithoutProration);
    });
     
    Last edited: Jun 18, 2021
  13. JeffDUnity3D

    JeffDUnity3D

    Joined:
    May 2, 2017
    Posts:
    14,446
    Did you try my suggestion? I will try here too
     
  14. ashishdevden

    ashishdevden

    Joined:
    Oct 5, 2020
    Posts:
    17
    ya I switched the order from this
    SubscriptionManager.UpdateSubscriptionInGooglePlayStore(oldProduct, m_StoreController.products.WithID(_1YearSubscription), (string msg1, string msg2) =>
    {

    IgoogleplayStoreExtention.UpdateSubscription(oldProduct, m_StoreController.products.WithID(_1YearSubscription), GooglePlayStoreProrationMode.ImmediateWithoutProration);
    });

    to

    SubscriptionManager.UpdateSubscriptionInGooglePlayStore(m_StoreController.products.WithID(_1YearSubscription),oldProduct ,(string msg1, string msg2) =>
    {

    IgoogleplayStoreExtention.UpdateSubscription(oldProduct, m_StoreController.products.WithID(_1YearSubscription), GooglePlayStoreProrationMode.ImmediateWithoutProration);
    });

    but still
    the same issue

    Do u think this issue is arriving because I am doing internal testing of my application??
     
  15. JeffDUnity3D

    JeffDUnity3D

    Joined:
    May 2, 2017
    Posts:
    14,446
    No it should work in testing. I always create several email accounts and test users to test subscriptions and non-consumables. But we may have some work to do in this area, I still need to test.
     
  16. ashishdevden

    ashishdevden

    Joined:
    Oct 5, 2020
    Posts:
    17
  17. JeffDUnity3D

    JeffDUnity3D

    Joined:
    May 2, 2017
    Posts:
    14,446
    We have received your support ticket, we will follow up there. I will post the resolution here when the investigation is complete.
     
  18. JeffDUnity3D

    JeffDUnity3D

    Joined:
    May 2, 2017
    Posts:
    14,446
  19. ashishdevden

    ashishdevden

    Joined:
    Oct 5, 2020
    Posts:
    17
    Code (CSharp):
    1. Product newProduct = m_StoreController.products.WithID("newId");
    2.              
    3.            SubscriptionManager.UpdateSubscriptionInAppleStore(newProduct, "payload", (newProductArg, unknownArg) =>
    4.                     m_StoreController.InitiatePurchase(newProductArg));
    what is payload in this and how can i give proration method while upgrading the subscription
     
  20. JeffDUnity3D

    JeffDUnity3D

    Joined:
    May 2, 2017
    Posts:
    14,446
     
  21. Sancejas

    Sancejas

    Joined:
    Jul 12, 2019
    Posts:
    3
    Hi I want to know, how can I make a yearly subscription with Unity IAP?
     
  22. JeffDUnity3D

    JeffDUnity3D

    Joined:
    May 2, 2017
    Posts:
    14,446
  23. georgemarkosian

    georgemarkosian

    Joined:
    Aug 21, 2019
    Posts:
    3
    After several days of debugging and all possible tries it doesn't work right.

    We have 3 tiers of subscriptions with 2 durations for each: monthly and annual.
    When I purchase tier 1 annual it's ok as this is just a regular purchase. Then I purchase tier 2 monthly which is better. The SubscriptionManager continues showing 2 active subscriptions, both isSubscribed and isAuthRenewing == True. When the second subscription expires the manager returns the first one. At this moment I'm not subscribed in my account details. This is for iOS.

    Disclaimers:
    - I'm using the latest Unity IAP package (4.1.5)
    - I tried the solutions from this thread
    - I checked subscription items in the app store, all in the same group

    Calling SubscriptionManager.UpdateSubscriptionInAppleStore and then calling StoreController.InitiatePurchase has no effect.
     
  24. JeffDUnity3D

    JeffDUnity3D

    Joined:
    May 2, 2017
    Posts:
    14,446
    This sounds like expected behavior, perhaps I'm not following. Are you directly purchasing, or upgrading? And you mention "which is better", what do you mean by better? At any rate, this behavior will all be changing later this year as we move to StoreKit2
     
  25. unitylicense19

    unitylicense19

    Joined:
    Aug 29, 2018
    Posts:
    32
    Is there any update on this
    For IOS & For Android how can we upgrade subscriptions
     
  26. unity_52B9288CB7049A41C920

    unity_52B9288CB7049A41C920

    Joined:
    Sep 8, 2022
    Posts:
    11
    @unitylicense19 download samples from the latest unity IAP package, you'll get code for all the scenarios, I tried that and it worked for me perfectly.