react-native-iap 14.1.0 → 14.1.1

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.
package/src/index.ts CHANGED
@@ -1,6 +1,6 @@
1
1
  // External dependencies
2
- import { Platform } from 'react-native'
3
- import { NitroModules } from 'react-native-nitro-modules'
2
+ import {Platform} from 'react-native';
3
+ import {NitroModules} from 'react-native-nitro-modules';
4
4
 
5
5
  // Internal modules
6
6
  import type {
@@ -9,7 +9,7 @@ import type {
9
9
  NitroReceiptValidationParams,
10
10
  NitroReceiptValidationResultIOS,
11
11
  NitroReceiptValidationResultAndroid,
12
- } from './specs/RnIap.nitro'
12
+ } from './specs/RnIap.nitro';
13
13
  import type {
14
14
  Product,
15
15
  Purchase,
@@ -23,15 +23,15 @@ import type {
23
23
  ReceiptValidationResultAndroid,
24
24
  RequestPurchaseIosProps,
25
25
  RequestPurchaseAndroidProps,
26
- } from './types'
27
- import type { ProductRequest } from './types'
26
+ } from './types';
27
+ import type {ProductRequest} from './types';
28
28
  import {
29
29
  convertNitroProductToProduct,
30
30
  convertNitroPurchaseToPurchase,
31
31
  validateNitroProduct,
32
32
  validateNitroPurchase,
33
- } from './utils/type-bridge'
34
- import { parseErrorStringToJsonObj } from './utils/error'
33
+ } from './utils/type-bridge';
34
+ import {parseErrorStringToJsonObj} from './utils/error';
35
35
 
36
36
  // Export all types
37
37
  export type {
@@ -39,48 +39,48 @@ export type {
39
39
  NitroProduct,
40
40
  NitroPurchase,
41
41
  NitroPurchaseResult,
42
- } from './specs/RnIap.nitro'
43
- export * from './types'
44
- export * from './utils/error'
42
+ } from './specs/RnIap.nitro';
43
+ export * from './types';
44
+ export * from './utils/error';
45
45
 
46
46
  // Types for event listeners
47
47
  export interface EventSubscription {
48
- remove(): void
48
+ remove(): void;
49
49
  }
50
50
 
51
51
  // ActiveSubscription and PurchaseError types are already exported via 'export * from ./types'
52
52
 
53
53
  // Export hooks
54
- export { useIAP } from './hooks/useIAP'
54
+ export {useIAP} from './hooks/useIAP';
55
55
 
56
56
  // Development utilities removed - use type bridge functions directly if needed
57
57
 
58
58
  // Create the RnIap HybridObject instance (internal use only)
59
- const iap = NitroModules.createHybridObject<RnIap>('RnIap')
59
+ const iap = NitroModules.createHybridObject<RnIap>('RnIap');
60
60
 
61
61
  /**
62
62
  * Initialize connection to the store
63
63
  */
64
64
  export const initConnection = async (): Promise<boolean> => {
65
65
  try {
66
- return await iap.initConnection()
66
+ return await iap.initConnection();
67
67
  } catch (error) {
68
- console.error('Failed to initialize IAP connection:', error)
69
- throw error
68
+ console.error('Failed to initialize IAP connection:', error);
69
+ throw error;
70
70
  }
71
- }
71
+ };
72
72
 
73
73
  /**
74
74
  * End connection to the store
75
75
  */
76
76
  export const endConnection = async (): Promise<boolean> => {
77
77
  try {
78
- return await iap.endConnection()
78
+ return await iap.endConnection();
79
79
  } catch (error) {
80
- console.error('Failed to end IAP connection:', error)
81
- throw error
80
+ console.error('Failed to end IAP connection:', error);
81
+ throw error;
82
82
  }
83
- }
83
+ };
84
84
 
85
85
  /**
86
86
  * Fetch products from the store
@@ -104,41 +104,41 @@ export const fetchProducts = async ({
104
104
  }: ProductRequest): Promise<Product[]> => {
105
105
  try {
106
106
  if (!skus || skus.length === 0) {
107
- throw new Error('No SKUs provided')
107
+ throw new Error('No SKUs provided');
108
108
  }
109
109
 
110
110
  if (type === 'all') {
111
111
  const [inappNitro, subsNitro] = await Promise.all([
112
112
  iap.fetchProducts(skus, 'inapp'),
113
113
  iap.fetchProducts(skus, 'subs'),
114
- ])
115
- const allNitro = [...inappNitro, ...subsNitro]
116
- const validAll = allNitro.filter(validateNitroProduct)
114
+ ]);
115
+ const allNitro = [...inappNitro, ...subsNitro];
116
+ const validAll = allNitro.filter(validateNitroProduct);
117
117
  if (validAll.length !== allNitro.length) {
118
118
  console.warn(
119
- `[fetchProducts] Some products failed validation: ${allNitro.length - validAll.length} invalid`
120
- )
119
+ `[fetchProducts] Some products failed validation: ${allNitro.length - validAll.length} invalid`,
120
+ );
121
121
  }
122
- return validAll.map(convertNitroProductToProduct)
122
+ return validAll.map(convertNitroProductToProduct);
123
123
  }
124
124
 
125
- const nitroProducts = await iap.fetchProducts(skus, type)
125
+ const nitroProducts = await iap.fetchProducts(skus, type);
126
126
 
127
127
  // Validate and convert NitroProducts to TypeScript Products
128
- const validProducts = nitroProducts.filter(validateNitroProduct)
128
+ const validProducts = nitroProducts.filter(validateNitroProduct);
129
129
  if (validProducts.length !== nitroProducts.length) {
130
130
  console.warn(
131
- `[fetchProducts] Some products failed validation: ${nitroProducts.length - validProducts.length} invalid`
132
- )
131
+ `[fetchProducts] Some products failed validation: ${nitroProducts.length - validProducts.length} invalid`,
132
+ );
133
133
  }
134
134
 
135
- const typedProducts = validProducts.map(convertNitroProductToProduct)
136
- return typedProducts
135
+ const typedProducts = validProducts.map(convertNitroProductToProduct);
136
+ return typedProducts;
137
137
  } catch (error) {
138
- console.error('[fetchProducts] Failed:', error)
139
- throw error
138
+ console.error('[fetchProducts] Failed:', error);
139
+ throw error;
140
140
  }
141
- }
141
+ };
142
142
 
143
143
  /**
144
144
  * Request a purchase for products or subscriptions
@@ -182,65 +182,64 @@ export const requestPurchase = async ({
182
182
  request,
183
183
  type = 'inapp',
184
184
  }: {
185
- request: RequestPurchaseProps | RequestSubscriptionProps
186
- type?: 'inapp' | 'subs'
185
+ request: RequestPurchaseProps | RequestSubscriptionProps;
186
+ type?: 'inapp' | 'subs';
187
187
  }): Promise<void> => {
188
188
  try {
189
189
  // Validate platform-specific requests
190
190
  if (Platform.OS === 'ios') {
191
- const iosRequest = request.ios
191
+ const iosRequest = request.ios;
192
192
  if (!iosRequest?.sku) {
193
193
  throw new Error(
194
- 'Invalid request for iOS. The `sku` property is required.'
195
- )
194
+ 'Invalid request for iOS. The `sku` property is required.',
195
+ );
196
196
  }
197
197
  } else if (Platform.OS === 'android') {
198
- const androidRequest = request.android
198
+ const androidRequest = request.android;
199
199
  if (!androidRequest?.skus?.length) {
200
200
  throw new Error(
201
- 'Invalid request for Android. The `skus` property is required and must be a non-empty array.'
202
- )
201
+ 'Invalid request for Android. The `skus` property is required and must be a non-empty array.',
202
+ );
203
203
  }
204
204
  } else {
205
- throw new Error('Unsupported platform')
205
+ throw new Error('Unsupported platform');
206
206
  }
207
207
 
208
208
  // Transform the request for the unified interface
209
- const unifiedRequest: any = {}
209
+ const unifiedRequest: any = {};
210
210
 
211
211
  if (Platform.OS === 'ios' && request.ios) {
212
- const iosReq = request.ios as RequestPurchaseIosProps
212
+ const iosReq = request.ios as RequestPurchaseIosProps;
213
213
  const autoFinishSubs =
214
- type === 'subs' &&
215
- iosReq.andDangerouslyFinishTransactionAutomatically == null
214
+ type === 'subs' && iosReq.andDangerouslyFinishTransactionAutomatically == null;
216
215
  unifiedRequest.ios = {
217
216
  ...iosReq,
218
217
  // Align with native SwiftUI flow: auto-finish subscriptions by default
219
218
  ...(autoFinishSubs
220
- ? { andDangerouslyFinishTransactionAutomatically: true }
219
+ ? {andDangerouslyFinishTransactionAutomatically: true}
221
220
  : {}),
222
- } as RequestPurchaseIosProps
221
+ } as RequestPurchaseIosProps;
223
222
  }
224
223
 
225
224
  if (Platform.OS === 'android' && request.android) {
226
225
  if (type === 'subs') {
227
- const subsRequest = request.android as RequestSubscriptionAndroidProps
226
+ const subsRequest = request.android as RequestSubscriptionAndroidProps;
228
227
  unifiedRequest.android = {
229
228
  ...subsRequest,
230
229
  subscriptionOffers: subsRequest.subscriptionOffers || [],
231
- } as RequestPurchaseAndroidProps
230
+ } as RequestPurchaseAndroidProps;
232
231
  } else {
233
- unifiedRequest.android = request.android
232
+ unifiedRequest.android = request.android;
234
233
  }
235
234
  }
236
235
 
237
236
  // Call unified method - returns void, listen for events instead
238
- await iap.requestPurchase(unifiedRequest)
237
+ await iap.requestPurchase(unifiedRequest);
239
238
  } catch (error) {
240
- console.error('Failed to request purchase:', error)
241
- throw error
239
+ console.error('Failed to request purchase:', error);
240
+ throw error;
242
241
  }
243
- }
242
+ };
244
243
 
245
244
  /**
246
245
  * Get available purchases (purchased items not yet consumed/finished)
@@ -261,7 +260,7 @@ export const getAvailablePurchases = async ({
261
260
  }: PurchaseOptions = {}): Promise<Purchase[]> => {
262
261
  try {
263
262
  // Create unified options
264
- const options: any = {}
263
+ const options: any = {};
265
264
 
266
265
  if (Platform.OS === 'ios') {
267
266
  // Provide both new and deprecated keys for compatibility
@@ -270,46 +269,46 @@ export const getAvailablePurchases = async ({
270
269
  onlyIncludeActiveItemsIOS,
271
270
  alsoPublishToEventListener: alsoPublishToEventListenerIOS,
272
271
  onlyIncludeActiveItems: onlyIncludeActiveItemsIOS,
273
- }
272
+ };
274
273
  } else if (Platform.OS === 'android') {
275
274
  // For Android, we need to call twice for inapp and subs
276
275
  const inappNitroPurchases = await iap.getAvailablePurchases({
277
- android: { type: 'inapp' },
278
- })
276
+ android: {type: 'inapp'},
277
+ });
279
278
  const subsNitroPurchases = await iap.getAvailablePurchases({
280
- android: { type: 'subs' },
281
- })
279
+ android: {type: 'subs'},
280
+ });
282
281
 
283
282
  // Validate and convert both sets of purchases
284
- const allNitroPurchases = [...inappNitroPurchases, ...subsNitroPurchases]
285
- const validPurchases = allNitroPurchases.filter(validateNitroPurchase)
283
+ const allNitroPurchases = [...inappNitroPurchases, ...subsNitroPurchases];
284
+ const validPurchases = allNitroPurchases.filter(validateNitroPurchase);
286
285
  if (validPurchases.length !== allNitroPurchases.length) {
287
286
  console.warn(
288
- `[getAvailablePurchases] Some Android purchases failed validation: ${allNitroPurchases.length - validPurchases.length} invalid`
289
- )
287
+ `[getAvailablePurchases] Some Android purchases failed validation: ${allNitroPurchases.length - validPurchases.length} invalid`,
288
+ );
290
289
  }
291
290
 
292
- return validPurchases.map(convertNitroPurchaseToPurchase)
291
+ return validPurchases.map(convertNitroPurchaseToPurchase);
293
292
  } else {
294
- throw new Error('Unsupported platform')
293
+ throw new Error('Unsupported platform');
295
294
  }
296
295
 
297
- const nitroPurchases = await iap.getAvailablePurchases(options)
296
+ const nitroPurchases = await iap.getAvailablePurchases(options);
298
297
 
299
298
  // Validate and convert NitroPurchases to TypeScript Purchases
300
- const validPurchases = nitroPurchases.filter(validateNitroPurchase)
299
+ const validPurchases = nitroPurchases.filter(validateNitroPurchase);
301
300
  if (validPurchases.length !== nitroPurchases.length) {
302
301
  console.warn(
303
- `[getAvailablePurchases] Some purchases failed validation: ${nitroPurchases.length - validPurchases.length} invalid`
304
- )
302
+ `[getAvailablePurchases] Some purchases failed validation: ${nitroPurchases.length - validPurchases.length} invalid`,
303
+ );
305
304
  }
306
305
 
307
- return validPurchases.map(convertNitroPurchaseToPurchase)
306
+ return validPurchases.map(convertNitroPurchaseToPurchase);
308
307
  } catch (error) {
309
- console.error('Failed to get available purchases:', error)
310
- throw error
308
+ console.error('Failed to get available purchases:', error);
309
+ throw error;
311
310
  }
312
- }
311
+ };
313
312
 
314
313
  /**
315
314
  * Finish a transaction (consume or acknowledge)
@@ -331,58 +330,58 @@ export const finishTransaction = async ({
331
330
  }: FinishTransactionParams): Promise<NitroPurchaseResult | boolean> => {
332
331
  try {
333
332
  // Create unified params
334
- const params: any = {}
333
+ const params: any = {};
335
334
 
336
335
  if (Platform.OS === 'ios') {
337
336
  if (!purchase.id) {
338
- throw new Error('purchase.id required to finish iOS transaction')
337
+ throw new Error('purchase.id required to finish iOS transaction');
339
338
  }
340
339
  params.ios = {
341
340
  transactionId: purchase.id,
342
- }
341
+ };
343
342
  } else if (Platform.OS === 'android') {
344
- const androidPurchase = purchase as PurchaseAndroid
343
+ const androidPurchase = purchase as PurchaseAndroid;
345
344
  const token =
346
- androidPurchase.purchaseToken || androidPurchase.purchaseTokenAndroid
345
+ androidPurchase.purchaseToken || androidPurchase.purchaseTokenAndroid;
347
346
 
348
347
  if (!token) {
349
- throw new Error('purchaseToken required to finish Android transaction')
348
+ throw new Error('purchaseToken required to finish Android transaction');
350
349
  }
351
350
 
352
351
  params.android = {
353
352
  purchaseToken: token,
354
353
  isConsumable,
355
- }
354
+ };
356
355
  } else {
357
- throw new Error('Unsupported platform')
356
+ throw new Error('Unsupported platform');
358
357
  }
359
358
 
360
- const result = await iap.finishTransaction(params)
359
+ const result = await iap.finishTransaction(params);
361
360
 
362
361
  // Handle variant return type
363
362
  if (typeof result === 'boolean') {
364
- return result
363
+ return result;
365
364
  }
366
365
  // It's a PurchaseResult
367
- return result as NitroPurchaseResult
366
+ return result as NitroPurchaseResult;
368
367
  } catch (error) {
369
368
  // If iOS transaction has already been auto-finished natively, treat as success
370
369
  if (Platform.OS === 'ios') {
371
- const err = parseErrorStringToJsonObj(error)
372
- const msg = (err?.message || '').toString()
373
- const code = (err?.code || '').toString()
370
+ const err = parseErrorStringToJsonObj(error);
371
+ const msg = (err?.message || '').toString();
372
+ const code = (err?.code || '').toString();
374
373
  if (
375
374
  msg.includes('Transaction not found') ||
376
375
  code === 'E_ITEM_UNAVAILABLE'
377
376
  ) {
378
377
  // Consider already finished
379
- return true
378
+ return true;
380
379
  }
381
380
  }
382
- console.error('Failed to finish transaction:', error)
383
- throw error
381
+ console.error('Failed to finish transaction:', error);
382
+ throw error;
384
383
  }
385
- }
384
+ };
386
385
 
387
386
  /**
388
387
  * Acknowledge a purchase (Android only)
@@ -394,11 +393,13 @@ export const finishTransaction = async ({
394
393
  * ```
395
394
  */
396
395
  export const acknowledgePurchaseAndroid = async (
397
- purchaseToken: string
396
+ purchaseToken: string,
398
397
  ): Promise<NitroPurchaseResult> => {
399
398
  try {
400
399
  if (Platform.OS !== 'android') {
401
- throw new Error('acknowledgePurchaseAndroid is only available on Android')
400
+ throw new Error(
401
+ 'acknowledgePurchaseAndroid is only available on Android',
402
+ );
402
403
  }
403
404
 
404
405
  const result = await iap.finishTransaction({
@@ -406,7 +407,7 @@ export const acknowledgePurchaseAndroid = async (
406
407
  purchaseToken,
407
408
  isConsumable: false,
408
409
  },
409
- })
410
+ });
410
411
 
411
412
  // Result is a variant, extract PurchaseResult
412
413
  if (typeof result === 'boolean') {
@@ -416,14 +417,14 @@ export const acknowledgePurchaseAndroid = async (
416
417
  code: '0',
417
418
  message: 'Success',
418
419
  purchaseToken,
419
- }
420
+ };
420
421
  }
421
- return result as NitroPurchaseResult
422
+ return result as NitroPurchaseResult;
422
423
  } catch (error) {
423
- console.error('Failed to acknowledge purchase Android:', error)
424
- throw error
424
+ console.error('Failed to acknowledge purchase Android:', error);
425
+ throw error;
425
426
  }
426
- }
427
+ };
427
428
 
428
429
  /**
429
430
  * Consume a purchase (Android only)
@@ -435,11 +436,11 @@ export const acknowledgePurchaseAndroid = async (
435
436
  * ```
436
437
  */
437
438
  export const consumePurchaseAndroid = async (
438
- purchaseToken: string
439
+ purchaseToken: string,
439
440
  ): Promise<NitroPurchaseResult> => {
440
441
  try {
441
442
  if (Platform.OS !== 'android') {
442
- throw new Error('consumePurchaseAndroid is only available on Android')
443
+ throw new Error('consumePurchaseAndroid is only available on Android');
443
444
  }
444
445
 
445
446
  const result = await iap.finishTransaction({
@@ -447,7 +448,7 @@ export const consumePurchaseAndroid = async (
447
448
  purchaseToken,
448
449
  isConsumable: true,
449
450
  },
450
- })
451
+ });
451
452
 
452
453
  // Result is a variant, extract PurchaseResult
453
454
  if (typeof result === 'boolean') {
@@ -457,21 +458,21 @@ export const consumePurchaseAndroid = async (
457
458
  code: '0',
458
459
  message: 'Success',
459
460
  purchaseToken,
460
- }
461
+ };
461
462
  }
462
- return result as NitroPurchaseResult
463
+ return result as NitroPurchaseResult;
463
464
  } catch (error) {
464
- console.error('Failed to consume purchase Android:', error)
465
- throw error
465
+ console.error('Failed to consume purchase Android:', error);
466
+ throw error;
466
467
  }
467
- }
468
+ };
468
469
 
469
470
  // ============================================================================
470
471
  // EVENT LISTENERS
471
472
  // ============================================================================
472
473
 
473
474
  // Store wrapped listeners for proper removal
474
- const listenerMap = new WeakMap<Function, Function>()
475
+ const listenerMap = new WeakMap<Function, Function>();
475
476
 
476
477
  /**
477
478
  * Purchase updated event listener
@@ -494,35 +495,35 @@ const listenerMap = new WeakMap<Function, Function>()
494
495
  * ```
495
496
  */
496
497
  export const purchaseUpdatedListener = (
497
- listener: (purchase: Purchase) => void
498
+ listener: (purchase: Purchase) => void,
498
499
  ): EventSubscription => {
499
500
  // Wrap the listener to convert NitroPurchase to Purchase
500
501
  const wrappedListener = (nitroPurchase: any) => {
501
502
  if (validateNitroPurchase(nitroPurchase)) {
502
- const convertedPurchase = convertNitroPurchaseToPurchase(nitroPurchase)
503
- listener(convertedPurchase)
503
+ const convertedPurchase = convertNitroPurchaseToPurchase(nitroPurchase);
504
+ listener(convertedPurchase);
504
505
  } else {
505
506
  console.error(
506
507
  'Invalid purchase data received from native:',
507
- nitroPurchase
508
- )
508
+ nitroPurchase,
509
+ );
509
510
  }
510
- }
511
+ };
511
512
 
512
513
  // Store the wrapped listener for removal
513
- listenerMap.set(listener, wrappedListener)
514
- iap.addPurchaseUpdatedListener(wrappedListener)
514
+ listenerMap.set(listener, wrappedListener);
515
+ iap.addPurchaseUpdatedListener(wrappedListener);
515
516
 
516
517
  return {
517
518
  remove: () => {
518
- const wrapped = listenerMap.get(listener)
519
+ const wrapped = listenerMap.get(listener);
519
520
  if (wrapped) {
520
- iap.removePurchaseUpdatedListener(wrapped as any)
521
- listenerMap.delete(listener)
521
+ iap.removePurchaseUpdatedListener(wrapped as any);
522
+ listenerMap.delete(listener);
522
523
  }
523
524
  },
524
- }
525
- }
525
+ };
526
+ };
526
527
 
527
528
  /**
528
529
  * Purchase error event listener
@@ -552,19 +553,19 @@ export const purchaseUpdatedListener = (
552
553
  * ```
553
554
  */
554
555
  export const purchaseErrorListener = (
555
- listener: (error: NitroPurchaseResult) => void
556
+ listener: (error: NitroPurchaseResult) => void,
556
557
  ): EventSubscription => {
557
558
  // Store the listener for removal
558
- listenerMap.set(listener, listener)
559
- iap.addPurchaseErrorListener(listener as any)
559
+ listenerMap.set(listener, listener);
560
+ iap.addPurchaseErrorListener(listener as any);
560
561
 
561
562
  return {
562
563
  remove: () => {
563
- iap.removePurchaseErrorListener(listener as any)
564
- listenerMap.delete(listener)
564
+ iap.removePurchaseErrorListener(listener as any);
565
+ listenerMap.delete(listener);
565
566
  },
566
- }
567
- }
567
+ };
568
+ };
568
569
 
569
570
  /**
570
571
  * iOS-only listener for App Store promoted product events.
@@ -587,42 +588,42 @@ export const purchaseErrorListener = (
587
588
  * @platform iOS
588
589
  */
589
590
  export const promotedProductListenerIOS = (
590
- listener: (product: Product) => void
591
+ listener: (product: Product) => void,
591
592
  ): EventSubscription => {
592
593
  if (Platform.OS !== 'ios') {
593
594
  console.warn(
594
- 'promotedProductListenerIOS: This listener is only available on iOS'
595
- )
596
- return { remove: () => {} }
595
+ 'promotedProductListenerIOS: This listener is only available on iOS',
596
+ );
597
+ return {remove: () => {}};
597
598
  }
598
599
 
599
600
  // Wrap the listener to convert NitroProduct to Product
600
601
  const wrappedListener = (nitroProduct: any) => {
601
602
  if (validateNitroProduct(nitroProduct)) {
602
- const convertedProduct = convertNitroProductToProduct(nitroProduct)
603
- listener(convertedProduct)
603
+ const convertedProduct = convertNitroProductToProduct(nitroProduct);
604
+ listener(convertedProduct);
604
605
  } else {
605
606
  console.error(
606
607
  'Invalid promoted product data received from native:',
607
- nitroProduct
608
- )
608
+ nitroProduct,
609
+ );
609
610
  }
610
- }
611
+ };
611
612
 
612
613
  // Store the wrapped listener for removal
613
- listenerMap.set(listener, wrappedListener)
614
- iap.addPromotedProductListenerIOS(wrappedListener)
614
+ listenerMap.set(listener, wrappedListener);
615
+ iap.addPromotedProductListenerIOS(wrappedListener);
615
616
 
616
617
  return {
617
618
  remove: () => {
618
- const wrapped = listenerMap.get(listener)
619
+ const wrapped = listenerMap.get(listener);
619
620
  if (wrapped) {
620
- iap.removePromotedProductListenerIOS(wrapped as any)
621
- listenerMap.delete(listener)
621
+ iap.removePromotedProductListenerIOS(wrapped as any);
622
+ listenerMap.delete(listener);
622
623
  }
623
624
  },
624
- }
625
- }
625
+ };
626
+ };
626
627
 
627
628
  // ============================================================================
628
629
  // iOS-SPECIFIC FUNCTIONS
@@ -637,30 +638,30 @@ export const promotedProductListenerIOS = (
637
638
  export const validateReceipt = async (
638
639
  sku: string,
639
640
  androidOptions?: {
640
- packageName: string
641
- productToken: string
642
- accessToken: string
643
- isSub?: boolean
644
- }
641
+ packageName: string;
642
+ productToken: string;
643
+ accessToken: string;
644
+ isSub?: boolean;
645
+ },
645
646
  ): Promise<import('./types').ReceiptValidationResult> => {
646
647
  if (!iap) {
647
648
  const errorJson = parseErrorStringToJsonObj(
648
- 'RnIap: Service not initialized. Call initConnection() first.'
649
- )
650
- throw new Error(errorJson.message)
649
+ 'RnIap: Service not initialized. Call initConnection() first.',
650
+ );
651
+ throw new Error(errorJson.message);
651
652
  }
652
653
 
653
654
  try {
654
655
  const params: NitroReceiptValidationParams = {
655
656
  sku,
656
657
  androidOptions,
657
- }
658
+ };
658
659
 
659
- const nitroResult = await iap.validateReceipt(params)
660
+ const nitroResult = await iap.validateReceipt(params);
660
661
 
661
662
  // Convert Nitro result to public API result
662
663
  if (Platform.OS === 'ios') {
663
- const iosResult = nitroResult as NitroReceiptValidationResultIOS
664
+ const iosResult = nitroResult as NitroReceiptValidationResultIOS;
664
665
  const result: ReceiptValidationResultIOS = {
665
666
  isValid: iosResult.isValid,
666
667
  receiptData: iosResult.receiptData,
@@ -668,11 +669,11 @@ export const validateReceipt = async (
668
669
  latestTransaction: iosResult.latestTransaction
669
670
  ? convertNitroPurchaseToPurchase(iosResult.latestTransaction)
670
671
  : undefined,
671
- }
672
- return result
672
+ };
673
+ return result;
673
674
  } else {
674
675
  // Android
675
- const androidResult = nitroResult as NitroReceiptValidationResultAndroid
676
+ const androidResult = nitroResult as NitroReceiptValidationResultAndroid;
676
677
  const result: ReceiptValidationResultAndroid = {
677
678
  autoRenewing: androidResult.autoRenewing,
678
679
  betaProduct: androidResult.betaProduct,
@@ -684,7 +685,7 @@ export const validateReceipt = async (
684
685
  gracePeriodEndDate: androidResult.gracePeriodEndDate,
685
686
  parentProductId: androidResult.parentProductId,
686
687
  productId: androidResult.productId,
687
- productType: androidResult.productType === 'subs' ? 'subs' : 'inapp',
688
+ productType: (androidResult.productType === 'subs' ? 'subs' : 'inapp'),
688
689
  purchaseDate: androidResult.purchaseDate,
689
690
  quantity: androidResult.quantity,
690
691
  receiptId: androidResult.receiptId,
@@ -692,15 +693,15 @@ export const validateReceipt = async (
692
693
  term: androidResult.term,
693
694
  termSku: androidResult.termSku,
694
695
  testTransaction: androidResult.testTransaction,
695
- }
696
- return result
696
+ };
697
+ return result;
697
698
  }
698
699
  } catch (error) {
699
- console.error('[validateReceipt] Failed:', error)
700
- const errorJson = parseErrorStringToJsonObj(error)
701
- throw new Error(errorJson.message)
700
+ console.error('[validateReceipt] Failed:', error);
701
+ const errorJson = parseErrorStringToJsonObj(error);
702
+ throw new Error(errorJson.message);
702
703
  }
703
- }
704
+ };
704
705
 
705
706
  /**
706
707
  * Sync iOS purchases with App Store (iOS only)
@@ -709,24 +710,24 @@ export const validateReceipt = async (
709
710
  */
710
711
  export const syncIOS = async (): Promise<boolean> => {
711
712
  if (Platform.OS !== 'ios') {
712
- throw new Error('syncIOS is only available on iOS')
713
+ throw new Error('syncIOS is only available on iOS');
713
714
  }
714
715
 
715
716
  if (!iap) {
716
717
  const errorJson = parseErrorStringToJsonObj(
717
- 'RnIap: Service not initialized. Call initConnection() first.'
718
- )
719
- throw new Error(errorJson.message)
718
+ 'RnIap: Service not initialized. Call initConnection() first.',
719
+ );
720
+ throw new Error(errorJson.message);
720
721
  }
721
722
 
722
723
  try {
723
- return await iap.syncIOS()
724
+ return await iap.syncIOS();
724
725
  } catch (error) {
725
- console.error('[syncIOS] Failed:', error)
726
- const errorJson = parseErrorStringToJsonObj(error)
727
- throw new Error(errorJson.message)
726
+ console.error('[syncIOS] Failed:', error);
727
+ const errorJson = parseErrorStringToJsonObj(error);
728
+ throw new Error(errorJson.message);
728
729
  }
729
- }
730
+ };
730
731
 
731
732
  /**
732
733
  * Request the promoted product from the App Store (iOS only)
@@ -735,28 +736,28 @@ export const syncIOS = async (): Promise<boolean> => {
735
736
  */
736
737
  export const requestPromotedProductIOS = async (): Promise<Product | null> => {
737
738
  if (Platform.OS !== 'ios') {
738
- return null
739
+ return null;
739
740
  }
740
741
 
741
742
  if (!iap) {
742
743
  const errorJson = parseErrorStringToJsonObj(
743
- 'RnIap: Service not initialized. Call initConnection() first.'
744
- )
745
- throw new Error(errorJson.message)
744
+ 'RnIap: Service not initialized. Call initConnection() first.',
745
+ );
746
+ throw new Error(errorJson.message);
746
747
  }
747
748
 
748
749
  try {
749
- const nitroProduct = await iap.requestPromotedProductIOS()
750
+ const nitroProduct = await iap.requestPromotedProductIOS();
750
751
  if (nitroProduct) {
751
- return convertNitroProductToProduct(nitroProduct)
752
+ return convertNitroProductToProduct(nitroProduct);
752
753
  }
753
- return null
754
+ return null;
754
755
  } catch (error) {
755
- console.error('[getPromotedProductIOS] Failed:', error)
756
- const errorJson = parseErrorStringToJsonObj(error)
757
- throw new Error(errorJson.message)
756
+ console.error('[getPromotedProductIOS] Failed:', error);
757
+ const errorJson = parseErrorStringToJsonObj(error);
758
+ throw new Error(errorJson.message);
758
759
  }
759
- }
760
+ };
760
761
 
761
762
  /**
762
763
  * Present the code redemption sheet for offer codes (iOS only)
@@ -765,24 +766,24 @@ export const requestPromotedProductIOS = async (): Promise<Product | null> => {
765
766
  */
766
767
  export const presentCodeRedemptionSheetIOS = async (): Promise<boolean> => {
767
768
  if (Platform.OS !== 'ios') {
768
- return false
769
+ return false;
769
770
  }
770
771
 
771
772
  if (!iap) {
772
773
  const errorJson = parseErrorStringToJsonObj(
773
- 'RnIap: Service not initialized. Call initConnection() first.'
774
- )
775
- throw new Error(errorJson.message)
774
+ 'RnIap: Service not initialized. Call initConnection() first.',
775
+ );
776
+ throw new Error(errorJson.message);
776
777
  }
777
778
 
778
779
  try {
779
- return await iap.presentCodeRedemptionSheetIOS()
780
+ return await iap.presentCodeRedemptionSheetIOS();
780
781
  } catch (error) {
781
- console.error('[presentCodeRedemptionSheetIOS] Failed:', error)
782
- const errorJson = parseErrorStringToJsonObj(error)
783
- throw new Error(errorJson.message)
782
+ console.error('[presentCodeRedemptionSheetIOS] Failed:', error);
783
+ const errorJson = parseErrorStringToJsonObj(error);
784
+ throw new Error(errorJson.message);
784
785
  }
785
- }
786
+ };
786
787
 
787
788
  /**
788
789
  * Buy promoted product on iOS
@@ -791,24 +792,24 @@ export const presentCodeRedemptionSheetIOS = async (): Promise<boolean> => {
791
792
  */
792
793
  export const buyPromotedProductIOS = async (): Promise<void> => {
793
794
  if (Platform.OS !== 'ios') {
794
- throw new Error('buyPromotedProductIOS is only available on iOS')
795
+ throw new Error('buyPromotedProductIOS is only available on iOS');
795
796
  }
796
797
 
797
798
  if (!iap) {
798
799
  const errorJson = parseErrorStringToJsonObj(
799
- 'RnIap: Service not initialized. Call initConnection() first.'
800
- )
801
- throw new Error(errorJson.message)
800
+ 'RnIap: Service not initialized. Call initConnection() first.',
801
+ );
802
+ throw new Error(errorJson.message);
802
803
  }
803
804
 
804
805
  try {
805
- await iap.buyPromotedProductIOS()
806
+ await iap.buyPromotedProductIOS();
806
807
  } catch (error) {
807
- console.error('[buyPromotedProductIOS] Failed:', error)
808
- const errorJson = parseErrorStringToJsonObj(error)
809
- throw new Error(errorJson.message)
808
+ console.error('[buyPromotedProductIOS] Failed:', error);
809
+ const errorJson = parseErrorStringToJsonObj(error);
810
+ throw new Error(errorJson.message);
810
811
  }
811
- }
812
+ };
812
813
 
813
814
  /**
814
815
  * Clear unfinished transactions on iOS
@@ -817,24 +818,24 @@ export const buyPromotedProductIOS = async (): Promise<void> => {
817
818
  */
818
819
  export const clearTransactionIOS = async (): Promise<void> => {
819
820
  if (Platform.OS !== 'ios') {
820
- return
821
+ return;
821
822
  }
822
823
 
823
824
  if (!iap) {
824
825
  const errorJson = parseErrorStringToJsonObj(
825
- 'RnIap: Service not initialized. Call initConnection() first.'
826
- )
827
- throw new Error(errorJson.message)
826
+ 'RnIap: Service not initialized. Call initConnection() first.',
827
+ );
828
+ throw new Error(errorJson.message);
828
829
  }
829
830
 
830
831
  try {
831
- await iap.clearTransactionIOS()
832
+ await iap.clearTransactionIOS();
832
833
  } catch (error) {
833
- console.error('[clearTransactionIOS] Failed:', error)
834
- const errorJson = parseErrorStringToJsonObj(error)
835
- throw new Error(errorJson.message)
834
+ console.error('[clearTransactionIOS] Failed:', error);
835
+ const errorJson = parseErrorStringToJsonObj(error);
836
+ throw new Error(errorJson.message);
836
837
  }
837
- }
838
+ };
838
839
 
839
840
  /**
840
841
  * Begin a refund request for a product on iOS 15+
@@ -843,27 +844,27 @@ export const clearTransactionIOS = async (): Promise<void> => {
843
844
  * @platform iOS
844
845
  */
845
846
  export const beginRefundRequestIOS = async (
846
- sku: string
847
+ sku: string,
847
848
  ): Promise<string | null> => {
848
849
  if (Platform.OS !== 'ios') {
849
- return null
850
+ return null;
850
851
  }
851
852
 
852
853
  if (!iap) {
853
854
  const errorJson = parseErrorStringToJsonObj(
854
- 'RnIap: Service not initialized. Call initConnection() first.'
855
- )
856
- throw new Error(errorJson.message)
855
+ 'RnIap: Service not initialized. Call initConnection() first.',
856
+ );
857
+ throw new Error(errorJson.message);
857
858
  }
858
859
 
859
860
  try {
860
- return await iap.beginRefundRequestIOS(sku)
861
+ return await iap.beginRefundRequestIOS(sku);
861
862
  } catch (error) {
862
- console.error('[beginRefundRequestIOS] Failed:', error)
863
- const errorJson = parseErrorStringToJsonObj(error)
864
- throw new Error(errorJson.message)
863
+ console.error('[beginRefundRequestIOS] Failed:', error);
864
+ const errorJson = parseErrorStringToJsonObj(error);
865
+ throw new Error(errorJson.message);
865
866
  }
866
- }
867
+ };
867
868
 
868
869
  /**
869
870
  * Get subscription status for a product (iOS only)
@@ -873,25 +874,25 @@ export const beginRefundRequestIOS = async (
873
874
  */
874
875
  export const subscriptionStatusIOS = async (sku: string): Promise<any[]> => {
875
876
  if (Platform.OS !== 'ios') {
876
- throw new Error('subscriptionStatusIOS is only available on iOS')
877
+ throw new Error('subscriptionStatusIOS is only available on iOS');
877
878
  }
878
879
 
879
880
  if (!iap) {
880
881
  const errorJson = parseErrorStringToJsonObj(
881
- 'RnIap: Service not initialized. Call initConnection() first.'
882
- )
883
- throw new Error(errorJson.message)
882
+ 'RnIap: Service not initialized. Call initConnection() first.',
883
+ );
884
+ throw new Error(errorJson.message);
884
885
  }
885
886
 
886
887
  try {
887
- const statuses = await iap.subscriptionStatusIOS(sku)
888
- return statuses || []
888
+ const statuses = await iap.subscriptionStatusIOS(sku);
889
+ return statuses || [];
889
890
  } catch (error) {
890
- console.error('[subscriptionStatusIOS] Failed:', error)
891
- const errorJson = parseErrorStringToJsonObj(error)
892
- throw new Error(errorJson.message)
891
+ console.error('[subscriptionStatusIOS] Failed:', error);
892
+ const errorJson = parseErrorStringToJsonObj(error);
893
+ throw new Error(errorJson.message);
893
894
  }
894
- }
895
+ };
895
896
 
896
897
  /**
897
898
  * Get current entitlement for a product (iOS only)
@@ -900,31 +901,31 @@ export const subscriptionStatusIOS = async (sku: string): Promise<any[]> => {
900
901
  * @platform iOS
901
902
  */
902
903
  export const currentEntitlementIOS = async (
903
- sku: string
904
+ sku: string,
904
905
  ): Promise<Purchase | null> => {
905
906
  if (Platform.OS !== 'ios') {
906
- return null
907
+ return null;
907
908
  }
908
909
 
909
910
  if (!iap) {
910
911
  const errorJson = parseErrorStringToJsonObj(
911
- 'RnIap: Service not initialized. Call initConnection() first.'
912
- )
913
- throw new Error(errorJson.message)
912
+ 'RnIap: Service not initialized. Call initConnection() first.',
913
+ );
914
+ throw new Error(errorJson.message);
914
915
  }
915
916
 
916
917
  try {
917
- const nitroPurchase = await iap.currentEntitlementIOS(sku)
918
+ const nitroPurchase = await iap.currentEntitlementIOS(sku);
918
919
  if (nitroPurchase) {
919
- return convertNitroPurchaseToPurchase(nitroPurchase)
920
+ return convertNitroPurchaseToPurchase(nitroPurchase);
920
921
  }
921
- return null
922
+ return null;
922
923
  } catch (error) {
923
- console.error('[currentEntitlementIOS] Failed:', error)
924
- const errorJson = parseErrorStringToJsonObj(error)
925
- throw new Error(errorJson.message)
924
+ console.error('[currentEntitlementIOS] Failed:', error);
925
+ const errorJson = parseErrorStringToJsonObj(error);
926
+ throw new Error(errorJson.message);
926
927
  }
927
- }
928
+ };
928
929
 
929
930
  /**
930
931
  * Get latest transaction for a product (iOS only)
@@ -933,31 +934,31 @@ export const currentEntitlementIOS = async (
933
934
  * @platform iOS
934
935
  */
935
936
  export const latestTransactionIOS = async (
936
- sku: string
937
+ sku: string,
937
938
  ): Promise<Purchase | null> => {
938
939
  if (Platform.OS !== 'ios') {
939
- return null
940
+ return null;
940
941
  }
941
942
 
942
943
  if (!iap) {
943
944
  const errorJson = parseErrorStringToJsonObj(
944
- 'RnIap: Service not initialized. Call initConnection() first.'
945
- )
946
- throw new Error(errorJson.message)
945
+ 'RnIap: Service not initialized. Call initConnection() first.',
946
+ );
947
+ throw new Error(errorJson.message);
947
948
  }
948
949
 
949
950
  try {
950
- const nitroPurchase = await iap.latestTransactionIOS(sku)
951
+ const nitroPurchase = await iap.latestTransactionIOS(sku);
951
952
  if (nitroPurchase) {
952
- return convertNitroPurchaseToPurchase(nitroPurchase)
953
+ return convertNitroPurchaseToPurchase(nitroPurchase);
953
954
  }
954
- return null
955
+ return null;
955
956
  } catch (error) {
956
- console.error('[latestTransactionIOS] Failed:', error)
957
- const errorJson = parseErrorStringToJsonObj(error)
958
- throw new Error(errorJson.message)
957
+ console.error('[latestTransactionIOS] Failed:', error);
958
+ const errorJson = parseErrorStringToJsonObj(error);
959
+ throw new Error(errorJson.message);
959
960
  }
960
- }
961
+ };
961
962
 
962
963
  /**
963
964
  * Get pending transactions (iOS only)
@@ -966,25 +967,25 @@ export const latestTransactionIOS = async (
966
967
  */
967
968
  export const getPendingTransactionsIOS = async (): Promise<Purchase[]> => {
968
969
  if (Platform.OS !== 'ios') {
969
- return []
970
+ return [];
970
971
  }
971
972
 
972
973
  if (!iap) {
973
974
  const errorJson = parseErrorStringToJsonObj(
974
- 'RnIap: Service not initialized. Call initConnection() first.'
975
- )
976
- throw new Error(errorJson.message)
975
+ 'RnIap: Service not initialized. Call initConnection() first.',
976
+ );
977
+ throw new Error(errorJson.message);
977
978
  }
978
979
 
979
980
  try {
980
- const nitroPurchases = await iap.getPendingTransactionsIOS()
981
- return nitroPurchases.map(convertNitroPurchaseToPurchase)
981
+ const nitroPurchases = await iap.getPendingTransactionsIOS();
982
+ return nitroPurchases.map(convertNitroPurchaseToPurchase);
982
983
  } catch (error) {
983
- console.error('[getPendingTransactionsIOS] Failed:', error)
984
- const errorJson = parseErrorStringToJsonObj(error)
985
- throw new Error(errorJson.message)
984
+ console.error('[getPendingTransactionsIOS] Failed:', error);
985
+ const errorJson = parseErrorStringToJsonObj(error);
986
+ throw new Error(errorJson.message);
986
987
  }
987
- }
988
+ };
988
989
 
989
990
  /**
990
991
  * Show manage subscriptions screen (iOS only)
@@ -993,25 +994,25 @@ export const getPendingTransactionsIOS = async (): Promise<Purchase[]> => {
993
994
  */
994
995
  export const showManageSubscriptionsIOS = async (): Promise<Purchase[]> => {
995
996
  if (Platform.OS !== 'ios') {
996
- return []
997
+ return [];
997
998
  }
998
999
 
999
1000
  if (!iap) {
1000
1001
  const errorJson = parseErrorStringToJsonObj(
1001
- 'RnIap: Service not initialized. Call initConnection() first.'
1002
- )
1003
- throw new Error(errorJson.message)
1002
+ 'RnIap: Service not initialized. Call initConnection() first.',
1003
+ );
1004
+ throw new Error(errorJson.message);
1004
1005
  }
1005
1006
 
1006
1007
  try {
1007
- const nitroPurchases = await iap.showManageSubscriptionsIOS()
1008
- return nitroPurchases.map(convertNitroPurchaseToPurchase)
1008
+ const nitroPurchases = await iap.showManageSubscriptionsIOS();
1009
+ return nitroPurchases.map(convertNitroPurchaseToPurchase);
1009
1010
  } catch (error) {
1010
- console.error('[showManageSubscriptionsIOS] Failed:', error)
1011
- const errorJson = parseErrorStringToJsonObj(error)
1012
- throw new Error(errorJson.message)
1011
+ console.error('[showManageSubscriptionsIOS] Failed:', error);
1012
+ const errorJson = parseErrorStringToJsonObj(error);
1013
+ throw new Error(errorJson.message);
1013
1014
  }
1014
- }
1015
+ };
1015
1016
 
1016
1017
  /**
1017
1018
  * Check if user is eligible for intro offer (iOS only)
@@ -1020,27 +1021,27 @@ export const showManageSubscriptionsIOS = async (): Promise<Purchase[]> => {
1020
1021
  * @platform iOS
1021
1022
  */
1022
1023
  export const isEligibleForIntroOfferIOS = async (
1023
- groupID: string
1024
+ groupID: string,
1024
1025
  ): Promise<boolean> => {
1025
1026
  if (Platform.OS !== 'ios') {
1026
- return false
1027
+ return false;
1027
1028
  }
1028
1029
 
1029
1030
  if (!iap) {
1030
1031
  const errorJson = parseErrorStringToJsonObj(
1031
- 'RnIap: Service not initialized. Call initConnection() first.'
1032
- )
1033
- throw new Error(errorJson.message)
1032
+ 'RnIap: Service not initialized. Call initConnection() first.',
1033
+ );
1034
+ throw new Error(errorJson.message);
1034
1035
  }
1035
1036
 
1036
1037
  try {
1037
- return await iap.isEligibleForIntroOfferIOS(groupID)
1038
+ return await iap.isEligibleForIntroOfferIOS(groupID);
1038
1039
  } catch (error) {
1039
- console.error('[isEligibleForIntroOfferIOS] Failed:', error)
1040
- const errorJson = parseErrorStringToJsonObj(error)
1041
- throw new Error(errorJson.message)
1040
+ console.error('[isEligibleForIntroOfferIOS] Failed:', error);
1041
+ const errorJson = parseErrorStringToJsonObj(error);
1042
+ throw new Error(errorJson.message);
1042
1043
  }
1043
- }
1044
+ };
1044
1045
 
1045
1046
  /**
1046
1047
  * Get receipt data (iOS only)
@@ -1049,24 +1050,24 @@ export const isEligibleForIntroOfferIOS = async (
1049
1050
  */
1050
1051
  export const getReceiptDataIOS = async (): Promise<string> => {
1051
1052
  if (Platform.OS !== 'ios') {
1052
- throw new Error('getReceiptDataIOS is only available on iOS')
1053
+ throw new Error('getReceiptDataIOS is only available on iOS');
1053
1054
  }
1054
1055
 
1055
1056
  if (!iap) {
1056
1057
  const errorJson = parseErrorStringToJsonObj(
1057
- 'RnIap: Service not initialized. Call initConnection() first.'
1058
- )
1059
- throw new Error(errorJson.message)
1058
+ 'RnIap: Service not initialized. Call initConnection() first.',
1059
+ );
1060
+ throw new Error(errorJson.message);
1060
1061
  }
1061
1062
 
1062
1063
  try {
1063
- return await iap.getReceiptDataIOS()
1064
+ return await iap.getReceiptDataIOS();
1064
1065
  } catch (error) {
1065
- console.error('[getReceiptDataIOS] Failed:', error)
1066
- const errorJson = parseErrorStringToJsonObj(error)
1067
- throw new Error(errorJson.message)
1066
+ console.error('[getReceiptDataIOS] Failed:', error);
1067
+ const errorJson = parseErrorStringToJsonObj(error);
1068
+ throw new Error(errorJson.message);
1068
1069
  }
1069
- }
1070
+ };
1070
1071
 
1071
1072
  /**
1072
1073
  * Check if transaction is verified (iOS only)
@@ -1075,27 +1076,27 @@ export const getReceiptDataIOS = async (): Promise<string> => {
1075
1076
  * @platform iOS
1076
1077
  */
1077
1078
  export const isTransactionVerifiedIOS = async (
1078
- sku: string
1079
+ sku: string,
1079
1080
  ): Promise<boolean> => {
1080
1081
  if (Platform.OS !== 'ios') {
1081
- return false
1082
+ return false;
1082
1083
  }
1083
1084
 
1084
1085
  if (!iap) {
1085
1086
  const errorJson = parseErrorStringToJsonObj(
1086
- 'RnIap: Service not initialized. Call initConnection() first.'
1087
- )
1088
- throw new Error(errorJson.message)
1087
+ 'RnIap: Service not initialized. Call initConnection() first.',
1088
+ );
1089
+ throw new Error(errorJson.message);
1089
1090
  }
1090
1091
 
1091
1092
  try {
1092
- return await iap.isTransactionVerifiedIOS(sku)
1093
+ return await iap.isTransactionVerifiedIOS(sku);
1093
1094
  } catch (error) {
1094
- console.error('[isTransactionVerifiedIOS] Failed:', error)
1095
- const errorJson = parseErrorStringToJsonObj(error)
1096
- throw new Error(errorJson.message)
1095
+ console.error('[isTransactionVerifiedIOS] Failed:', error);
1096
+ const errorJson = parseErrorStringToJsonObj(error);
1097
+ throw new Error(errorJson.message);
1097
1098
  }
1098
- }
1099
+ };
1099
1100
 
1100
1101
  /**
1101
1102
  * Get transaction JWS representation (iOS only)
@@ -1104,27 +1105,27 @@ export const isTransactionVerifiedIOS = async (
1104
1105
  * @platform iOS
1105
1106
  */
1106
1107
  export const getTransactionJwsIOS = async (
1107
- sku: string
1108
+ sku: string,
1108
1109
  ): Promise<string | null> => {
1109
1110
  if (Platform.OS !== 'ios') {
1110
- return null
1111
+ return null;
1111
1112
  }
1112
1113
 
1113
1114
  if (!iap) {
1114
1115
  const errorJson = parseErrorStringToJsonObj(
1115
- 'RnIap: Service not initialized. Call initConnection() first.'
1116
- )
1117
- throw new Error(errorJson.message)
1116
+ 'RnIap: Service not initialized. Call initConnection() first.',
1117
+ );
1118
+ throw new Error(errorJson.message);
1118
1119
  }
1119
1120
 
1120
1121
  try {
1121
- return await iap.getTransactionJwsIOS(sku)
1122
+ return await iap.getTransactionJwsIOS(sku);
1122
1123
  } catch (error) {
1123
- console.error('[getTransactionJwsIOS] Failed:', error)
1124
- const errorJson = parseErrorStringToJsonObj(error)
1125
- throw new Error(errorJson.message)
1124
+ console.error('[getTransactionJwsIOS] Failed:', error);
1125
+ const errorJson = parseErrorStringToJsonObj(error);
1126
+ throw new Error(errorJson.message);
1126
1127
  }
1127
- }
1128
+ };
1128
1129
 
1129
1130
  /**
1130
1131
  * Get the storefront identifier for the user's App Store account (iOS only)
@@ -1139,18 +1140,18 @@ export const getTransactionJwsIOS = async (
1139
1140
  */
1140
1141
  export const getStorefrontIOS = async (): Promise<string> => {
1141
1142
  if (Platform.OS !== 'ios') {
1142
- throw new Error('getStorefrontIOS is only available on iOS')
1143
+ throw new Error('getStorefrontIOS is only available on iOS');
1143
1144
  }
1144
1145
 
1145
1146
  try {
1146
1147
  // Call the native method to get storefront
1147
- const storefront = await iap.getStorefrontIOS()
1148
- return storefront
1148
+ const storefront = await iap.getStorefrontIOS();
1149
+ return storefront;
1149
1150
  } catch (error) {
1150
- console.error('Failed to get storefront:', error)
1151
- throw error
1151
+ console.error('Failed to get storefront:', error);
1152
+ throw error;
1152
1153
  }
1153
- }
1154
+ };
1154
1155
 
1155
1156
  /**
1156
1157
  * iOS only - Gets the original app transaction ID if the app was purchased from the App Store
@@ -1173,24 +1174,24 @@ export const getStorefrontIOS = async (): Promise<string> => {
1173
1174
  */
1174
1175
  export const getAppTransactionIOS = async (): Promise<string | null> => {
1175
1176
  if (Platform.OS !== 'ios') {
1176
- throw new Error('getAppTransactionIOS is only available on iOS')
1177
+ throw new Error('getAppTransactionIOS is only available on iOS');
1177
1178
  }
1178
1179
 
1179
1180
  try {
1180
1181
  // Call the native method to get app transaction
1181
- const appTransaction = await iap.getAppTransactionIOS()
1182
- return appTransaction
1182
+ const appTransaction = await iap.getAppTransactionIOS();
1183
+ return appTransaction;
1183
1184
  } catch (error) {
1184
- console.error('Failed to get app transaction:', error)
1185
- throw error
1185
+ console.error('Failed to get app transaction:', error);
1186
+ throw error;
1186
1187
  }
1187
- }
1188
+ };
1188
1189
 
1189
1190
  // Export subscription helpers
1190
1191
  export {
1191
1192
  getActiveSubscriptions,
1192
1193
  hasActiveSubscriptions,
1193
- } from './helpers/subscription'
1194
+ } from './helpers/subscription';
1194
1195
 
1195
1196
  // Type conversion utilities
1196
1197
  export {
@@ -1200,15 +1201,15 @@ export {
1200
1201
  validateNitroProduct,
1201
1202
  validateNitroPurchase,
1202
1203
  checkTypeSynchronization,
1203
- } from './utils/type-bridge'
1204
+ } from './utils/type-bridge';
1204
1205
 
1205
1206
  // Deprecated exports for backward compatibility
1206
1207
  /**
1207
1208
  * @deprecated Use acknowledgePurchaseAndroid instead
1208
1209
  */
1209
- export const acknowledgePurchase = acknowledgePurchaseAndroid
1210
+ export const acknowledgePurchase = acknowledgePurchaseAndroid;
1210
1211
 
1211
1212
  /**
1212
1213
  * @deprecated Use consumePurchaseAndroid instead
1213
1214
  */
1214
- export const consumePurchase = consumePurchaseAndroid
1215
+ export const consumePurchase = consumePurchaseAndroid;