Sell products & subscriptions
List store products, start a purchase, restore entitlements, and consume consumables from the App Store and Google Play.
Load your product catalog
Fetch localized products for a paywall. Unknown store ids come back in invalidIds. Each product is a BdkIapProduct — kind is consumable, nonConsumable, subscription, or nonRenewingSubscription.
In a plain browser the command doesn't run; the returned object has no ok field and triggered: false.
This feature can be switched off in a given app build. Check await bdk.capabilities.has("iap") before showing the paywall. When it is off, the call resolves ok: false with code: "common/feature_disabled". See Detect features.
The previous-generation purchase flow (purchaseIos / purchaseAndroid) is documented at In-app purchases and remains supported.
Start a purchase
Open the store sheet. The call resolves { state: "launched" } — that is not a sale. The outcome arrives on iap.purchaseCompleted, so subscribe before you call.
Pass planId and offerId from the product's subscription plans when you buy a subscription.
Subscribe to iap.purchaseCompleted before you call. A deferred grant re-emits later — keep a persistent listener, not a one-shot.
Purchase and wait
Wait for the first outcome (purchased, pending, cancelled, or failed). pending is deferred approval — the grant arrives later on iap.purchaseCompleted, so keep a persistent listener.
purchaseAndWait takes the same options as purchase, plus timeoutMs to bound the wait for that first outcome (the store sheet, not a later deferred grant).
A pending result is not a grant. Do not unlock. The persistent listener receives the later purchased event.
Check entitlements
Read what the store currently says the user owns. Each item is a BdkIapEntitlement — state is active, gracePeriod, billingRetry, revoked, or expired.
Restore purchases
Ask the store to restore previous purchases and subscriptions. Use it on a restore button. The call returns the restored entitlements.
Get the raw receipt
Read the material your server needs to verify a purchase. On iOS you get receipt plus jws; on Android you get purchases (productId, purchaseToken, packageName, productType).
Treat a client purchased event as the store reporting a transaction. Verify on the server before granting access — see Verify purchases.
Consume a consumable
Mark a consumable as used so the user can buy it again. Pass the product id. On iOS, remaining is the locally tracked count after the consume.
React to renewals and revocations
Listen for subscription renewals, revocations, and transactions that started outside your UI. Subscribe once at startup, then refresh entitlements.