IAP Subscription Upgrade for Android and iOS documentation?

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:

Product oldProduct = m_Controller.products.WithID("oldProductID");
Product newProduct = m_Controller.products.WithID("newProductID");
Action<string, string> googlePlayCallback = new Action<string, string>(m_GooglePlayStoreExtensions.UpgradeDowngradeSubscription);
SubscriptionManager.UpdateSubscription(newProduct, oldProduct, "sampleDeveloperPayload", null, googlePlayCallback);

following an answer I found here: Google Play Subscription Upgrade / Downgrade

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

@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?

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.

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.

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.

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.

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.

  • purchase subscription A like you purchase any other IAP
  • do NOT purchase subscription B
  • 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

 Product oldProduct = m_StoreController.products.WithID("oldId");
                Product newProduct = m_StoreController.products.WithID("newId");
       
                SubscriptionManager.UpdateSubscriptionInGooglePlayStore(oldProduct, newProduct,
                    (productInfos, newProductId) =>
                    {
                        m_GooglePlayStoreExtensions.UpgradeDowngradeSubscription(oldProduct.definition.id, newProduct.definition.id);
                    });

for iOS this is the code:

Product newProduct = m_StoreController.products.WithID("newId");
               
           SubscriptionManager.UpdateSubscriptionInAppleStore(newProduct, "payload", (newProductArg, unknownArg) =>
                    m_StoreController.InitiatePurchase(newProductArg));
2 Likes

Hi,

I am working on upgrading /downgrading subscription
but I don’t know what is “m_GooglePlayStoreExtensions”, and how can I access this?

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.

public void OnInitialized(IStoreController controller, IExtensionProvider extensions)
    {
        MyDebug("OnInitialized: PASS");

        m_StoreController = controller;
        m_StoreExtensionProvider = extensions;
        m_AppleExtensions = extensions.GetExtension<IAppleExtensions>();
        m_GoogleExtensions = extensions.GetExtension<IGooglePlayStoreExtensions>();

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.

Can you share your code? Have you tried switching the product order, it sounds like you may have them switched

   public void Buy1YearSubscription()
    {

        print("trying to buy 12 months of subscription");




        bool alreadyHaveSomeSubscription = false;
        Product oldProduct = m_StoreController.products.WithID(_1YearSubscription);


        foreach (Product p in m_StoreController.products.all)
        {
            GooglePurchaseData data = new GooglePurchaseData(p.receipt);

            if (p.hasReceipt)
            {
                alreadyHaveSomeSubscription = true;
                oldProduct = m_StoreController.products.WithID(data.json.productId);
                GooglePurchaseData data2 = new GooglePurchaseData(oldProduct.receipt);

                print("Has the reciept of----->" + data2.json.productId);

                break;
            }
        }
  
        if (!alreadyHaveSomeSubscription)
        {
            print("no previous subscription");
            BuyProductID(_1YearSubscription);
        }
        else
        {

            print("upgrading to 1year");
            SubscriptionManager.UpdateSubscriptionInGooglePlayStore(oldProduct, m_StoreController.products.WithID(_1YearSubscription), (string msg1, string msg2) =>
            {

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


        }
    }

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);
});

Did you try my suggestion? I will try here too

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??

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.

ohh ok!:face_with_spiral_eyes::sweat_smile:

We have received your support ticket, we will follow up there. I will post the resolution here when the investigation is complete.

The code above worked for me without issue IAP Subscription Upgrade for Android and iOS documentation?

Product newProduct = m_StoreController.products.WithID("newId");
              
           SubscriptionManager.UpdateSubscriptionInAppleStore(newProduct, "payload", (newProductArg, unknownArg) =>
                    m_StoreController.InitiatePurchase(newProductArg));

what is payload in this and how can i give proration method while upgrading the subscription