Skip to main content
Inspiring
October 13, 2025
Question

[IAP] Each Purchase object has its "Type" property set to Unknown for subscriptions.

Full Disclosure: I am testing subscriptions in draft mode and with test user account.

        IAP.GetViewerPurchases().OnComplete(msg =>
        {
            if (msg.IsError)
            {
                return;
            }


            if (msg.GetPurchaseList().Count == 0)
            {
                return;
            }

            foreach (Purchase item in msg.GetPurchaseList())
            {
                Debug.LogFormat("Purchased: sku:{0} granttime:{1} id:{2} expire:{3} type:{4}", item.Sku, item.GrantTime, item.ID, item.ExpirationTime, item.Type); // All values are available properly except for item.Type prints "unknown" in console.
            }


        });

However, this API does return any unconsumed items properly with type set to "CONSUMABLE" but for subscription its not working.

So my question is, if this is happening due to subscription being in draft mode? and if I can depend on this property in production app to check if items in loop is any unconsumed product or just a subscription ?

3 replies

Meta Employee
October 13, 2025

Hello there!

Draft Mode should still allow you to grant or revoke add-on entitlements. As far as the unconsumed items, are you only having this issue with subscriptions? I would recommend checking your project against our documentation on subscriptions to make sure everything is setup properly. 

If you are still having issues, or have additional questions on implementation, let me know!

Inspiring
October 14, 2025

Hi there,

Yes, I am able to subscribe/cancel/renew/expire subscription while in draft mode. Yes the issue is only with subscription "Type" property not set. As a workaround, I am comparing SKU from `PurchaseList` against my SKU:

//workaround
var subscriptionPurchases = msg.GetPurchaseList().Where(i => i.Sku == SKU_SUB_LOW_TIER || i.Sku == SKU_SUB_HIGH_TIER );
var consumablePurchases = msg.GetPurchaseList().Where(i => i.Sku != SKU_SUB_LOW_TIER || i.Sku != SKU_SUB_HIGH_TIER );

//expected (not working for subscription)
var subscriptionPurchases = msg.GetPurchaseList().Where(i => i.Type == ProductType.SUBSCRIPTION);
var consumablePurchases = msg.GetPurchaseList().Where(i => i.Type == ProductType.CONSUMABLE);

From the link you provided, I guess you're suggesting subscription should be validated from server-to-server API at regular intervals (such as: app launch, sub ID change, expire timestamp change, etc) instead of depending on local check?

Meta Employee
October 17, 2025

Thanks for clarifying! For now, I'd recommend continuing to use your workaround as that looks like a stable solution. If you have any additional questions on implementation, please feel free to reach out.