@@ -170,26 +170,51 @@ public final class OpenIapModule: NSObject, OpenIapModuleProtocol {
170170 let iosProps = try resolveIosPurchaseProps ( from: params)
171171 let sku = iosProps. sku
172172 let product = try await storeProduct ( for: sku)
173- let options = StoreKitTypesBridge . purchaseOptions ( from: iosProps)
173+ let options = try StoreKitTypesBridge . purchaseOptions ( from: iosProps)
174174
175175 let result : StoreKit . Product . PurchaseResult
176- #if canImport(UIKit)
177- if #available( iOS 17 . 0 , * ) {
178- let scene : UIWindowScene ? = await MainActor . run {
179- UIApplication . shared. connectedScenes. first as? UIWindowScene
180- }
181- guard let scene else {
182- let error = makePurchaseError ( code: . purchaseError, message: " Could not find window scene " )
183- emitPurchaseError ( error)
184- throw error
176+ do {
177+ #if canImport(UIKit)
178+ if #available( iOS 17 . 0 , * ) {
179+ let scene : UIWindowScene ? = await MainActor . run {
180+ UIApplication . shared. connectedScenes. first as? UIWindowScene
181+ }
182+ guard let scene else {
183+ let error = makePurchaseError ( code: . purchaseError, message: " Could not find window scene " )
184+ emitPurchaseError ( error)
185+ throw error
186+ }
187+ result = try await product. purchase ( confirmIn: scene, options: options)
188+ } else {
189+ result = try await product. purchase ( options: options)
185190 }
186- result = try await product. purchase ( confirmIn: scene, options: options)
187- } else {
191+ #else
188192 result = try await product. purchase ( options: options)
193+ #endif
194+ } catch {
195+ // Enhanced error handling for promotional offers
196+ if iosProps. withOffer != nil {
197+ OpenIapLog . error ( " Purchase with promotional offer failed: \( error. localizedDescription) " )
198+ let enhancedMessage = """
199+ Promotional offer purchase failed: \( error. localizedDescription)
200+
201+ Common causes:
202+ 1. Invalid signature - verify server generates correct signature
203+ 2. Sandbox testing - ensure current subscription has expired before testing offers
204+ 3. Offer eligibility - user may not be eligible for this promotional offer
205+ 4. Key mismatch - verify using correct In-App Purchase key for environment
206+ """
207+ let purchaseError = makePurchaseError (
208+ code: . purchaseError,
209+ productId: sku,
210+ message: enhancedMessage
211+ )
212+ emitPurchaseError ( purchaseError)
213+ throw purchaseError
214+ }
215+ // Re-throw original error for non-promotional purchases
216+ throw error
189217 }
190- #else
191- result = try await product. purchase ( options: options)
192- #endif
193218
194219 switch result {
195220 case . success( let verification) :
0 commit comments