expo-iap 3.1.1 → 3.1.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (42) hide show
  1. package/android/src/main/java/expo/modules/iap/ExpoIapHelper.kt +171 -0
  2. package/android/src/main/java/expo/modules/iap/ExpoIapLog.kt +4 -0
  3. package/android/src/main/java/expo/modules/iap/ExpoIapModule.kt +50 -114
  4. package/build/types.d.ts +34 -34
  5. package/build/types.js +34 -34
  6. package/build/types.js.map +1 -1
  7. package/build/utils/errorMapping.d.ts +7 -8
  8. package/build/utils/errorMapping.d.ts.map +1 -1
  9. package/build/utils/errorMapping.js +83 -53
  10. package/build/utils/errorMapping.js.map +1 -1
  11. package/coverage/clover.xml +506 -0
  12. package/coverage/coverage-final.json +6 -0
  13. package/coverage/lcov-report/base.css +224 -0
  14. package/coverage/lcov-report/block-navigation.js +87 -0
  15. package/coverage/lcov-report/favicon.png +0 -0
  16. package/coverage/lcov-report/index.html +161 -0
  17. package/coverage/lcov-report/prettify.css +1 -0
  18. package/coverage/lcov-report/prettify.js +2 -0
  19. package/coverage/lcov-report/sort-arrow-sprite.png +0 -0
  20. package/coverage/lcov-report/sorter.js +196 -0
  21. package/coverage/lcov-report/src/helpers/index.html +116 -0
  22. package/coverage/lcov-report/src/helpers/subscription.ts.html +496 -0
  23. package/coverage/lcov-report/src/index.html +116 -0
  24. package/coverage/lcov-report/src/index.ts.html +1993 -0
  25. package/coverage/lcov-report/src/modules/android.ts.html +550 -0
  26. package/coverage/lcov-report/src/modules/index.html +131 -0
  27. package/coverage/lcov-report/src/modules/ios.ts.html +1222 -0
  28. package/coverage/lcov-report/src/utils/errorMapping.ts.html +1126 -0
  29. package/coverage/lcov-report/src/utils/index.html +116 -0
  30. package/coverage/lcov.info +959 -0
  31. package/ios/ExpoIapHelper.swift +101 -6
  32. package/ios/ExpoIapModule.swift +29 -97
  33. package/jest.config.js +0 -1
  34. package/openiap-versions.json +2 -2
  35. package/package.json +1 -1
  36. package/src/types.ts +34 -34
  37. package/src/utils/errorMapping.ts +101 -82
  38. package/build/utils/constants.d.ts +0 -6
  39. package/build/utils/constants.d.ts.map +0 -1
  40. package/build/utils/constants.js +0 -19
  41. package/build/utils/constants.js.map +0 -1
  42. package/src/utils/constants.ts +0 -23
@@ -0,0 +1,171 @@
1
+ package expo.modules.iap
2
+
3
+ import android.util.Log
4
+ import dev.hyo.openiap.AndroidSubscriptionOfferInput
5
+ import dev.hyo.openiap.OpenIapModule
6
+ import dev.hyo.openiap.ProductQueryType
7
+ import expo.modules.kotlin.Promise
8
+ import expo.modules.kotlin.modules.Module
9
+ import kotlinx.coroutines.CoroutineScope
10
+ import kotlinx.coroutines.launch
11
+ import java.util.Locale
12
+ import java.util.concurrent.ConcurrentLinkedQueue
13
+
14
+ object ExpoIapHelper {
15
+ private const val TAG = "ExpoIapHelper"
16
+ private const val MAX_BUFFERED_EVENTS = 200
17
+
18
+ fun emitOrQueue(
19
+ module: Module,
20
+ scope: CoroutineScope,
21
+ connectionReady: java.util.concurrent.atomic.AtomicBoolean,
22
+ pendingEvents: ConcurrentLinkedQueue<Pair<String, Map<String, Any?>>>,
23
+ name: String,
24
+ payload: Map<String, Any?>,
25
+ ) {
26
+ if (connectionReady.get()) {
27
+ // Ensure event emission occurs on the main dispatcher
28
+ scope.launch { module.sendEvent(name, payload) }
29
+ return
30
+ }
31
+ // Bound the buffer to prevent unbounded growth if init stalls
32
+ if (pendingEvents.size >= MAX_BUFFERED_EVENTS) {
33
+ pendingEvents.poll()
34
+ ExpoIapLog.warning("pendingEvents overflow; dropping oldest")
35
+ }
36
+ pendingEvents.add(name to payload)
37
+ }
38
+
39
+ fun parseProductQueryType(rawType: String?): ProductQueryType {
40
+ val normalized =
41
+ rawType
42
+ ?.trim()
43
+ ?.lowercase(Locale.US)
44
+ ?.replace("-", "")
45
+ ?.replace("_", "")
46
+
47
+ return when (normalized) {
48
+ "subs" -> ProductQueryType.Subs
49
+ "all" -> ProductQueryType.All
50
+ else -> ProductQueryType.InApp
51
+ }
52
+ }
53
+
54
+ fun parseRequestPurchaseParams(params: Map<String, Any?>): RequestPurchaseParams {
55
+ val type = params["type"] as? String
56
+ val skus: List<String> =
57
+ (params["skus"] as? List<*>)?.filterIsInstance<String>()
58
+ ?: (params["skuArr"] as? List<*>)?.filterIsInstance<String>()
59
+ ?: emptyList()
60
+ val obfuscatedAccountId =
61
+ (params["obfuscatedAccountIdAndroid"] ?: params["obfuscatedAccountId"]) as? String
62
+ val obfuscatedProfileId =
63
+ (params["obfuscatedProfileIdAndroid"] ?: params["obfuscatedProfileId"]) as? String
64
+ val isOfferPersonalized = params["isOfferPersonalized"] as? Boolean ?: false
65
+ val offerTokenArr =
66
+ (params["offerTokenArr"] as? List<*>)?.filterIsInstance<String>() ?: emptyList()
67
+ val explicitSubscriptionOffers =
68
+ (params["subscriptionOffers"] as? List<*>)?.mapNotNull { rawOffer ->
69
+ val offerMap = rawOffer as? Map<*, *> ?: return@mapNotNull null
70
+ val sku = offerMap["sku"] as? String
71
+ val offerToken = offerMap["offerToken"] as? String
72
+ if (sku.isNullOrEmpty() || offerToken.isNullOrEmpty()) {
73
+ null
74
+ } else {
75
+ AndroidSubscriptionOfferInput(offerToken = offerToken, sku = sku)
76
+ }
77
+ } ?: emptyList()
78
+ val purchaseToken =
79
+ (params["purchaseTokenAndroid"] ?: params["purchaseToken"]) as? String
80
+ val replacementMode =
81
+ (params["replacementModeAndroid"] ?: params["replacementMode"]) as? Number
82
+
83
+ return RequestPurchaseParams(
84
+ type = type,
85
+ skus = skus,
86
+ obfuscatedAccountId = obfuscatedAccountId,
87
+ obfuscatedProfileId = obfuscatedProfileId,
88
+ isOfferPersonalized = isOfferPersonalized,
89
+ offerTokenArr = offerTokenArr,
90
+ explicitSubscriptionOffers = explicitSubscriptionOffers,
91
+ purchaseToken = purchaseToken,
92
+ replacementMode = replacementMode,
93
+ )
94
+ }
95
+
96
+ data class RequestPurchaseParams(
97
+ val type: String?,
98
+ val skus: List<String>,
99
+ val obfuscatedAccountId: String?,
100
+ val obfuscatedProfileId: String?,
101
+ val isOfferPersonalized: Boolean,
102
+ val offerTokenArr: List<String>,
103
+ val explicitSubscriptionOffers: List<AndroidSubscriptionOfferInput>,
104
+ val purchaseToken: String?,
105
+ val replacementMode: Number?,
106
+ )
107
+
108
+ fun addPurchasePromise(promise: Promise) {
109
+ PromiseUtils.addPromiseForKey(PromiseUtils.PROMISE_BUY_ITEM, promise)
110
+ }
111
+
112
+ fun resolvePurchasePromises(purchases: List<Map<String, Any?>>) {
113
+ PromiseUtils.resolvePromisesForKey(
114
+ PromiseUtils.PROMISE_BUY_ITEM,
115
+ purchases,
116
+ )
117
+ }
118
+
119
+ fun rejectPurchasePromises(
120
+ code: String,
121
+ message: String?,
122
+ error: Exception?,
123
+ ) {
124
+ PromiseUtils.rejectPromisesForKey(
125
+ PromiseUtils.PROMISE_BUY_ITEM,
126
+ code,
127
+ message,
128
+ error,
129
+ )
130
+ }
131
+
132
+ fun setupListeners(
133
+ openIap: OpenIapModule,
134
+ module: Module,
135
+ scope: CoroutineScope,
136
+ connectionReady: java.util.concurrent.atomic.AtomicBoolean,
137
+ pendingEvents: ConcurrentLinkedQueue<Pair<String, Map<String, Any?>>>,
138
+ eventPurchaseUpdated: String,
139
+ eventPurchaseError: String,
140
+ ) {
141
+ openIap.addPurchaseUpdateListener { p ->
142
+ runCatching {
143
+ emitOrQueue(
144
+ module,
145
+ scope,
146
+ connectionReady,
147
+ pendingEvents,
148
+ eventPurchaseUpdated,
149
+ p.toJson(),
150
+ )
151
+ }.onFailure { android.util.Log.e(TAG, "Failed to buffer/send PURCHASE_UPDATED", it) }
152
+ }
153
+ openIap.addPurchaseErrorListener { e ->
154
+ runCatching {
155
+ emitOrQueue(
156
+ module,
157
+ scope,
158
+ connectionReady,
159
+ pendingEvents,
160
+ eventPurchaseError,
161
+ e.toJSON(),
162
+ )
163
+ }.onFailure { android.util.Log.e(TAG, "Failed to buffer/send PURCHASE_ERROR", it) }
164
+ }
165
+ }
166
+
167
+ fun cleanupListeners(openIap: OpenIapModule) {
168
+ // Android doesn't have explicit listeners to clean up
169
+ // This function is kept for API compatibility with iOS
170
+ }
171
+ }
@@ -28,6 +28,10 @@ internal object ExpoIapLog {
28
28
  Log.e(TAG, "$name failed: ${error.localizedMessage}", error)
29
29
  }
30
30
 
31
+ fun warning(message: String) {
32
+ Log.w(TAG, message)
33
+ }
34
+
31
35
  fun debug(message: String) {
32
36
  Log.d(TAG, message)
33
37
  }
@@ -28,7 +28,6 @@ import kotlinx.coroutines.Job
28
28
  import kotlinx.coroutines.launch
29
29
  import kotlinx.coroutines.sync.Mutex
30
30
  import kotlinx.coroutines.sync.withLock
31
- import java.util.Locale
32
31
  import java.util.concurrent.ConcurrentLinkedQueue
33
32
  import java.util.concurrent.atomic.AtomicBoolean
34
33
 
@@ -53,38 +52,6 @@ class ExpoIapModule : Module() {
53
52
  private val connectionReady = AtomicBoolean(false)
54
53
  private val connectionMutex = Mutex()
55
54
 
56
- private fun emitOrQueue(
57
- name: String,
58
- payload: Map<String, Any?>,
59
- ) {
60
- if (connectionReady.get()) {
61
- // Ensure event emission occurs on the main dispatcher
62
- scope.launch { sendEvent(name, payload) }
63
- return
64
- }
65
- // Bound the buffer to prevent unbounded growth if init stalls
66
- if (pendingEvents.size >= MAX_BUFFERED_EVENTS) {
67
- pendingEvents.poll()
68
- Log.w(TAG, "pendingEvents overflow; dropping oldest")
69
- }
70
- pendingEvents.add(name to payload)
71
- }
72
-
73
- private fun parseProductQueryType(rawType: String?): ProductQueryType {
74
- val normalized =
75
- rawType
76
- ?.trim()
77
- ?.lowercase(Locale.US)
78
- ?.replace("-", "")
79
- ?.replace("_", "")
80
-
81
- return when (normalized) {
82
- "subs" -> ProductQueryType.Subs
83
- "all" -> ProductQueryType.All
84
- else -> ProductQueryType.InApp
85
- }
86
- }
87
-
88
55
  override fun definition() =
89
56
  ModuleDefinition {
90
57
  Name("ExpoIap")
@@ -101,7 +68,6 @@ class ExpoIapModule : Module() {
101
68
  connectionMutex.withLock {
102
69
  try {
103
70
  // Activity may be unavailable in headless/background scenarios.
104
- // Attempt to set it, but do not fail init if missing.
105
71
  runCatching { openIap.setActivity(currentActivity) }
106
72
  .onFailure { Log.w(TAG, "initConnection: Activity missing; proceeding headless", it) }
107
73
 
@@ -115,15 +81,15 @@ class ExpoIapModule : Module() {
115
81
  // Attach listeners early to avoid races during init
116
82
  if (!listenersAttached) {
117
83
  listenersAttached = true
118
- openIap.addPurchaseUpdateListener { p ->
119
- runCatching {
120
- emitOrQueue(EVENT_PURCHASE_UPDATED, p.toJson())
121
- }.onFailure { Log.e(TAG, "Failed to buffer/send PURCHASE_UPDATED", it) }
122
- }
123
- openIap.addPurchaseErrorListener { e ->
124
- runCatching { emitOrQueue(EVENT_PURCHASE_ERROR, e.toJSON()) }
125
- .onFailure { Log.e(TAG, "Failed to buffer/send PURCHASE_ERROR", it) }
126
- }
84
+ ExpoIapHelper.setupListeners(
85
+ openIap,
86
+ this@ExpoIapModule,
87
+ scope,
88
+ connectionReady,
89
+ pendingEvents,
90
+ EVENT_PURCHASE_UPDATED,
91
+ EVENT_PURCHASE_ERROR,
92
+ )
127
93
  }
128
94
 
129
95
  val ok = openIap.initConnection()
@@ -131,10 +97,7 @@ class ExpoIapModule : Module() {
131
97
  if (!ok) {
132
98
  // Clear any buffered events from a failed init
133
99
  pendingEvents.clear()
134
- ExpoIapLog.failure(
135
- "initConnection",
136
- IllegalStateException("Failed to initialize connection"),
137
- )
100
+ ExpoIapLog.failure("initConnection", IllegalStateException("Failed to initialize connection"))
138
101
  promise.reject(OpenIapError.InitConnection.CODE, "Failed to initialize connection", null)
139
102
  return@withLock
140
103
  }
@@ -163,9 +126,11 @@ class ExpoIapModule : Module() {
163
126
  scope.launch {
164
127
  connectionMutex.withLock {
165
128
  runCatching { openIap.endConnection() }
129
+ ExpoIapHelper.cleanupListeners(openIap)
166
130
  // Reset connection state and clear any buffered events
167
131
  connectionReady.set(false)
168
132
  pendingEvents.clear()
133
+ listenersAttached = false
169
134
  ExpoIapLog.result("endConnection", true)
170
135
  promise.resolve(true)
171
136
  }
@@ -179,7 +144,7 @@ class ExpoIapModule : Module() {
179
144
  )
180
145
  scope.launch {
181
146
  try {
182
- val queryType = parseProductQueryType(type)
147
+ val queryType = ExpoIapHelper.parseProductQueryType(type)
183
148
  val request = ProductRequest(skuArr.toList(), queryType)
184
149
  val result = openIap.fetchProducts(request)
185
150
  val payload =
@@ -216,18 +181,10 @@ class ExpoIapModule : Module() {
216
181
  AsyncFunction("deepLinkToSubscriptionsAndroid") { params: Map<String, Any?>, promise: Promise ->
217
182
  val sku = (params["sku"] ?: params["skuAndroid"]) as? String
218
183
  val packageName = (params["packageName"] ?: params["packageNameAndroid"]) as? String
219
- ExpoIapLog.payload(
220
- "deepLinkToSubscriptionsAndroid",
221
- mapOf("sku" to sku, "packageName" to packageName),
222
- )
184
+ ExpoIapLog.payload("deepLinkToSubscriptionsAndroid", mapOf("sku" to sku, "packageName" to packageName))
223
185
  scope.launch {
224
186
  try {
225
- openIap.deepLinkToSubscriptions(
226
- DeepLinkOptions(
227
- packageNameAndroid = packageName,
228
- skuAndroid = sku,
229
- ),
230
- )
187
+ openIap.deepLinkToSubscriptions(DeepLinkOptions(packageNameAndroid = packageName, skuAndroid = sku))
231
188
  ExpoIapLog.result("deepLinkToSubscriptionsAndroid", true)
232
189
  promise.resolve(null)
233
190
  } catch (e: Exception) {
@@ -254,43 +211,17 @@ class ExpoIapModule : Module() {
254
211
 
255
212
  AsyncFunction("requestPurchase") { params: Map<String, Any?>, promise: Promise ->
256
213
  ExpoIapLog.payload("requestPurchaseAndroid", params)
257
- val type = params["type"] as? String
258
- val skus: List<String> =
259
- (params["skus"] as? List<*>)?.filterIsInstance<String>()
260
- ?: (params["skuArr"] as? List<*>)?.filterIsInstance<String>()
261
- ?: emptyList()
262
- val obfuscatedAccountId =
263
- (params["obfuscatedAccountIdAndroid"] ?: params["obfuscatedAccountId"]) as? String
264
- val obfuscatedProfileId =
265
- (params["obfuscatedProfileIdAndroid"] ?: params["obfuscatedProfileId"]) as? String
266
- val isOfferPersonalized = params["isOfferPersonalized"] as? Boolean ?: false
267
- val offerTokenArr =
268
- (params["offerTokenArr"] as? List<*>)?.filterIsInstance<String>() ?: emptyList()
269
- val explicitSubscriptionOffers =
270
- (params["subscriptionOffers"] as? List<*>)?.mapNotNull { rawOffer ->
271
- val offerMap = rawOffer as? Map<*, *> ?: return@mapNotNull null
272
- val sku = offerMap["sku"] as? String
273
- val offerToken = offerMap["offerToken"] as? String
274
- if (sku.isNullOrEmpty() || offerToken.isNullOrEmpty()) {
275
- null
276
- } else {
277
- AndroidSubscriptionOfferInput(offerToken = offerToken, sku = sku)
278
- }
279
- } ?: emptyList()
280
- val purchaseToken =
281
- (params["purchaseTokenAndroid"] ?: params["purchaseToken"]) as? String
282
- val replacementMode =
283
- (params["replacementModeAndroid"] ?: params["replacementMode"]) as? Number
214
+ val parsedParams = ExpoIapHelper.parseRequestPurchaseParams(params)
284
215
 
285
216
  val productType =
286
- when (parseProductQueryType(type)) {
217
+ when (ExpoIapHelper.parseProductQueryType(parsedParams.type)) {
287
218
  ProductQueryType.Subs -> ProductQueryType.Subs
288
219
  else -> ProductQueryType.InApp
289
220
  }
290
221
 
291
222
  val fallbackOffers =
292
- if (explicitSubscriptionOffers.isEmpty() && offerTokenArr.isNotEmpty()) {
293
- skus.zip(offerTokenArr).mapNotNull { (sku, token) ->
223
+ if (parsedParams.explicitSubscriptionOffers.isEmpty() && parsedParams.offerTokenArr.isNotEmpty()) {
224
+ parsedParams.skus.zip(parsedParams.offerTokenArr).mapNotNull { (sku, token) ->
294
225
  if (token.isNotEmpty()) {
295
226
  AndroidSubscriptionOfferInput(offerToken = token, sku = sku)
296
227
  } else {
@@ -302,7 +233,7 @@ class ExpoIapModule : Module() {
302
233
  }
303
234
 
304
235
  val subscriptionOffers =
305
- (explicitSubscriptionOffers.ifEmpty { fallbackOffers })
236
+ (parsedParams.explicitSubscriptionOffers.ifEmpty { fallbackOffers })
306
237
  .takeIf { it.isNotEmpty() }
307
238
 
308
239
  val requestProps =
@@ -310,12 +241,12 @@ class ExpoIapModule : Module() {
310
241
  ProductQueryType.Subs -> {
311
242
  val android =
312
243
  RequestSubscriptionAndroidProps(
313
- isOfferPersonalized = isOfferPersonalized,
314
- obfuscatedAccountIdAndroid = obfuscatedAccountId,
315
- obfuscatedProfileIdAndroid = obfuscatedProfileId,
316
- purchaseTokenAndroid = purchaseToken,
317
- replacementModeAndroid = replacementMode?.toInt(),
318
- skus = skus,
244
+ isOfferPersonalized = parsedParams.isOfferPersonalized,
245
+ obfuscatedAccountIdAndroid = parsedParams.obfuscatedAccountId,
246
+ obfuscatedProfileIdAndroid = parsedParams.obfuscatedProfileId,
247
+ purchaseTokenAndroid = parsedParams.purchaseToken,
248
+ replacementModeAndroid = parsedParams.replacementMode?.toInt(),
249
+ skus = parsedParams.skus,
319
250
  subscriptionOffers = subscriptionOffers,
320
251
  )
321
252
  RequestPurchaseProps(
@@ -330,10 +261,10 @@ class ExpoIapModule : Module() {
330
261
  else -> {
331
262
  val android =
332
263
  RequestPurchaseAndroidProps(
333
- isOfferPersonalized = isOfferPersonalized,
334
- obfuscatedAccountIdAndroid = obfuscatedAccountId,
335
- obfuscatedProfileIdAndroid = obfuscatedProfileId,
336
- skus = skus,
264
+ isOfferPersonalized = parsedParams.isOfferPersonalized,
265
+ obfuscatedAccountIdAndroid = parsedParams.obfuscatedAccountId,
266
+ obfuscatedProfileIdAndroid = parsedParams.obfuscatedProfileId,
267
+ skus = parsedParams.skus,
337
268
  )
338
269
  RequestPurchaseProps(
339
270
  request =
@@ -345,7 +276,7 @@ class ExpoIapModule : Module() {
345
276
  }
346
277
  }
347
278
 
348
- PromiseUtils.addPromiseForKey(PromiseUtils.PROMISE_BUY_ITEM, promise)
279
+ ExpoIapHelper.addPurchasePromise(promise)
349
280
  scope.launch {
350
281
  try {
351
282
  openIap.setActivity(currentActivity)
@@ -360,10 +291,7 @@ class ExpoIapModule : Module() {
360
291
  "requestPurchaseAndroid",
361
292
  purchases.map { it.toJson() },
362
293
  )
363
- PromiseUtils.resolvePromisesForKey(
364
- PromiseUtils.PROMISE_BUY_ITEM,
365
- purchases.map { it.toJson() },
366
- )
294
+ ExpoIapHelper.resolvePurchasePromises(purchases.map { it.toJson() })
367
295
  } catch (e: Exception) {
368
296
  ExpoIapLog.failure("requestPurchaseAndroid", e)
369
297
  val errorMap =
@@ -372,16 +300,23 @@ class ExpoIapModule : Module() {
372
300
  "message" to (e.message ?: "Purchase failed"),
373
301
  "platform" to "android",
374
302
  )
375
- runCatching { emitOrQueue(EVENT_PURCHASE_ERROR, errorMap) }
376
- .onFailure { ex ->
377
- Log.e(
378
- TAG,
379
- "Failed to send PURCHASE_ERROR event (requestPurchase)",
380
- ex,
381
- )
382
- }
383
- PromiseUtils.rejectPromisesForKey(
384
- PromiseUtils.PROMISE_BUY_ITEM,
303
+ runCatching {
304
+ ExpoIapHelper.emitOrQueue(
305
+ this@ExpoIapModule,
306
+ scope,
307
+ connectionReady,
308
+ pendingEvents,
309
+ EVENT_PURCHASE_ERROR,
310
+ errorMap,
311
+ )
312
+ }.onFailure { ex ->
313
+ Log.e(
314
+ TAG,
315
+ "Failed to send PURCHASE_ERROR event (requestPurchase)",
316
+ ex,
317
+ )
318
+ }
319
+ ExpoIapHelper.rejectPurchasePromises(
385
320
  OpenIapError.PurchaseFailed.CODE,
386
321
  e.message,
387
322
  null,
@@ -422,6 +357,7 @@ class ExpoIapModule : Module() {
422
357
  }
423
358
 
424
359
  OnDestroy {
360
+ ExpoIapHelper.cleanupListeners(openIap)
425
361
  job.cancel()
426
362
  }
427
363
  }
package/build/types.d.ts CHANGED
@@ -77,40 +77,40 @@ export interface EntitlementIOS {
77
77
  transactionId: string;
78
78
  }
79
79
  export declare enum ErrorCode {
80
- ActivityUnavailable = "ACTIVITY_UNAVAILABLE",
81
- AlreadyOwned = "ALREADY_OWNED",
82
- AlreadyPrepared = "ALREADY_PREPARED",
83
- BillingResponseJsonParseError = "BILLING_RESPONSE_JSON_PARSE_ERROR",
84
- BillingUnavailable = "BILLING_UNAVAILABLE",
85
- ConnectionClosed = "CONNECTION_CLOSED",
86
- DeferredPayment = "DEFERRED_PAYMENT",
87
- DeveloperError = "DEVELOPER_ERROR",
88
- EmptySkuList = "EMPTY_SKU_LIST",
89
- FeatureNotSupported = "FEATURE_NOT_SUPPORTED",
90
- IapNotAvailable = "IAP_NOT_AVAILABLE",
91
- InitConnection = "INIT_CONNECTION",
92
- Interrupted = "INTERRUPTED",
93
- ItemNotOwned = "ITEM_NOT_OWNED",
94
- ItemUnavailable = "ITEM_UNAVAILABLE",
95
- NetworkError = "NETWORK_ERROR",
96
- NotEnded = "NOT_ENDED",
97
- NotPrepared = "NOT_PREPARED",
98
- Pending = "PENDING",
99
- PurchaseError = "PURCHASE_ERROR",
100
- QueryProduct = "QUERY_PRODUCT",
101
- ReceiptFailed = "RECEIPT_FAILED",
102
- ReceiptFinished = "RECEIPT_FINISHED",
103
- ReceiptFinishedFailed = "RECEIPT_FINISHED_FAILED",
104
- RemoteError = "REMOTE_ERROR",
105
- ServiceDisconnected = "SERVICE_DISCONNECTED",
106
- ServiceError = "SERVICE_ERROR",
107
- SkuNotFound = "SKU_NOT_FOUND",
108
- SkuOfferMismatch = "SKU_OFFER_MISMATCH",
109
- SyncError = "SYNC_ERROR",
110
- TransactionValidationFailed = "TRANSACTION_VALIDATION_FAILED",
111
- Unknown = "UNKNOWN",
112
- UserCancelled = "USER_CANCELLED",
113
- UserError = "USER_ERROR"
80
+ ActivityUnavailable = "activity-unavailable",
81
+ AlreadyOwned = "already-owned",
82
+ AlreadyPrepared = "already-prepared",
83
+ BillingResponseJsonParseError = "billing-response-json-parse-error",
84
+ BillingUnavailable = "billing-unavailable",
85
+ ConnectionClosed = "connection-closed",
86
+ DeferredPayment = "deferred-payment",
87
+ DeveloperError = "developer-error",
88
+ EmptySkuList = "empty-sku-list",
89
+ FeatureNotSupported = "feature-not-supported",
90
+ IapNotAvailable = "iap-not-available",
91
+ InitConnection = "init-connection",
92
+ Interrupted = "interrupted",
93
+ ItemNotOwned = "item-not-owned",
94
+ ItemUnavailable = "item-unavailable",
95
+ NetworkError = "network-error",
96
+ NotEnded = "not-ended",
97
+ NotPrepared = "not-prepared",
98
+ Pending = "pending",
99
+ PurchaseError = "purchase-error",
100
+ QueryProduct = "query-product",
101
+ ReceiptFailed = "receipt-failed",
102
+ ReceiptFinished = "receipt-finished",
103
+ ReceiptFinishedFailed = "receipt-finished-failed",
104
+ RemoteError = "remote-error",
105
+ ServiceDisconnected = "service-disconnected",
106
+ ServiceError = "service-error",
107
+ SkuNotFound = "sku-not-found",
108
+ SkuOfferMismatch = "sku-offer-mismatch",
109
+ SyncError = "sync-error",
110
+ TransactionValidationFailed = "transaction-validation-failed",
111
+ Unknown = "unknown",
112
+ UserCancelled = "user-cancelled",
113
+ UserError = "user-error"
114
114
  }
115
115
  export type FetchProductsResult = Product[] | ProductSubscription[] | null;
116
116
  export type IapEvent = 'purchase-updated' | 'purchase-error' | 'promoted-product-ios';
package/build/types.js CHANGED
@@ -4,40 +4,40 @@
4
4
  // ============================================================================
5
5
  export var ErrorCode;
6
6
  (function (ErrorCode) {
7
- ErrorCode["ActivityUnavailable"] = "ACTIVITY_UNAVAILABLE";
8
- ErrorCode["AlreadyOwned"] = "ALREADY_OWNED";
9
- ErrorCode["AlreadyPrepared"] = "ALREADY_PREPARED";
10
- ErrorCode["BillingResponseJsonParseError"] = "BILLING_RESPONSE_JSON_PARSE_ERROR";
11
- ErrorCode["BillingUnavailable"] = "BILLING_UNAVAILABLE";
12
- ErrorCode["ConnectionClosed"] = "CONNECTION_CLOSED";
13
- ErrorCode["DeferredPayment"] = "DEFERRED_PAYMENT";
14
- ErrorCode["DeveloperError"] = "DEVELOPER_ERROR";
15
- ErrorCode["EmptySkuList"] = "EMPTY_SKU_LIST";
16
- ErrorCode["FeatureNotSupported"] = "FEATURE_NOT_SUPPORTED";
17
- ErrorCode["IapNotAvailable"] = "IAP_NOT_AVAILABLE";
18
- ErrorCode["InitConnection"] = "INIT_CONNECTION";
19
- ErrorCode["Interrupted"] = "INTERRUPTED";
20
- ErrorCode["ItemNotOwned"] = "ITEM_NOT_OWNED";
21
- ErrorCode["ItemUnavailable"] = "ITEM_UNAVAILABLE";
22
- ErrorCode["NetworkError"] = "NETWORK_ERROR";
23
- ErrorCode["NotEnded"] = "NOT_ENDED";
24
- ErrorCode["NotPrepared"] = "NOT_PREPARED";
25
- ErrorCode["Pending"] = "PENDING";
26
- ErrorCode["PurchaseError"] = "PURCHASE_ERROR";
27
- ErrorCode["QueryProduct"] = "QUERY_PRODUCT";
28
- ErrorCode["ReceiptFailed"] = "RECEIPT_FAILED";
29
- ErrorCode["ReceiptFinished"] = "RECEIPT_FINISHED";
30
- ErrorCode["ReceiptFinishedFailed"] = "RECEIPT_FINISHED_FAILED";
31
- ErrorCode["RemoteError"] = "REMOTE_ERROR";
32
- ErrorCode["ServiceDisconnected"] = "SERVICE_DISCONNECTED";
33
- ErrorCode["ServiceError"] = "SERVICE_ERROR";
34
- ErrorCode["SkuNotFound"] = "SKU_NOT_FOUND";
35
- ErrorCode["SkuOfferMismatch"] = "SKU_OFFER_MISMATCH";
36
- ErrorCode["SyncError"] = "SYNC_ERROR";
37
- ErrorCode["TransactionValidationFailed"] = "TRANSACTION_VALIDATION_FAILED";
38
- ErrorCode["Unknown"] = "UNKNOWN";
39
- ErrorCode["UserCancelled"] = "USER_CANCELLED";
40
- ErrorCode["UserError"] = "USER_ERROR";
7
+ ErrorCode["ActivityUnavailable"] = "activity-unavailable";
8
+ ErrorCode["AlreadyOwned"] = "already-owned";
9
+ ErrorCode["AlreadyPrepared"] = "already-prepared";
10
+ ErrorCode["BillingResponseJsonParseError"] = "billing-response-json-parse-error";
11
+ ErrorCode["BillingUnavailable"] = "billing-unavailable";
12
+ ErrorCode["ConnectionClosed"] = "connection-closed";
13
+ ErrorCode["DeferredPayment"] = "deferred-payment";
14
+ ErrorCode["DeveloperError"] = "developer-error";
15
+ ErrorCode["EmptySkuList"] = "empty-sku-list";
16
+ ErrorCode["FeatureNotSupported"] = "feature-not-supported";
17
+ ErrorCode["IapNotAvailable"] = "iap-not-available";
18
+ ErrorCode["InitConnection"] = "init-connection";
19
+ ErrorCode["Interrupted"] = "interrupted";
20
+ ErrorCode["ItemNotOwned"] = "item-not-owned";
21
+ ErrorCode["ItemUnavailable"] = "item-unavailable";
22
+ ErrorCode["NetworkError"] = "network-error";
23
+ ErrorCode["NotEnded"] = "not-ended";
24
+ ErrorCode["NotPrepared"] = "not-prepared";
25
+ ErrorCode["Pending"] = "pending";
26
+ ErrorCode["PurchaseError"] = "purchase-error";
27
+ ErrorCode["QueryProduct"] = "query-product";
28
+ ErrorCode["ReceiptFailed"] = "receipt-failed";
29
+ ErrorCode["ReceiptFinished"] = "receipt-finished";
30
+ ErrorCode["ReceiptFinishedFailed"] = "receipt-finished-failed";
31
+ ErrorCode["RemoteError"] = "remote-error";
32
+ ErrorCode["ServiceDisconnected"] = "service-disconnected";
33
+ ErrorCode["ServiceError"] = "service-error";
34
+ ErrorCode["SkuNotFound"] = "sku-not-found";
35
+ ErrorCode["SkuOfferMismatch"] = "sku-offer-mismatch";
36
+ ErrorCode["SyncError"] = "sync-error";
37
+ ErrorCode["TransactionValidationFailed"] = "transaction-validation-failed";
38
+ ErrorCode["Unknown"] = "unknown";
39
+ ErrorCode["UserCancelled"] = "user-cancelled";
40
+ ErrorCode["UserError"] = "user-error";
41
41
  })(ErrorCode || (ErrorCode = {}));
42
42
  // -- End subscription helper types
43
43
  //# sourceMappingURL=types.js.map