Skip to content

In-app purchases (Cocos)

FRVRSDK.instance exposes a full IAP surface for Cocos. The backing store (Facebook IAP, Apple IAP, Google Play Billing, …) is whichever one the host channel uses — you don’t pick it.

if (!FRVRSDK.instance.isIAPReady()) {
  // Don't show buy buttons yet — the catalog isn't loaded
  return;
}

Call this before populating shop UI. The catalog takes a moment to resolve on session start.

const catalog = FRVRSDK.instance.getIAPCatalog();
// { product_id_1: { label, price, priceValue, currencyCode, storeId, ... }, ... }

const product = FRVRSDK.instance.getIAPProduct('coins_100');
// { label, price, priceValue, currencyCode, storeId, ... } | undefined

Use product.price directly in button labels — it’s already localized to the player’s currency.

const purchase = await FRVRSDK.instance.purchase('coins_100', { meta: 'shop_click' });

if (purchase) {
  grantItem(purchase.productId);

  // Consume only for consumables (coins, single-use boosters)
  await FRVRSDK.instance.consumePurchase(purchase);
}

purchase is null / undefined if the user cancelled or the purchase failed. Don’t show an error in those cases — the store UI already handled them.

{
  purchaseId:          string,  // unique id for this transaction
  productId:           string,  // your catalog key
  channelId:           string,  // e.g. "facebook-instant"
  purchaseTime:        number,  // ms since epoch
  transactionId:       string,
  transactionReceipt:  string,  // signed blob — validate server-side
}
  • Consumables (coins, lives, event currency) — call consumePurchase() after granting, so the store allows re‑buying.
  • Durables (remove‑ads, premium skins, season pass) — do not consume. If the player reinstalls or switches devices, restore them via the unconsumed‑purchases check below.

If the game crashed between a successful purchase and granting the item, the store keeps the receipt in a pending state. Run this at boot:

const unconsumed = await FRVRSDK.instance.getUnconsumedPurchases();
for (const purchase of unconsumed) {
  grantItem(purchase.productId);
  await FRVRSDK.instance.consumePurchase(purchase);
}

This is also how you restore durables on a new device — granting a durable is idempotent in your own code, so it’s safe to re‑run.

  • Product catalog setup, error‑type semantics: Web SDK IAP.