fetchProducts
Retrieve in-app products, subscriptions, or a mixed result from the store by SKU.
iOS: Wraps Product.products(for:) (StoreKit 2). Fetches the localized price/title for each SKU. Unknown SKUs are simply omitted from the returned array — only transport failures (network, store unavailable, etc.) throw. Apple docs. Android: Calls BillingClient.queryProductDetailsAsync with the right ProductType (INAPP/SUBS) per request. Unknown SKUs return an empty list, not an error. Google docs. When type is 'all', Android queries both INAPP and SUBS product details and returns a mixed result that preserves product and subscription variants.
Note about request* APIs#
Signature
func fetchProducts(_ params: ProductRequest) async throws -> FetchProductsResultParameters#
Pass a single ProductRequest object:
skus(required,string[]) — Product identifiers to fetch.type(optional,'in-app' | 'subs' | 'all', default'in-app') — Filter by product kind. Use'all'to query both in one call.
Returns#
Promise<FetchProductsResult> — sealed union, discriminated by the request type:
Product[](fortype: 'in-app') — Array of one-time products. Empty array if none of the SKUs exist.ProductSubscription[](fortype: 'subs') — Array of subscription products with offer details.(Product | ProductSubscription)[](fortype: 'all') — Mixed array that preserves each item as either a product or a subscription. TypeScript-based wrappers expose this as a flat discriminated union; generated Kotlin, Dart, and C# schema handlers expose the same contract through their language-specific union wrappers.null(legacy) — Older schema branch retained for backwards compatibility.
Fetch all product types#
Use type: 'all' only when you intentionally want one request to return both in-app products and subscriptions. If type is omitted, OpenIAP defaults to in-app products.
let result = try await OpenIapModule.shared.fetchProducts(
ProductRequest(skus: ["com.app.coins_100", "com.app.monthly"], type: .all)
)
if case let .all(items) = result {
for item in items ?? [] {
switch item {
case let .product(product):
print("in-app product \(product.id)")
case let .productSubscription(subscription):
print("subscription \(subscription.id)")
}
}
}Example
let products = try await OpenIapModule.shared.fetchProducts(
ProductRequest(skus: ["com.app.premium"], type: .inApp)
)See: Product, ProductSubscription