openRedeemOfferCode
Open the platform's offer/promo code redemption flow so the user can enter a code. Replaces the deprecated presentCodeRedemptionSheetIOS and openRedeemOfferCodeAndroid, both scheduled for removal in OpenIAP 4.0.
Available in OpenIAP Spec 3.3.0 / openiap-apple 3.3.0 / openiap-google 3.4.0.
iOS: Presents the App Store offer code redemption sheet. Xcode 27+ builds running on iOS 27+, Mac Catalyst 27+, or visionOS 27+ resolve the verified redeemed purchase; older sheet APIs resolve null after presentation. Apple docs. Android: On Google Play builds, launches the Play Store redeem page (https://play.google.com/redeem) and resolves null; the billing client does not need to be initialized. Meta Horizon and Amazon Appstore have no equivalent redemption surface and resolve null without launching anything.
Redeemed purchases are delivered through the standard purchase listeners. Register purchaseUpdatedListener before calling, and always reconcile with getAvailablePurchases when the app resumes — the complete reconciliation sequence is in the Offer Code Redemption guide.
Signature
func openRedeemOfferCode() async throws -> PurchaseIOS?Returns#
Promise<Purchase | null> — the verified redeemed Purchase only on Apple 27+ runtimes from Xcode 27+ builds. Every other outcome resolves null:
- iOS 15–26 / visionOS 1–26: the system sheet was presented, but that API path cannot return the transaction directly.
- Google Play: the Play Store redeem page was launched; the redemption completes outside the app.
- Meta Horizon / Amazon Appstore: no redemption flow exists, so nothing was launched.
Throws#
Only when a redemption flow exists but cannot be presented or launched — for example, no active window scene or view controller on iOS, or the Play Store deep link fails to open. Apple platforms without the redemption sheet (macOS, tvOS, watchOS) throw FeatureNotSupported. Stores without a redemption flow resolve null instead of throwing. Until wrappers adopt openiap-google 3.4.0, a failed Play launch surfaces per SDK: kmp-iap already throws; react-native/expo/flutter/maui resolve null (the released native API reports it as a plain false) while native exceptions still throw; godot resolves null for all Android failures.
Example
let purchase = try await OpenIapModule.shared.openRedeemOfferCode()
if let purchase {
print("Verified redemption:", purchase.productId)
}Live example: expo-iap · react-native-iap · flutter_inapp_purchase · kmp-iap