Retrieve a list of available items and prices by SKU
To retrieve a list of add-on items that are available to the user to purchase by SKU, use the following method. The SKUs must have a description to be retrieved by this method.
This method also returns any virtual SKUs associated with subscription periods.
Platform.IAP.GetProductsBySKU()
If your app displays a price for any add-on, you should use the localized price returned from this endpoint. Do not hard-code price amounts inside the app.
SKUs for subscriptions
If a subscription tier only has a single subscription period, you can reference that single subscription period as an add-on using the SKU of its tier.
However, to differentiate between multiple subscription periods of the same SKU, we create a virtual SKU for each period by appending the subscription period (WEEKLY, BIWEEKLY, MONTHLY, QUARTERLY, SEMIANNUAL, ANNUAL) to the SKU in this format:
<SKU>:SUBSCRIPTION__<PERIOD>
For example, consider a subscription tier with the SKU MyApp-Subscription that has both monthly and annual subscription periods. You would reference the subscription add-on items by virtual SKU as follows:
MyApp-Subscription:SUBSCRIPTION__MONTHLY
MyApp-Subscription:SUBSCRIPTION__ANNUAL
The GetProductsBySKU method also returns virtual SKUs, so to prevent errors, we recommend you call that method to obtain the full list of available SKUs instead of hardcoding virtual SKU strings into your product.
using UnityEngine;
using Oculus.Platform;
using Oculus.Platform.Models;
using UnityEngine.UI;
// This class coordinates In-App-Purchases (IAP) for the application. Follow the
// instructions in the Readme for setting up IAP on the Meta Quest dashboard. Only
// one consumable IAP item is used is the demo: the Power-Ball!
public class IAPManager : MonoBehaviour
{
// the game controller to notify when the user purchase more powerballs
[SerializeField] private GameController m_gameController;
// where to record to display the current price for the IAP item
[SerializeField] private Text m_priceText;
// purchasable IAP products we've configured on the Meta Quest dashboard
private const string CONSUMABLE_1 = "PowerballPack1";
void Start()
{
FetchProductPrices();
FetchPurchasedProducts();
}
// get the current price for the configured IAP item
public void FetchProductPrices()
{
string[] skus = { CONSUMABLE_1 };
IAP.GetProductsBySKU(skus).OnComplete(GetProductsBySKUCallback);
}
void GetProductsBySKUCallback(Message<ProductList> msg)
{
if (msg.IsError)
{
PlatformManager.TerminateWithError(msg);
return;
}
foreach (Product p in msg.GetProductList())
{
Debug.LogFormat("Product: sku:{0} name:{1} price:{2}", p.Sku, p.Name, p.FormattedPrice);
if (p.Sku == CONSUMABLE_1)
{
m_priceText.text = p.FormattedPrice;
}
}
}
// fetches the Durable purchased IAP items. should return none unless you are expanding the
// to sample to include them.
public void FetchPurchasedProducts()
{
IAP.GetViewerPurchases().OnComplete(GetViewerPurchasesCallback);
}
void GetViewerPurchasesCallback(Message<PurchaseList> msg)
{
if (msg.IsError)
{
PlatformManager.TerminateWithError(msg);
return;
}
foreach (Purchase p in msg.GetPurchaseList())
{
Debug.LogFormat("Purchased: sku:{0} granttime:{1} id:{2}", p.Sku, p.GrantTime, p.ID);
}
}
public void BuyPowerBallsPressed()
{
#if UNITY_EDITOR
m_gameController.AddPowerballs(1);
#else
IAP.LaunchCheckoutFlow(CONSUMABLE_1).OnComplete(LaunchCheckoutFlowCallback);
#endif
}
private void LaunchCheckoutFlowCallback(Message<Purchase> msg)
{
if (msg.IsError)
{
PlatformManager.TerminateWithError(msg);
return;
}
Purchase p = msg.GetPurchase();
Debug.Log("purchased " + p.Sku);
m_gameController.AddPowerballs(3);
}
}