@@ -32,6 +32,7 @@ class ExpoIapModule :
32
32
const val E_INIT_CONNECTION = " E_INIT_CONNECTION"
33
33
const val E_QUERY_PRODUCT = " E_QUERY_PRODUCT"
34
34
const val EMPTY_SKU_LIST = " EMPTY_SKU_LIST"
35
+ private const val PROMISE_BUY_ITEM = " PROMISE_BUY_ITEM"
35
36
}
36
37
37
38
object IapEvent {
@@ -62,7 +63,12 @@ class ExpoIapModule :
62
63
val errorData = PlayUtils .getBillingResponseData(responseCode)
63
64
error[" code" ] = errorData.code
64
65
error[" message" ] = errorData.message
65
- sendEvent(IapEvent .PURCHASE_ERROR , error.toMap())
66
+ try {
67
+ sendEvent(IapEvent .PURCHASE_ERROR , error.toMap())
68
+ } catch (e: Exception ) {
69
+ Log .e(TAG , " Failed to send PURCHASE_ERROR event: ${e.message} " )
70
+ }
71
+ PromiseUtils .rejectPromisesForKey(PROMISE_BUY_ITEM , errorData.code, errorData.message, null )
66
72
return
67
73
}
68
74
@@ -90,8 +96,13 @@ class ExpoIapModule :
90
96
item[" obfuscatedProfileIdAndroid" ] = accountIdentifiers.obfuscatedProfileId
91
97
}
92
98
promiseItems.add(item.toMap())
93
- sendEvent(IapEvent .PURCHASE_UPDATED , item.toMap())
99
+ try {
100
+ sendEvent(IapEvent .PURCHASE_UPDATED , item.toMap())
101
+ } catch (e: Exception ) {
102
+ Log .e(TAG , " Failed to send PURCHASE_UPDATED event: ${e.message} " )
103
+ }
94
104
}
105
+ PromiseUtils .resolvePromisesForKey(PROMISE_BUY_ITEM , promiseItems)
95
106
} else {
96
107
val result =
97
108
mutableMapOf<String , Any ?>(
@@ -100,7 +111,12 @@ class ExpoIapModule :
100
111
" extraMessage" to
101
112
" The purchases are null. This is a normal behavior if you have requested DEFERRED proration. If not please report an issue." ,
102
113
)
103
- sendEvent(IapEvent .PURCHASE_UPDATED , result.toMap())
114
+ try {
115
+ sendEvent(IapEvent .PURCHASE_UPDATED , result.toMap())
116
+ } catch (e: Exception ) {
117
+ Log .e(TAG , " Failed to send PURCHASE_UPDATED event: ${e.message} " )
118
+ }
119
+ PromiseUtils .resolvePromisesForKey(PROMISE_BUY_ITEM , result)
104
120
}
105
121
}
106
122
@@ -301,22 +317,29 @@ class ExpoIapModule :
301
317
val isOfferPersonalized = params[" isOfferPersonalized" ] as ? Boolean ? : false
302
318
303
319
if (currentActivity == null ) {
304
- throw Exception (" getCurrentActivity returned null" )
320
+ promise.reject(" E_UNKNOWN" , " getCurrentActivity returned null" , null )
321
+ return @AsyncFunction
305
322
}
306
323
307
324
ensureConnection(promise) { billingClient ->
325
+ PromiseUtils .addPromiseForKey(PROMISE_BUY_ITEM , promise)
326
+
308
327
if (type == BillingClient .ProductType .SUBS && skuArr.size != offerTokenArr.size) {
309
- val debugMessage =
310
- " The number of skus (${skuArr.size} ) must match: the number of offerTokens (${offerTokenArr.size} ) for Subscriptions"
311
- sendEvent(
312
- IapEvent .PURCHASE_ERROR ,
313
- mapOf (
314
- " debugMessage" to debugMessage,
315
- " code" to " E_SKU_OFFER_MISMATCH" ,
316
- " message" to debugMessage,
317
- ),
318
- )
319
- throw Exception (debugMessage)
328
+ val debugMessage = " The number of skus (${skuArr.size} ) must match: the number of offerTokens (${offerTokenArr.size} ) for Subscriptions"
329
+ try {
330
+ sendEvent(
331
+ IapEvent .PURCHASE_ERROR ,
332
+ mapOf (
333
+ " debugMessage" to debugMessage,
334
+ " code" to " E_SKU_OFFER_MISMATCH" ,
335
+ " message" to debugMessage,
336
+ )
337
+ )
338
+ } catch (e: Exception ) {
339
+ Log .e(TAG , " Failed to send PURCHASE_ERROR event: ${e.message} " )
340
+ }
341
+ promise.reject(" E_SKU_OFFER_MISMATCH" , debugMessage, null )
342
+ return @ensureConnection
320
343
}
321
344
322
345
val productParamsList =
@@ -325,16 +348,21 @@ class ExpoIapModule :
325
348
if (selectedSku == null ) {
326
349
val debugMessage =
327
350
" The sku was not found. Please fetch products first by calling getItems"
328
- sendEvent(
329
- IapEvent .PURCHASE_ERROR ,
330
- mapOf (
331
- " debugMessage" to debugMessage,
332
- " code" to " E_SKU_NOT_FOUND" ,
333
- " message" to debugMessage,
334
- " productId" to sku,
335
- ),
336
- )
337
- throw Exception (debugMessage)
351
+ try {
352
+ sendEvent(
353
+ IapEvent .PURCHASE_ERROR ,
354
+ mapOf (
355
+ " debugMessage" to debugMessage,
356
+ " code" to " E_SKU_NOT_FOUND" ,
357
+ " message" to debugMessage,
358
+ " productId" to sku,
359
+ ),
360
+ )
361
+ } catch (e: Exception ) {
362
+ Log .e(TAG , " Failed to send PURCHASE_ERROR event: ${e.message} " )
363
+ }
364
+ promise.reject(" E_SKU_NOT_FOUND" , debugMessage, null )
365
+ return @ensureConnection
338
366
}
339
367
340
368
val productDetailParams =
@@ -378,7 +406,6 @@ class ExpoIapModule :
378
406
}
379
407
subscriptionUpdateParams.setSubscriptionReplacementMode(mode)
380
408
}
381
-
382
409
builder.setSubscriptionUpdateParams(subscriptionUpdateParams.build())
383
410
}
384
411
@@ -389,14 +416,10 @@ class ExpoIapModule :
389
416
val billingResult = billingClient.launchBillingFlow(currentActivity, flowParams)
390
417
391
418
if (billingResult.responseCode != BillingClient .BillingResponseCode .OK ) {
392
- promise.reject(
393
- " Billing Error" ,
394
- billingResult.debugMessage,
395
- null ,
396
- )
419
+ val errorData = PlayUtils .getBillingResponseData(billingResult.responseCode)
420
+ promise.reject(errorData.code, billingResult.debugMessage, null )
421
+ return @ensureConnection
397
422
}
398
-
399
- promise.resolve(true )
400
423
}
401
424
}
402
425
0 commit comments