Table of Contents

Class IAPModule

Namespace
Titipi.MocaLib2

Wraps Unity IAP v5 for product registration, purchase flow, receipt validation, and restore. Uses the event-driven StoreController API. Supports an optional server-side validation step via IIapPurchaseVerificator. Confirm policy: an order is confirmed with the store only after it has been delivered to the game or proven invalid. On transient failures (verification timeout or error, no restore subscriber) the order is left pending, so the store redelivers it on the next launch — a purchase can be delayed but never lost.

public static class IAPModule
Inheritance
IAPModule
Inherited Members

Properties

Config

The config used to initialize this module.

IsInitialized

Whether Unity IAP is ready for purchases: store connected AND product catalog fetched.

Methods

FetchAdditionalProducts(Action, Action<string>, ProductType, params string[])

Fetches additional products from the store that were not registered at initialization time. onFailed receives the failure reason string.

GetISOCurrencyCode(string)

Returns the ISO 4217 currency code (e.g., "USD") for the given product ID.

GetProductDescription(string)

Returns the localized product description for the given product ID.

GetProductName(string)

Returns the localized product title for the given product ID.

GetProductPrice(string)

Returns the localized price as a decimal for the given product ID.

GetProductPriceString(string)

Returns the formatted price string (e.g., "$0.99") for the given product ID.

InitializeAsync(IAPModuleConfig, List<(string productId, ProductType productType)>)

Initializes Unity IAP v5 with the given product catalog and waits until the store is connected and products are fetched. Returns false if the product list is empty, the store fails to connect, or the initial product fetch fails — in which case it can be called again to retry. Honors the Remote Config kill-switch: when Enabled is false, returns false without connecting to the store — callers never need to check it.

PurchaseProductAsync(string, Action)

Initiates a purchase flow for the given product ID and awaits its completion. Returns the purchased Product on success, or throws IapPurchaseException on failure — check its Reason code rather than parsing the message (e.g. Deferred for Ask-to-Buy, where the grant arrives later via OnRestorePurchases). Only one purchase can be in flight at a time; a concurrent call throws InvalidOperationException. onStartValidate fires when server-side receipt validation begins (optional).

RestorePurchases()

Triggers an iOS purchase restore. Each restored product arrives via OnRestorePurchases — possibly after the underlying store request has already reported completion, so subscribers stay attached. No-op in the Editor.

SetPurchaseVerificator(IIapPurchaseVerificator)

Sets the server-side purchase verificator. Call before any purchase is made. Ignored when UsePurchaseVerification is false.

Events

OnPurchaseDeferred

Fired when a purchase is deferred pending external approval (iOS Ask-to-Buy, Google Play pending transactions). No content is granted yet: the in-flight PurchaseProductAsync(string, Action) fails with Deferred, and once approved — possibly days later — the store redelivers the order and it arrives via OnRestorePurchases.

OnPurchaseStarted

Fired when a purchase flow begins.

OnPurchaseSucceeded

Fired after a purchase initiated by PurchaseProductAsync(string, Action) has succeeded. Parameters: the purchased Product and the raw receipt string (order.Info.Receipt). Wire this to analytics logging calls such as AppsFlyerModule.LogPurchase. Not fired for restored/redelivered purchases — those arrive via OnRestorePurchases, so analytics don't double-count recovered revenue.

OnRestorePurchases

Delivery channel for purchases that arrive outside an active PurchaseProductAsync(string, Action) call: iOS restores, purchases left unconfirmed by a crash, and approved deferred purchases. Subscribe BEFORE InitializeAsync(IAPModuleConfig, List<(string productId, ProductType productType)>) — redeliveries fire during initialization, and an order that arrives while there is no subscriber is left unconfirmed (the store redelivers it next launch: delayed, not lost). Parameters: the Product, the raw receipt string (order.Info.Receipt), and true when the product is the one recorded as pending from a purchase interrupted on this device (UX only — never gate grants on it). Handlers must grant idempotently: the store may redeliver the same order more than once. Use the receipt's transaction ID (see UtilityModule's receipt parsing) to recognize an order you already granted.