requestPurchase

Initiate a purchase flow. The result is delivered through purchaseUpdatedListener, not the return value.

iOS: Calls Product.purchase(options:) and emits the result on the Transaction.updates listener — the return value is just the dispatch ack. Apple docs. Android: Calls BillingClient.launchBillingFlow and emits the result on PurchasesUpdatedListener. Subscription offers require an offerToken. Google docs.

Signature

swift
func requestPurchase(_ params: RequestPurchaseProps) async throws -> RequestPurchaseResult?

Parameters#

Pass a single RequestPurchaseProps, discriminated by type:

  • type (required, 'in-app' | 'subs') — Selects the request shape. Use 'in-app' for one-time products and 'subs' for subscriptions.
  • request.apple.sku (iOS only, string) iOS. Single SKU for the iOS purchase.
  • request.apple.appAccountToken (optional, string) iOS. UUID-format account token forwarded to Apple. Non-UUID values land as null on the resulting Purchase.
  • request.apple.quantity (optional, number) iOS. Quantity for consumable bulk purchases.
  • request.apple.billingPlanType (subscriptions only, optional, 'monthly' | 'up-front') iOS 26.4+. Selects the StoreKit subscription billing plan, such as monthly billing with a 12-month commitment. See iOS commitment billing plans.
  • request.google.skus (Android only, string[]) Android. Product SKUs to launch the Play purchase flow for.
  • request.google.subscriptionOffers (required for 'subs', { sku: string; offerToken: string }[]) Android. Required for subscription requests; pair each SKU with its offerToken from fetchProducts.
  • request.google.obfuscatedAccountIdAndroid (optional, string) Android. Optional account identifier passed to Play.
  • request.google.obfuscatedProfileIdAndroid (optional, string) Android. Optional profile identifier passed to Play.

Returns#

Promise<Purchase | void> — dispatched purchase payload. Do not rely on this for the actual outcome — listen via purchaseUpdatedListener / purchaseErrorListener instead.

Throws#

Invalid arguments or failures that prevent dispatch can reject the promise. Store outcomes are event-based in React Native; Android not-prepared arrives through purchaseErrorListener or the hook's onPurchaseError callback.

Example

swift
guard try await OpenIapModule.shared.initConnection() else { return }
try await OpenIapModule.shared.requestPurchase(
    RequestPurchaseProps(
        request: .purchase(RequestPurchasePropsByPlatforms(
            apple: RequestPurchaseIosProps(sku: "com.app.premium")
        )),
        type: .inApp
    )
)