react-native-iap 14.2.2 → 14.2.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.
- package/NitroIap.podspec +4 -1
- package/README.md +10 -0
- package/android/src/main/java/com/margelo/nitro/iap/HybridRnIap.kt +5 -1
- package/app.plugin.js +1 -1
- package/lib/module/helpers/subscription.js.map +1 -1
- package/lib/module/hooks/useIAP.js.map +1 -1
- package/lib/module/index.js.map +1 -1
- package/lib/module/types/react-test-renderer.d.js +2 -0
- package/lib/module/types/react-test-renderer.d.js.map +1 -0
- package/lib/module/utils/error.js.map +1 -1
- package/lib/module/utils/errorMapping.js.map +1 -1
- package/lib/module/utils/type-bridge.js.map +1 -1
- package/lib/typescript/plugin/src/withIAP.d.ts.map +1 -1
- package/lib/typescript/src/helpers/subscription.d.ts.map +1 -1
- package/lib/typescript/src/hooks/useIAP.d.ts.map +1 -1
- package/lib/typescript/src/index.d.ts.map +1 -1
- package/lib/typescript/src/specs/RnIap.nitro.d.ts.map +1 -1
- package/lib/typescript/src/types.d.ts.map +1 -1
- package/lib/typescript/src/utils/error.d.ts.map +1 -1
- package/lib/typescript/src/utils/errorMapping.d.ts.map +1 -1
- package/lib/typescript/src/utils/type-bridge.d.ts.map +1 -1
- package/package.json +1 -9
- package/plugin/src/withIAP.ts +59 -59
- package/src/helpers/subscription.ts +21 -21
- package/src/hooks/useIAP.ts +193 -193
- package/src/index.ts +346 -344
- package/src/specs/RnIap.nitro.ts +160 -157
- package/src/types/react-test-renderer.d.ts +7 -0
- package/src/types.ts +294 -294
- package/src/utils/error.ts +19 -19
- package/src/utils/errorMapping.ts +13 -13
- package/src/utils/type-bridge.ts +94 -93
package/src/index.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
// External dependencies
|
|
2
|
-
import {
|
|
3
|
-
import {
|
|
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,
|
|
@@ -24,16 +24,16 @@ import type {
|
|
|
24
24
|
RequestPurchaseIosProps,
|
|
25
25
|
RequestPurchaseAndroidProps,
|
|
26
26
|
SubscriptionStatusIOS,
|
|
27
|
-
} from './types'
|
|
28
|
-
import type {
|
|
27
|
+
} from './types';
|
|
28
|
+
import type {ProductRequest} from './types';
|
|
29
29
|
import {
|
|
30
30
|
convertNitroProductToProduct,
|
|
31
31
|
convertNitroPurchaseToPurchase,
|
|
32
32
|
validateNitroProduct,
|
|
33
33
|
validateNitroPurchase,
|
|
34
34
|
convertNitroSubscriptionStatusToSubscriptionStatusIOS,
|
|
35
|
-
} from './utils/type-bridge'
|
|
36
|
-
import {
|
|
35
|
+
} from './utils/type-bridge';
|
|
36
|
+
import {parseErrorStringToJsonObj} from './utils/error';
|
|
37
37
|
|
|
38
38
|
// Export all types
|
|
39
39
|
export type {
|
|
@@ -41,67 +41,67 @@ export type {
|
|
|
41
41
|
NitroProduct,
|
|
42
42
|
NitroPurchase,
|
|
43
43
|
NitroPurchaseResult,
|
|
44
|
-
} from './specs/RnIap.nitro'
|
|
45
|
-
export * from './types'
|
|
46
|
-
export * from './utils/error'
|
|
44
|
+
} from './specs/RnIap.nitro';
|
|
45
|
+
export * from './types';
|
|
46
|
+
export * from './utils/error';
|
|
47
47
|
|
|
48
48
|
// Types for event listeners
|
|
49
49
|
export interface EventSubscription {
|
|
50
|
-
remove(): void
|
|
50
|
+
remove(): void;
|
|
51
51
|
}
|
|
52
52
|
|
|
53
53
|
// ActiveSubscription and PurchaseError types are already exported via 'export * from ./types'
|
|
54
54
|
|
|
55
55
|
// Export hooks
|
|
56
|
-
export {
|
|
56
|
+
export {useIAP} from './hooks/useIAP';
|
|
57
57
|
|
|
58
58
|
// iOS promoted product aliases for API parity
|
|
59
59
|
export const getPromotedProductIOS = async (): Promise<Product | null> =>
|
|
60
|
-
requestPromotedProductIOS()
|
|
60
|
+
requestPromotedProductIOS();
|
|
61
61
|
export const requestPurchaseOnPromotedProductIOS = async (): Promise<void> =>
|
|
62
|
-
buyPromotedProductIOS()
|
|
62
|
+
buyPromotedProductIOS();
|
|
63
63
|
|
|
64
64
|
// Restore completed transactions (cross-platform)
|
|
65
65
|
export const restorePurchases = async (
|
|
66
66
|
options: PurchaseOptions = {
|
|
67
67
|
alsoPublishToEventListenerIOS: false,
|
|
68
68
|
onlyIncludeActiveItemsIOS: true,
|
|
69
|
-
}
|
|
69
|
+
},
|
|
70
70
|
): Promise<Purchase[]> => {
|
|
71
71
|
if (Platform.OS === 'ios') {
|
|
72
|
-
await syncIOS()
|
|
72
|
+
await syncIOS();
|
|
73
73
|
}
|
|
74
|
-
return getAvailablePurchases(options)
|
|
75
|
-
}
|
|
74
|
+
return getAvailablePurchases(options);
|
|
75
|
+
};
|
|
76
76
|
|
|
77
77
|
// Development utilities removed - use type bridge functions directly if needed
|
|
78
78
|
|
|
79
79
|
// Create the RnIap HybridObject instance (internal use only)
|
|
80
|
-
const iap = NitroModules.createHybridObject<RnIap>('RnIap')
|
|
80
|
+
const iap = NitroModules.createHybridObject<RnIap>('RnIap');
|
|
81
81
|
|
|
82
82
|
/**
|
|
83
83
|
* Initialize connection to the store
|
|
84
84
|
*/
|
|
85
85
|
export const initConnection = async (): Promise<boolean> => {
|
|
86
86
|
try {
|
|
87
|
-
return await iap.initConnection()
|
|
87
|
+
return await iap.initConnection();
|
|
88
88
|
} catch (error) {
|
|
89
|
-
console.error('Failed to initialize IAP connection:', error)
|
|
90
|
-
throw error
|
|
89
|
+
console.error('Failed to initialize IAP connection:', error);
|
|
90
|
+
throw error;
|
|
91
91
|
}
|
|
92
|
-
}
|
|
92
|
+
};
|
|
93
93
|
|
|
94
94
|
/**
|
|
95
95
|
* End connection to the store
|
|
96
96
|
*/
|
|
97
97
|
export const endConnection = async (): Promise<boolean> => {
|
|
98
98
|
try {
|
|
99
|
-
return await iap.endConnection()
|
|
99
|
+
return await iap.endConnection();
|
|
100
100
|
} catch (error) {
|
|
101
|
-
console.error('Failed to end IAP connection:', error)
|
|
102
|
-
throw error
|
|
101
|
+
console.error('Failed to end IAP connection:', error);
|
|
102
|
+
throw error;
|
|
103
103
|
}
|
|
104
|
-
}
|
|
104
|
+
};
|
|
105
105
|
|
|
106
106
|
/**
|
|
107
107
|
* Fetch products from the store
|
|
@@ -125,41 +125,41 @@ export const fetchProducts = async ({
|
|
|
125
125
|
}: ProductRequest): Promise<Product[]> => {
|
|
126
126
|
try {
|
|
127
127
|
if (!skus || skus.length === 0) {
|
|
128
|
-
throw new Error('No SKUs provided')
|
|
128
|
+
throw new Error('No SKUs provided');
|
|
129
129
|
}
|
|
130
130
|
|
|
131
131
|
if (type === 'all') {
|
|
132
132
|
const [inappNitro, subsNitro] = await Promise.all([
|
|
133
133
|
iap.fetchProducts(skus, 'inapp'),
|
|
134
134
|
iap.fetchProducts(skus, 'subs'),
|
|
135
|
-
])
|
|
136
|
-
const allNitro = [...inappNitro, ...subsNitro]
|
|
137
|
-
const validAll = allNitro.filter(validateNitroProduct)
|
|
135
|
+
]);
|
|
136
|
+
const allNitro = [...inappNitro, ...subsNitro];
|
|
137
|
+
const validAll = allNitro.filter(validateNitroProduct);
|
|
138
138
|
if (validAll.length !== allNitro.length) {
|
|
139
139
|
console.warn(
|
|
140
|
-
`[fetchProducts] Some products failed validation: ${allNitro.length - validAll.length} invalid
|
|
141
|
-
)
|
|
140
|
+
`[fetchProducts] Some products failed validation: ${allNitro.length - validAll.length} invalid`,
|
|
141
|
+
);
|
|
142
142
|
}
|
|
143
|
-
return validAll.map(convertNitroProductToProduct)
|
|
143
|
+
return validAll.map(convertNitroProductToProduct);
|
|
144
144
|
}
|
|
145
145
|
|
|
146
|
-
const nitroProducts = await iap.fetchProducts(skus, type)
|
|
146
|
+
const nitroProducts = await iap.fetchProducts(skus, type);
|
|
147
147
|
|
|
148
148
|
// Validate and convert NitroProducts to TypeScript Products
|
|
149
|
-
const validProducts = nitroProducts.filter(validateNitroProduct)
|
|
149
|
+
const validProducts = nitroProducts.filter(validateNitroProduct);
|
|
150
150
|
if (validProducts.length !== nitroProducts.length) {
|
|
151
151
|
console.warn(
|
|
152
|
-
`[fetchProducts] Some products failed validation: ${nitroProducts.length - validProducts.length} invalid
|
|
153
|
-
)
|
|
152
|
+
`[fetchProducts] Some products failed validation: ${nitroProducts.length - validProducts.length} invalid`,
|
|
153
|
+
);
|
|
154
154
|
}
|
|
155
155
|
|
|
156
|
-
const typedProducts = validProducts.map(convertNitroProductToProduct)
|
|
157
|
-
return typedProducts
|
|
156
|
+
const typedProducts = validProducts.map(convertNitroProductToProduct);
|
|
157
|
+
return typedProducts;
|
|
158
158
|
} catch (error) {
|
|
159
|
-
console.error('[fetchProducts] Failed:', error)
|
|
160
|
-
throw error
|
|
159
|
+
console.error('[fetchProducts] Failed:', error);
|
|
160
|
+
throw error;
|
|
161
161
|
}
|
|
162
|
-
}
|
|
162
|
+
};
|
|
163
163
|
|
|
164
164
|
/**
|
|
165
165
|
* Request a purchase for products or subscriptions
|
|
@@ -203,65 +203,65 @@ export const requestPurchase = async ({
|
|
|
203
203
|
request,
|
|
204
204
|
type = 'inapp',
|
|
205
205
|
}: {
|
|
206
|
-
request: RequestPurchaseProps | RequestSubscriptionProps
|
|
207
|
-
type?: 'inapp' | 'subs'
|
|
206
|
+
request: RequestPurchaseProps | RequestSubscriptionProps;
|
|
207
|
+
type?: 'inapp' | 'subs';
|
|
208
208
|
}): Promise<void> => {
|
|
209
209
|
try {
|
|
210
210
|
// Validate platform-specific requests
|
|
211
211
|
if (Platform.OS === 'ios') {
|
|
212
|
-
const iosRequest = request.ios
|
|
212
|
+
const iosRequest = request.ios;
|
|
213
213
|
if (!iosRequest?.sku) {
|
|
214
214
|
throw new Error(
|
|
215
|
-
'Invalid request for iOS. The `sku` property is required.'
|
|
216
|
-
)
|
|
215
|
+
'Invalid request for iOS. The `sku` property is required.',
|
|
216
|
+
);
|
|
217
217
|
}
|
|
218
218
|
} else if (Platform.OS === 'android') {
|
|
219
|
-
const androidRequest = request.android
|
|
219
|
+
const androidRequest = request.android;
|
|
220
220
|
if (!androidRequest?.skus?.length) {
|
|
221
221
|
throw new Error(
|
|
222
|
-
'Invalid request for Android. The `skus` property is required and must be a non-empty array.'
|
|
223
|
-
)
|
|
222
|
+
'Invalid request for Android. The `skus` property is required and must be a non-empty array.',
|
|
223
|
+
);
|
|
224
224
|
}
|
|
225
225
|
} else {
|
|
226
|
-
throw new Error('Unsupported platform')
|
|
226
|
+
throw new Error('Unsupported platform');
|
|
227
227
|
}
|
|
228
228
|
|
|
229
229
|
// Transform the request for the unified interface
|
|
230
|
-
const unifiedRequest: any = {}
|
|
230
|
+
const unifiedRequest: any = {};
|
|
231
231
|
|
|
232
232
|
if (Platform.OS === 'ios' && request.ios) {
|
|
233
|
-
const iosReq = request.ios as RequestPurchaseIosProps
|
|
233
|
+
const iosReq = request.ios as RequestPurchaseIosProps;
|
|
234
234
|
const autoFinishSubs =
|
|
235
235
|
type === 'subs' &&
|
|
236
|
-
iosReq.andDangerouslyFinishTransactionAutomatically == null
|
|
236
|
+
iosReq.andDangerouslyFinishTransactionAutomatically == null;
|
|
237
237
|
unifiedRequest.ios = {
|
|
238
238
|
...iosReq,
|
|
239
239
|
// Align with native SwiftUI flow: auto-finish subscriptions by default
|
|
240
240
|
...(autoFinishSubs
|
|
241
|
-
? {
|
|
241
|
+
? {andDangerouslyFinishTransactionAutomatically: true}
|
|
242
242
|
: {}),
|
|
243
|
-
} as RequestPurchaseIosProps
|
|
243
|
+
} as RequestPurchaseIosProps;
|
|
244
244
|
}
|
|
245
245
|
|
|
246
246
|
if (Platform.OS === 'android' && request.android) {
|
|
247
247
|
if (type === 'subs') {
|
|
248
|
-
const subsRequest = request.android as RequestSubscriptionAndroidProps
|
|
248
|
+
const subsRequest = request.android as RequestSubscriptionAndroidProps;
|
|
249
249
|
unifiedRequest.android = {
|
|
250
250
|
...subsRequest,
|
|
251
251
|
subscriptionOffers: subsRequest.subscriptionOffers || [],
|
|
252
|
-
} as RequestPurchaseAndroidProps
|
|
252
|
+
} as RequestPurchaseAndroidProps;
|
|
253
253
|
} else {
|
|
254
|
-
unifiedRequest.android = request.android
|
|
254
|
+
unifiedRequest.android = request.android;
|
|
255
255
|
}
|
|
256
256
|
}
|
|
257
257
|
|
|
258
258
|
// Call unified method - returns void, listen for events instead
|
|
259
|
-
await iap.requestPurchase(unifiedRequest)
|
|
259
|
+
await iap.requestPurchase(unifiedRequest);
|
|
260
260
|
} catch (error) {
|
|
261
|
-
console.error('Failed to request purchase:', error)
|
|
262
|
-
throw error
|
|
261
|
+
console.error('Failed to request purchase:', error);
|
|
262
|
+
throw error;
|
|
263
263
|
}
|
|
264
|
-
}
|
|
264
|
+
};
|
|
265
265
|
|
|
266
266
|
/**
|
|
267
267
|
* Get available purchases (purchased items not yet consumed/finished)
|
|
@@ -282,7 +282,7 @@ export const getAvailablePurchases = async ({
|
|
|
282
282
|
}: PurchaseOptions = {}): Promise<Purchase[]> => {
|
|
283
283
|
try {
|
|
284
284
|
// Create unified options
|
|
285
|
-
const options: any = {}
|
|
285
|
+
const options: any = {};
|
|
286
286
|
|
|
287
287
|
if (Platform.OS === 'ios') {
|
|
288
288
|
// Provide both new and deprecated keys for compatibility
|
|
@@ -291,46 +291,46 @@ export const getAvailablePurchases = async ({
|
|
|
291
291
|
onlyIncludeActiveItemsIOS,
|
|
292
292
|
alsoPublishToEventListener: alsoPublishToEventListenerIOS,
|
|
293
293
|
onlyIncludeActiveItems: onlyIncludeActiveItemsIOS,
|
|
294
|
-
}
|
|
294
|
+
};
|
|
295
295
|
} else if (Platform.OS === 'android') {
|
|
296
296
|
// For Android, we need to call twice for inapp and subs
|
|
297
297
|
const inappNitroPurchases = await iap.getAvailablePurchases({
|
|
298
|
-
android: {
|
|
299
|
-
})
|
|
298
|
+
android: {type: 'inapp'},
|
|
299
|
+
});
|
|
300
300
|
const subsNitroPurchases = await iap.getAvailablePurchases({
|
|
301
|
-
android: {
|
|
302
|
-
})
|
|
301
|
+
android: {type: 'subs'},
|
|
302
|
+
});
|
|
303
303
|
|
|
304
304
|
// Validate and convert both sets of purchases
|
|
305
|
-
const allNitroPurchases = [...inappNitroPurchases, ...subsNitroPurchases]
|
|
306
|
-
const validPurchases = allNitroPurchases.filter(validateNitroPurchase)
|
|
305
|
+
const allNitroPurchases = [...inappNitroPurchases, ...subsNitroPurchases];
|
|
306
|
+
const validPurchases = allNitroPurchases.filter(validateNitroPurchase);
|
|
307
307
|
if (validPurchases.length !== allNitroPurchases.length) {
|
|
308
308
|
console.warn(
|
|
309
|
-
`[getAvailablePurchases] Some Android purchases failed validation: ${allNitroPurchases.length - validPurchases.length} invalid
|
|
310
|
-
)
|
|
309
|
+
`[getAvailablePurchases] Some Android purchases failed validation: ${allNitroPurchases.length - validPurchases.length} invalid`,
|
|
310
|
+
);
|
|
311
311
|
}
|
|
312
312
|
|
|
313
|
-
return validPurchases.map(convertNitroPurchaseToPurchase)
|
|
313
|
+
return validPurchases.map(convertNitroPurchaseToPurchase);
|
|
314
314
|
} else {
|
|
315
|
-
throw new Error('Unsupported platform')
|
|
315
|
+
throw new Error('Unsupported platform');
|
|
316
316
|
}
|
|
317
317
|
|
|
318
|
-
const nitroPurchases = await iap.getAvailablePurchases(options)
|
|
318
|
+
const nitroPurchases = await iap.getAvailablePurchases(options);
|
|
319
319
|
|
|
320
320
|
// Validate and convert NitroPurchases to TypeScript Purchases
|
|
321
|
-
const validPurchases = nitroPurchases.filter(validateNitroPurchase)
|
|
321
|
+
const validPurchases = nitroPurchases.filter(validateNitroPurchase);
|
|
322
322
|
if (validPurchases.length !== nitroPurchases.length) {
|
|
323
323
|
console.warn(
|
|
324
|
-
`[getAvailablePurchases] Some purchases failed validation: ${nitroPurchases.length - validPurchases.length} invalid
|
|
325
|
-
)
|
|
324
|
+
`[getAvailablePurchases] Some purchases failed validation: ${nitroPurchases.length - validPurchases.length} invalid`,
|
|
325
|
+
);
|
|
326
326
|
}
|
|
327
327
|
|
|
328
|
-
return validPurchases.map(convertNitroPurchaseToPurchase)
|
|
328
|
+
return validPurchases.map(convertNitroPurchaseToPurchase);
|
|
329
329
|
} catch (error) {
|
|
330
|
-
console.error('Failed to get available purchases:', error)
|
|
331
|
-
throw error
|
|
330
|
+
console.error('Failed to get available purchases:', error);
|
|
331
|
+
throw error;
|
|
332
332
|
}
|
|
333
|
-
}
|
|
333
|
+
};
|
|
334
334
|
|
|
335
335
|
/**
|
|
336
336
|
* Finish a transaction (consume or acknowledge)
|
|
@@ -352,58 +352,58 @@ export const finishTransaction = async ({
|
|
|
352
352
|
}: FinishTransactionParams): Promise<NitroPurchaseResult | boolean> => {
|
|
353
353
|
try {
|
|
354
354
|
// Create unified params
|
|
355
|
-
const params: any = {}
|
|
355
|
+
const params: any = {};
|
|
356
356
|
|
|
357
357
|
if (Platform.OS === 'ios') {
|
|
358
358
|
if (!purchase.id) {
|
|
359
|
-
throw new Error('purchase.id required to finish iOS transaction')
|
|
359
|
+
throw new Error('purchase.id required to finish iOS transaction');
|
|
360
360
|
}
|
|
361
361
|
params.ios = {
|
|
362
362
|
transactionId: purchase.id,
|
|
363
|
-
}
|
|
363
|
+
};
|
|
364
364
|
} else if (Platform.OS === 'android') {
|
|
365
|
-
const androidPurchase = purchase as PurchaseAndroid
|
|
365
|
+
const androidPurchase = purchase as PurchaseAndroid;
|
|
366
366
|
const token =
|
|
367
|
-
androidPurchase.purchaseToken || androidPurchase.purchaseTokenAndroid
|
|
367
|
+
androidPurchase.purchaseToken || androidPurchase.purchaseTokenAndroid;
|
|
368
368
|
|
|
369
369
|
if (!token) {
|
|
370
|
-
throw new Error('purchaseToken required to finish Android transaction')
|
|
370
|
+
throw new Error('purchaseToken required to finish Android transaction');
|
|
371
371
|
}
|
|
372
372
|
|
|
373
373
|
params.android = {
|
|
374
374
|
purchaseToken: token,
|
|
375
375
|
isConsumable,
|
|
376
|
-
}
|
|
376
|
+
};
|
|
377
377
|
} else {
|
|
378
|
-
throw new Error('Unsupported platform')
|
|
378
|
+
throw new Error('Unsupported platform');
|
|
379
379
|
}
|
|
380
380
|
|
|
381
|
-
const result = await iap.finishTransaction(params)
|
|
381
|
+
const result = await iap.finishTransaction(params);
|
|
382
382
|
|
|
383
383
|
// Handle variant return type
|
|
384
384
|
if (typeof result === 'boolean') {
|
|
385
|
-
return result
|
|
385
|
+
return result;
|
|
386
386
|
}
|
|
387
387
|
// It's a PurchaseResult
|
|
388
|
-
return result as NitroPurchaseResult
|
|
388
|
+
return result as NitroPurchaseResult;
|
|
389
389
|
} catch (error) {
|
|
390
390
|
// If iOS transaction has already been auto-finished natively, treat as success
|
|
391
391
|
if (Platform.OS === 'ios') {
|
|
392
|
-
const err = parseErrorStringToJsonObj(error)
|
|
393
|
-
const msg = (err?.message || '').toString()
|
|
394
|
-
const code = (err?.code || '').toString()
|
|
392
|
+
const err = parseErrorStringToJsonObj(error);
|
|
393
|
+
const msg = (err?.message || '').toString();
|
|
394
|
+
const code = (err?.code || '').toString();
|
|
395
395
|
if (
|
|
396
396
|
msg.includes('Transaction not found') ||
|
|
397
397
|
code === 'E_ITEM_UNAVAILABLE'
|
|
398
398
|
) {
|
|
399
399
|
// Consider already finished
|
|
400
|
-
return true
|
|
400
|
+
return true;
|
|
401
401
|
}
|
|
402
402
|
}
|
|
403
|
-
console.error('Failed to finish transaction:', error)
|
|
404
|
-
throw error
|
|
403
|
+
console.error('Failed to finish transaction:', error);
|
|
404
|
+
throw error;
|
|
405
405
|
}
|
|
406
|
-
}
|
|
406
|
+
};
|
|
407
407
|
|
|
408
408
|
/**
|
|
409
409
|
* Acknowledge a purchase (Android only)
|
|
@@ -415,11 +415,13 @@ export const finishTransaction = async ({
|
|
|
415
415
|
* ```
|
|
416
416
|
*/
|
|
417
417
|
export const acknowledgePurchaseAndroid = async (
|
|
418
|
-
purchaseToken: string
|
|
418
|
+
purchaseToken: string,
|
|
419
419
|
): Promise<NitroPurchaseResult> => {
|
|
420
420
|
try {
|
|
421
421
|
if (Platform.OS !== 'android') {
|
|
422
|
-
throw new Error(
|
|
422
|
+
throw new Error(
|
|
423
|
+
'acknowledgePurchaseAndroid is only available on Android',
|
|
424
|
+
);
|
|
423
425
|
}
|
|
424
426
|
|
|
425
427
|
const result = await iap.finishTransaction({
|
|
@@ -427,7 +429,7 @@ export const acknowledgePurchaseAndroid = async (
|
|
|
427
429
|
purchaseToken,
|
|
428
430
|
isConsumable: false,
|
|
429
431
|
},
|
|
430
|
-
})
|
|
432
|
+
});
|
|
431
433
|
|
|
432
434
|
// Result is a variant, extract PurchaseResult
|
|
433
435
|
if (typeof result === 'boolean') {
|
|
@@ -437,14 +439,14 @@ export const acknowledgePurchaseAndroid = async (
|
|
|
437
439
|
code: '0',
|
|
438
440
|
message: 'Success',
|
|
439
441
|
purchaseToken,
|
|
440
|
-
}
|
|
442
|
+
};
|
|
441
443
|
}
|
|
442
|
-
return result as NitroPurchaseResult
|
|
444
|
+
return result as NitroPurchaseResult;
|
|
443
445
|
} catch (error) {
|
|
444
|
-
console.error('Failed to acknowledge purchase Android:', error)
|
|
445
|
-
throw error
|
|
446
|
+
console.error('Failed to acknowledge purchase Android:', error);
|
|
447
|
+
throw error;
|
|
446
448
|
}
|
|
447
|
-
}
|
|
449
|
+
};
|
|
448
450
|
|
|
449
451
|
/**
|
|
450
452
|
* Consume a purchase (Android only)
|
|
@@ -456,11 +458,11 @@ export const acknowledgePurchaseAndroid = async (
|
|
|
456
458
|
* ```
|
|
457
459
|
*/
|
|
458
460
|
export const consumePurchaseAndroid = async (
|
|
459
|
-
purchaseToken: string
|
|
461
|
+
purchaseToken: string,
|
|
460
462
|
): Promise<NitroPurchaseResult> => {
|
|
461
463
|
try {
|
|
462
464
|
if (Platform.OS !== 'android') {
|
|
463
|
-
throw new Error('consumePurchaseAndroid is only available on Android')
|
|
465
|
+
throw new Error('consumePurchaseAndroid is only available on Android');
|
|
464
466
|
}
|
|
465
467
|
|
|
466
468
|
const result = await iap.finishTransaction({
|
|
@@ -468,7 +470,7 @@ export const consumePurchaseAndroid = async (
|
|
|
468
470
|
purchaseToken,
|
|
469
471
|
isConsumable: true,
|
|
470
472
|
},
|
|
471
|
-
})
|
|
473
|
+
});
|
|
472
474
|
|
|
473
475
|
// Result is a variant, extract PurchaseResult
|
|
474
476
|
if (typeof result === 'boolean') {
|
|
@@ -478,21 +480,21 @@ export const consumePurchaseAndroid = async (
|
|
|
478
480
|
code: '0',
|
|
479
481
|
message: 'Success',
|
|
480
482
|
purchaseToken,
|
|
481
|
-
}
|
|
483
|
+
};
|
|
482
484
|
}
|
|
483
|
-
return result as NitroPurchaseResult
|
|
485
|
+
return result as NitroPurchaseResult;
|
|
484
486
|
} catch (error) {
|
|
485
|
-
console.error('Failed to consume purchase Android:', error)
|
|
486
|
-
throw error
|
|
487
|
+
console.error('Failed to consume purchase Android:', error);
|
|
488
|
+
throw error;
|
|
487
489
|
}
|
|
488
|
-
}
|
|
490
|
+
};
|
|
489
491
|
|
|
490
492
|
// ============================================================================
|
|
491
493
|
// EVENT LISTENERS
|
|
492
494
|
// ============================================================================
|
|
493
495
|
|
|
494
496
|
// Store wrapped listeners for proper removal
|
|
495
|
-
const listenerMap = new WeakMap<Function, Function>()
|
|
497
|
+
const listenerMap = new WeakMap<Function, Function>();
|
|
496
498
|
|
|
497
499
|
/**
|
|
498
500
|
* Purchase updated event listener
|
|
@@ -515,35 +517,35 @@ const listenerMap = new WeakMap<Function, Function>()
|
|
|
515
517
|
* ```
|
|
516
518
|
*/
|
|
517
519
|
export const purchaseUpdatedListener = (
|
|
518
|
-
listener: (purchase: Purchase) => void
|
|
520
|
+
listener: (purchase: Purchase) => void,
|
|
519
521
|
): EventSubscription => {
|
|
520
522
|
// Wrap the listener to convert NitroPurchase to Purchase
|
|
521
523
|
const wrappedListener = (nitroPurchase: any) => {
|
|
522
524
|
if (validateNitroPurchase(nitroPurchase)) {
|
|
523
|
-
const convertedPurchase = convertNitroPurchaseToPurchase(nitroPurchase)
|
|
524
|
-
listener(convertedPurchase)
|
|
525
|
+
const convertedPurchase = convertNitroPurchaseToPurchase(nitroPurchase);
|
|
526
|
+
listener(convertedPurchase);
|
|
525
527
|
} else {
|
|
526
528
|
console.error(
|
|
527
529
|
'Invalid purchase data received from native:',
|
|
528
|
-
nitroPurchase
|
|
529
|
-
)
|
|
530
|
+
nitroPurchase,
|
|
531
|
+
);
|
|
530
532
|
}
|
|
531
|
-
}
|
|
533
|
+
};
|
|
532
534
|
|
|
533
535
|
// Store the wrapped listener for removal
|
|
534
|
-
listenerMap.set(listener, wrappedListener)
|
|
535
|
-
iap.addPurchaseUpdatedListener(wrappedListener)
|
|
536
|
+
listenerMap.set(listener, wrappedListener);
|
|
537
|
+
iap.addPurchaseUpdatedListener(wrappedListener);
|
|
536
538
|
|
|
537
539
|
return {
|
|
538
540
|
remove: () => {
|
|
539
|
-
const wrapped = listenerMap.get(listener)
|
|
541
|
+
const wrapped = listenerMap.get(listener);
|
|
540
542
|
if (wrapped) {
|
|
541
|
-
iap.removePurchaseUpdatedListener(wrapped as any)
|
|
542
|
-
listenerMap.delete(listener)
|
|
543
|
+
iap.removePurchaseUpdatedListener(wrapped as any);
|
|
544
|
+
listenerMap.delete(listener);
|
|
543
545
|
}
|
|
544
546
|
},
|
|
545
|
-
}
|
|
546
|
-
}
|
|
547
|
+
};
|
|
548
|
+
};
|
|
547
549
|
|
|
548
550
|
/**
|
|
549
551
|
* Purchase error event listener
|
|
@@ -573,19 +575,19 @@ export const purchaseUpdatedListener = (
|
|
|
573
575
|
* ```
|
|
574
576
|
*/
|
|
575
577
|
export const purchaseErrorListener = (
|
|
576
|
-
listener: (error: NitroPurchaseResult) => void
|
|
578
|
+
listener: (error: NitroPurchaseResult) => void,
|
|
577
579
|
): EventSubscription => {
|
|
578
580
|
// Store the listener for removal
|
|
579
|
-
listenerMap.set(listener, listener)
|
|
580
|
-
iap.addPurchaseErrorListener(listener as any)
|
|
581
|
+
listenerMap.set(listener, listener);
|
|
582
|
+
iap.addPurchaseErrorListener(listener as any);
|
|
581
583
|
|
|
582
584
|
return {
|
|
583
585
|
remove: () => {
|
|
584
|
-
iap.removePurchaseErrorListener(listener as any)
|
|
585
|
-
listenerMap.delete(listener)
|
|
586
|
+
iap.removePurchaseErrorListener(listener as any);
|
|
587
|
+
listenerMap.delete(listener);
|
|
586
588
|
},
|
|
587
|
-
}
|
|
588
|
-
}
|
|
589
|
+
};
|
|
590
|
+
};
|
|
589
591
|
|
|
590
592
|
/**
|
|
591
593
|
* iOS-only listener for App Store promoted product events.
|
|
@@ -608,42 +610,42 @@ export const purchaseErrorListener = (
|
|
|
608
610
|
* @platform iOS
|
|
609
611
|
*/
|
|
610
612
|
export const promotedProductListenerIOS = (
|
|
611
|
-
listener: (product: Product) => void
|
|
613
|
+
listener: (product: Product) => void,
|
|
612
614
|
): EventSubscription => {
|
|
613
615
|
if (Platform.OS !== 'ios') {
|
|
614
616
|
console.warn(
|
|
615
|
-
'promotedProductListenerIOS: This listener is only available on iOS'
|
|
616
|
-
)
|
|
617
|
-
return {
|
|
617
|
+
'promotedProductListenerIOS: This listener is only available on iOS',
|
|
618
|
+
);
|
|
619
|
+
return {remove: () => {}};
|
|
618
620
|
}
|
|
619
621
|
|
|
620
622
|
// Wrap the listener to convert NitroProduct to Product
|
|
621
623
|
const wrappedListener = (nitroProduct: any) => {
|
|
622
624
|
if (validateNitroProduct(nitroProduct)) {
|
|
623
|
-
const convertedProduct = convertNitroProductToProduct(nitroProduct)
|
|
624
|
-
listener(convertedProduct)
|
|
625
|
+
const convertedProduct = convertNitroProductToProduct(nitroProduct);
|
|
626
|
+
listener(convertedProduct);
|
|
625
627
|
} else {
|
|
626
628
|
console.error(
|
|
627
629
|
'Invalid promoted product data received from native:',
|
|
628
|
-
nitroProduct
|
|
629
|
-
)
|
|
630
|
+
nitroProduct,
|
|
631
|
+
);
|
|
630
632
|
}
|
|
631
|
-
}
|
|
633
|
+
};
|
|
632
634
|
|
|
633
635
|
// Store the wrapped listener for removal
|
|
634
|
-
listenerMap.set(listener, wrappedListener)
|
|
635
|
-
iap.addPromotedProductListenerIOS(wrappedListener)
|
|
636
|
+
listenerMap.set(listener, wrappedListener);
|
|
637
|
+
iap.addPromotedProductListenerIOS(wrappedListener);
|
|
636
638
|
|
|
637
639
|
return {
|
|
638
640
|
remove: () => {
|
|
639
|
-
const wrapped = listenerMap.get(listener)
|
|
641
|
+
const wrapped = listenerMap.get(listener);
|
|
640
642
|
if (wrapped) {
|
|
641
|
-
iap.removePromotedProductListenerIOS(wrapped as any)
|
|
642
|
-
listenerMap.delete(listener)
|
|
643
|
+
iap.removePromotedProductListenerIOS(wrapped as any);
|
|
644
|
+
listenerMap.delete(listener);
|
|
643
645
|
}
|
|
644
646
|
},
|
|
645
|
-
}
|
|
646
|
-
}
|
|
647
|
+
};
|
|
648
|
+
};
|
|
647
649
|
|
|
648
650
|
// ============================================================================
|
|
649
651
|
// iOS-SPECIFIC FUNCTIONS
|
|
@@ -658,30 +660,30 @@ export const promotedProductListenerIOS = (
|
|
|
658
660
|
export const validateReceipt = async (
|
|
659
661
|
sku: string,
|
|
660
662
|
androidOptions?: {
|
|
661
|
-
packageName: string
|
|
662
|
-
productToken: string
|
|
663
|
-
accessToken: string
|
|
664
|
-
isSub?: boolean
|
|
665
|
-
}
|
|
663
|
+
packageName: string;
|
|
664
|
+
productToken: string;
|
|
665
|
+
accessToken: string;
|
|
666
|
+
isSub?: boolean;
|
|
667
|
+
},
|
|
666
668
|
): Promise<import('./types').ReceiptValidationResult> => {
|
|
667
669
|
if (!iap) {
|
|
668
670
|
const errorJson = parseErrorStringToJsonObj(
|
|
669
|
-
'RnIap: Service not initialized. Call initConnection() first.'
|
|
670
|
-
)
|
|
671
|
-
throw new Error(errorJson.message)
|
|
671
|
+
'RnIap: Service not initialized. Call initConnection() first.',
|
|
672
|
+
);
|
|
673
|
+
throw new Error(errorJson.message);
|
|
672
674
|
}
|
|
673
675
|
|
|
674
676
|
try {
|
|
675
677
|
const params: NitroReceiptValidationParams = {
|
|
676
678
|
sku,
|
|
677
679
|
androidOptions,
|
|
678
|
-
}
|
|
680
|
+
};
|
|
679
681
|
|
|
680
|
-
const nitroResult = await iap.validateReceipt(params)
|
|
682
|
+
const nitroResult = await iap.validateReceipt(params);
|
|
681
683
|
|
|
682
684
|
// Convert Nitro result to public API result
|
|
683
685
|
if (Platform.OS === 'ios') {
|
|
684
|
-
const iosResult = nitroResult as NitroReceiptValidationResultIOS
|
|
686
|
+
const iosResult = nitroResult as NitroReceiptValidationResultIOS;
|
|
685
687
|
const result: ReceiptValidationResultIOS = {
|
|
686
688
|
isValid: iosResult.isValid,
|
|
687
689
|
receiptData: iosResult.receiptData,
|
|
@@ -689,11 +691,11 @@ export const validateReceipt = async (
|
|
|
689
691
|
latestTransaction: iosResult.latestTransaction
|
|
690
692
|
? convertNitroPurchaseToPurchase(iosResult.latestTransaction)
|
|
691
693
|
: undefined,
|
|
692
|
-
}
|
|
693
|
-
return result
|
|
694
|
+
};
|
|
695
|
+
return result;
|
|
694
696
|
} else {
|
|
695
697
|
// Android
|
|
696
|
-
const androidResult = nitroResult as NitroReceiptValidationResultAndroid
|
|
698
|
+
const androidResult = nitroResult as NitroReceiptValidationResultAndroid;
|
|
697
699
|
const result: ReceiptValidationResultAndroid = {
|
|
698
700
|
autoRenewing: androidResult.autoRenewing,
|
|
699
701
|
betaProduct: androidResult.betaProduct,
|
|
@@ -713,15 +715,15 @@ export const validateReceipt = async (
|
|
|
713
715
|
term: androidResult.term,
|
|
714
716
|
termSku: androidResult.termSku,
|
|
715
717
|
testTransaction: androidResult.testTransaction,
|
|
716
|
-
}
|
|
717
|
-
return result
|
|
718
|
+
};
|
|
719
|
+
return result;
|
|
718
720
|
}
|
|
719
721
|
} catch (error) {
|
|
720
|
-
console.error('[validateReceipt] Failed:', error)
|
|
721
|
-
const errorJson = parseErrorStringToJsonObj(error)
|
|
722
|
-
throw new Error(errorJson.message)
|
|
722
|
+
console.error('[validateReceipt] Failed:', error);
|
|
723
|
+
const errorJson = parseErrorStringToJsonObj(error);
|
|
724
|
+
throw new Error(errorJson.message);
|
|
723
725
|
}
|
|
724
|
-
}
|
|
726
|
+
};
|
|
725
727
|
|
|
726
728
|
/**
|
|
727
729
|
* Sync iOS purchases with App Store (iOS only)
|
|
@@ -730,24 +732,24 @@ export const validateReceipt = async (
|
|
|
730
732
|
*/
|
|
731
733
|
export const syncIOS = async (): Promise<boolean> => {
|
|
732
734
|
if (Platform.OS !== 'ios') {
|
|
733
|
-
throw new Error('syncIOS is only available on iOS')
|
|
735
|
+
throw new Error('syncIOS is only available on iOS');
|
|
734
736
|
}
|
|
735
737
|
|
|
736
738
|
if (!iap) {
|
|
737
739
|
const errorJson = parseErrorStringToJsonObj(
|
|
738
|
-
'RnIap: Service not initialized. Call initConnection() first.'
|
|
739
|
-
)
|
|
740
|
-
throw new Error(errorJson.message)
|
|
740
|
+
'RnIap: Service not initialized. Call initConnection() first.',
|
|
741
|
+
);
|
|
742
|
+
throw new Error(errorJson.message);
|
|
741
743
|
}
|
|
742
744
|
|
|
743
745
|
try {
|
|
744
|
-
return await iap.syncIOS()
|
|
746
|
+
return await iap.syncIOS();
|
|
745
747
|
} catch (error) {
|
|
746
|
-
console.error('[syncIOS] Failed:', error)
|
|
747
|
-
const errorJson = parseErrorStringToJsonObj(error)
|
|
748
|
-
throw new Error(errorJson.message)
|
|
748
|
+
console.error('[syncIOS] Failed:', error);
|
|
749
|
+
const errorJson = parseErrorStringToJsonObj(error);
|
|
750
|
+
throw new Error(errorJson.message);
|
|
749
751
|
}
|
|
750
|
-
}
|
|
752
|
+
};
|
|
751
753
|
|
|
752
754
|
/**
|
|
753
755
|
* Request the promoted product from the App Store (iOS only)
|
|
@@ -756,28 +758,28 @@ export const syncIOS = async (): Promise<boolean> => {
|
|
|
756
758
|
*/
|
|
757
759
|
export const requestPromotedProductIOS = async (): Promise<Product | null> => {
|
|
758
760
|
if (Platform.OS !== 'ios') {
|
|
759
|
-
return null
|
|
761
|
+
return null;
|
|
760
762
|
}
|
|
761
763
|
|
|
762
764
|
if (!iap) {
|
|
763
765
|
const errorJson = parseErrorStringToJsonObj(
|
|
764
|
-
'RnIap: Service not initialized. Call initConnection() first.'
|
|
765
|
-
)
|
|
766
|
-
throw new Error(errorJson.message)
|
|
766
|
+
'RnIap: Service not initialized. Call initConnection() first.',
|
|
767
|
+
);
|
|
768
|
+
throw new Error(errorJson.message);
|
|
767
769
|
}
|
|
768
770
|
|
|
769
771
|
try {
|
|
770
|
-
const nitroProduct = await iap.requestPromotedProductIOS()
|
|
772
|
+
const nitroProduct = await iap.requestPromotedProductIOS();
|
|
771
773
|
if (nitroProduct) {
|
|
772
|
-
return convertNitroProductToProduct(nitroProduct)
|
|
774
|
+
return convertNitroProductToProduct(nitroProduct);
|
|
773
775
|
}
|
|
774
|
-
return null
|
|
776
|
+
return null;
|
|
775
777
|
} catch (error) {
|
|
776
|
-
console.error('[getPromotedProductIOS] Failed:', error)
|
|
777
|
-
const errorJson = parseErrorStringToJsonObj(error)
|
|
778
|
-
throw new Error(errorJson.message)
|
|
778
|
+
console.error('[getPromotedProductIOS] Failed:', error);
|
|
779
|
+
const errorJson = parseErrorStringToJsonObj(error);
|
|
780
|
+
throw new Error(errorJson.message);
|
|
779
781
|
}
|
|
780
|
-
}
|
|
782
|
+
};
|
|
781
783
|
|
|
782
784
|
/**
|
|
783
785
|
* Present the code redemption sheet for offer codes (iOS only)
|
|
@@ -786,24 +788,24 @@ export const requestPromotedProductIOS = async (): Promise<Product | null> => {
|
|
|
786
788
|
*/
|
|
787
789
|
export const presentCodeRedemptionSheetIOS = async (): Promise<boolean> => {
|
|
788
790
|
if (Platform.OS !== 'ios') {
|
|
789
|
-
return false
|
|
791
|
+
return false;
|
|
790
792
|
}
|
|
791
793
|
|
|
792
794
|
if (!iap) {
|
|
793
795
|
const errorJson = parseErrorStringToJsonObj(
|
|
794
|
-
'RnIap: Service not initialized. Call initConnection() first.'
|
|
795
|
-
)
|
|
796
|
-
throw new Error(errorJson.message)
|
|
796
|
+
'RnIap: Service not initialized. Call initConnection() first.',
|
|
797
|
+
);
|
|
798
|
+
throw new Error(errorJson.message);
|
|
797
799
|
}
|
|
798
800
|
|
|
799
801
|
try {
|
|
800
|
-
return await iap.presentCodeRedemptionSheetIOS()
|
|
802
|
+
return await iap.presentCodeRedemptionSheetIOS();
|
|
801
803
|
} catch (error) {
|
|
802
|
-
console.error('[presentCodeRedemptionSheetIOS] Failed:', error)
|
|
803
|
-
const errorJson = parseErrorStringToJsonObj(error)
|
|
804
|
-
throw new Error(errorJson.message)
|
|
804
|
+
console.error('[presentCodeRedemptionSheetIOS] Failed:', error);
|
|
805
|
+
const errorJson = parseErrorStringToJsonObj(error);
|
|
806
|
+
throw new Error(errorJson.message);
|
|
805
807
|
}
|
|
806
|
-
}
|
|
808
|
+
};
|
|
807
809
|
|
|
808
810
|
/**
|
|
809
811
|
* Buy promoted product on iOS
|
|
@@ -812,24 +814,24 @@ export const presentCodeRedemptionSheetIOS = async (): Promise<boolean> => {
|
|
|
812
814
|
*/
|
|
813
815
|
export const buyPromotedProductIOS = async (): Promise<void> => {
|
|
814
816
|
if (Platform.OS !== 'ios') {
|
|
815
|
-
throw new Error('buyPromotedProductIOS is only available on iOS')
|
|
817
|
+
throw new Error('buyPromotedProductIOS is only available on iOS');
|
|
816
818
|
}
|
|
817
819
|
|
|
818
820
|
if (!iap) {
|
|
819
821
|
const errorJson = parseErrorStringToJsonObj(
|
|
820
|
-
'RnIap: Service not initialized. Call initConnection() first.'
|
|
821
|
-
)
|
|
822
|
-
throw new Error(errorJson.message)
|
|
822
|
+
'RnIap: Service not initialized. Call initConnection() first.',
|
|
823
|
+
);
|
|
824
|
+
throw new Error(errorJson.message);
|
|
823
825
|
}
|
|
824
826
|
|
|
825
827
|
try {
|
|
826
|
-
await iap.buyPromotedProductIOS()
|
|
828
|
+
await iap.buyPromotedProductIOS();
|
|
827
829
|
} catch (error) {
|
|
828
|
-
console.error('[buyPromotedProductIOS] Failed:', error)
|
|
829
|
-
const errorJson = parseErrorStringToJsonObj(error)
|
|
830
|
-
throw new Error(errorJson.message)
|
|
830
|
+
console.error('[buyPromotedProductIOS] Failed:', error);
|
|
831
|
+
const errorJson = parseErrorStringToJsonObj(error);
|
|
832
|
+
throw new Error(errorJson.message);
|
|
831
833
|
}
|
|
832
|
-
}
|
|
834
|
+
};
|
|
833
835
|
|
|
834
836
|
/**
|
|
835
837
|
* Clear unfinished transactions on iOS
|
|
@@ -838,24 +840,24 @@ export const buyPromotedProductIOS = async (): Promise<void> => {
|
|
|
838
840
|
*/
|
|
839
841
|
export const clearTransactionIOS = async (): Promise<void> => {
|
|
840
842
|
if (Platform.OS !== 'ios') {
|
|
841
|
-
return
|
|
843
|
+
return;
|
|
842
844
|
}
|
|
843
845
|
|
|
844
846
|
if (!iap) {
|
|
845
847
|
const errorJson = parseErrorStringToJsonObj(
|
|
846
|
-
'RnIap: Service not initialized. Call initConnection() first.'
|
|
847
|
-
)
|
|
848
|
-
throw new Error(errorJson.message)
|
|
848
|
+
'RnIap: Service not initialized. Call initConnection() first.',
|
|
849
|
+
);
|
|
850
|
+
throw new Error(errorJson.message);
|
|
849
851
|
}
|
|
850
852
|
|
|
851
853
|
try {
|
|
852
|
-
await iap.clearTransactionIOS()
|
|
854
|
+
await iap.clearTransactionIOS();
|
|
853
855
|
} catch (error) {
|
|
854
|
-
console.error('[clearTransactionIOS] Failed:', error)
|
|
855
|
-
const errorJson = parseErrorStringToJsonObj(error)
|
|
856
|
-
throw new Error(errorJson.message)
|
|
856
|
+
console.error('[clearTransactionIOS] Failed:', error);
|
|
857
|
+
const errorJson = parseErrorStringToJsonObj(error);
|
|
858
|
+
throw new Error(errorJson.message);
|
|
857
859
|
}
|
|
858
|
-
}
|
|
860
|
+
};
|
|
859
861
|
|
|
860
862
|
/**
|
|
861
863
|
* Begin a refund request for a product on iOS 15+
|
|
@@ -864,27 +866,27 @@ export const clearTransactionIOS = async (): Promise<void> => {
|
|
|
864
866
|
* @platform iOS
|
|
865
867
|
*/
|
|
866
868
|
export const beginRefundRequestIOS = async (
|
|
867
|
-
sku: string
|
|
869
|
+
sku: string,
|
|
868
870
|
): Promise<string | null> => {
|
|
869
871
|
if (Platform.OS !== 'ios') {
|
|
870
|
-
return null
|
|
872
|
+
return null;
|
|
871
873
|
}
|
|
872
874
|
|
|
873
875
|
if (!iap) {
|
|
874
876
|
const errorJson = parseErrorStringToJsonObj(
|
|
875
|
-
'RnIap: Service not initialized. Call initConnection() first.'
|
|
876
|
-
)
|
|
877
|
-
throw new Error(errorJson.message)
|
|
877
|
+
'RnIap: Service not initialized. Call initConnection() first.',
|
|
878
|
+
);
|
|
879
|
+
throw new Error(errorJson.message);
|
|
878
880
|
}
|
|
879
881
|
|
|
880
882
|
try {
|
|
881
|
-
return await iap.beginRefundRequestIOS(sku)
|
|
883
|
+
return await iap.beginRefundRequestIOS(sku);
|
|
882
884
|
} catch (error) {
|
|
883
|
-
console.error('[beginRefundRequestIOS] Failed:', error)
|
|
884
|
-
const errorJson = parseErrorStringToJsonObj(error)
|
|
885
|
-
throw new Error(errorJson.message)
|
|
885
|
+
console.error('[beginRefundRequestIOS] Failed:', error);
|
|
886
|
+
const errorJson = parseErrorStringToJsonObj(error);
|
|
887
|
+
throw new Error(errorJson.message);
|
|
886
888
|
}
|
|
887
|
-
}
|
|
889
|
+
};
|
|
888
890
|
|
|
889
891
|
/**
|
|
890
892
|
* Get subscription status for a product (iOS only)
|
|
@@ -894,31 +896,31 @@ export const beginRefundRequestIOS = async (
|
|
|
894
896
|
* @platform iOS
|
|
895
897
|
*/
|
|
896
898
|
export const subscriptionStatusIOS = async (
|
|
897
|
-
sku: string
|
|
899
|
+
sku: string,
|
|
898
900
|
): Promise<SubscriptionStatusIOS[]> => {
|
|
899
901
|
if (Platform.OS !== 'ios') {
|
|
900
|
-
throw new Error('subscriptionStatusIOS is only available on iOS')
|
|
902
|
+
throw new Error('subscriptionStatusIOS is only available on iOS');
|
|
901
903
|
}
|
|
902
904
|
|
|
903
905
|
if (!iap) {
|
|
904
906
|
const errorJson = parseErrorStringToJsonObj(
|
|
905
|
-
'RnIap: Service not initialized. Call initConnection() first.'
|
|
906
|
-
)
|
|
907
|
-
throw new Error(errorJson.message)
|
|
907
|
+
'RnIap: Service not initialized. Call initConnection() first.',
|
|
908
|
+
);
|
|
909
|
+
throw new Error(errorJson.message);
|
|
908
910
|
}
|
|
909
911
|
|
|
910
912
|
try {
|
|
911
|
-
const statuses = await iap.subscriptionStatusIOS(sku)
|
|
912
|
-
if (!statuses || !Array.isArray(statuses)) return []
|
|
913
|
+
const statuses = await iap.subscriptionStatusIOS(sku);
|
|
914
|
+
if (!statuses || !Array.isArray(statuses)) return [];
|
|
913
915
|
return statuses.map((s) =>
|
|
914
|
-
convertNitroSubscriptionStatusToSubscriptionStatusIOS(s as any)
|
|
915
|
-
)
|
|
916
|
+
convertNitroSubscriptionStatusToSubscriptionStatusIOS(s as any),
|
|
917
|
+
);
|
|
916
918
|
} catch (error) {
|
|
917
|
-
console.error('[subscriptionStatusIOS] Failed:', error)
|
|
918
|
-
const errorJson = parseErrorStringToJsonObj(error)
|
|
919
|
-
throw new Error(errorJson.message)
|
|
919
|
+
console.error('[subscriptionStatusIOS] Failed:', error);
|
|
920
|
+
const errorJson = parseErrorStringToJsonObj(error);
|
|
921
|
+
throw new Error(errorJson.message);
|
|
920
922
|
}
|
|
921
|
-
}
|
|
923
|
+
};
|
|
922
924
|
|
|
923
925
|
/**
|
|
924
926
|
* Get current entitlement for a product (iOS only)
|
|
@@ -927,31 +929,31 @@ export const subscriptionStatusIOS = async (
|
|
|
927
929
|
* @platform iOS
|
|
928
930
|
*/
|
|
929
931
|
export const currentEntitlementIOS = async (
|
|
930
|
-
sku: string
|
|
932
|
+
sku: string,
|
|
931
933
|
): Promise<Purchase | null> => {
|
|
932
934
|
if (Platform.OS !== 'ios') {
|
|
933
|
-
return null
|
|
935
|
+
return null;
|
|
934
936
|
}
|
|
935
937
|
|
|
936
938
|
if (!iap) {
|
|
937
939
|
const errorJson = parseErrorStringToJsonObj(
|
|
938
|
-
'RnIap: Service not initialized. Call initConnection() first.'
|
|
939
|
-
)
|
|
940
|
-
throw new Error(errorJson.message)
|
|
940
|
+
'RnIap: Service not initialized. Call initConnection() first.',
|
|
941
|
+
);
|
|
942
|
+
throw new Error(errorJson.message);
|
|
941
943
|
}
|
|
942
944
|
|
|
943
945
|
try {
|
|
944
|
-
const nitroPurchase = await iap.currentEntitlementIOS(sku)
|
|
946
|
+
const nitroPurchase = await iap.currentEntitlementIOS(sku);
|
|
945
947
|
if (nitroPurchase) {
|
|
946
|
-
return convertNitroPurchaseToPurchase(nitroPurchase)
|
|
948
|
+
return convertNitroPurchaseToPurchase(nitroPurchase);
|
|
947
949
|
}
|
|
948
|
-
return null
|
|
950
|
+
return null;
|
|
949
951
|
} catch (error) {
|
|
950
|
-
console.error('[currentEntitlementIOS] Failed:', error)
|
|
951
|
-
const errorJson = parseErrorStringToJsonObj(error)
|
|
952
|
-
throw new Error(errorJson.message)
|
|
952
|
+
console.error('[currentEntitlementIOS] Failed:', error);
|
|
953
|
+
const errorJson = parseErrorStringToJsonObj(error);
|
|
954
|
+
throw new Error(errorJson.message);
|
|
953
955
|
}
|
|
954
|
-
}
|
|
956
|
+
};
|
|
955
957
|
|
|
956
958
|
/**
|
|
957
959
|
* Get latest transaction for a product (iOS only)
|
|
@@ -960,31 +962,31 @@ export const currentEntitlementIOS = async (
|
|
|
960
962
|
* @platform iOS
|
|
961
963
|
*/
|
|
962
964
|
export const latestTransactionIOS = async (
|
|
963
|
-
sku: string
|
|
965
|
+
sku: string,
|
|
964
966
|
): Promise<Purchase | null> => {
|
|
965
967
|
if (Platform.OS !== 'ios') {
|
|
966
|
-
return null
|
|
968
|
+
return null;
|
|
967
969
|
}
|
|
968
970
|
|
|
969
971
|
if (!iap) {
|
|
970
972
|
const errorJson = parseErrorStringToJsonObj(
|
|
971
|
-
'RnIap: Service not initialized. Call initConnection() first.'
|
|
972
|
-
)
|
|
973
|
-
throw new Error(errorJson.message)
|
|
973
|
+
'RnIap: Service not initialized. Call initConnection() first.',
|
|
974
|
+
);
|
|
975
|
+
throw new Error(errorJson.message);
|
|
974
976
|
}
|
|
975
977
|
|
|
976
978
|
try {
|
|
977
|
-
const nitroPurchase = await iap.latestTransactionIOS(sku)
|
|
979
|
+
const nitroPurchase = await iap.latestTransactionIOS(sku);
|
|
978
980
|
if (nitroPurchase) {
|
|
979
|
-
return convertNitroPurchaseToPurchase(nitroPurchase)
|
|
981
|
+
return convertNitroPurchaseToPurchase(nitroPurchase);
|
|
980
982
|
}
|
|
981
|
-
return null
|
|
983
|
+
return null;
|
|
982
984
|
} catch (error) {
|
|
983
|
-
console.error('[latestTransactionIOS] Failed:', error)
|
|
984
|
-
const errorJson = parseErrorStringToJsonObj(error)
|
|
985
|
-
throw new Error(errorJson.message)
|
|
985
|
+
console.error('[latestTransactionIOS] Failed:', error);
|
|
986
|
+
const errorJson = parseErrorStringToJsonObj(error);
|
|
987
|
+
throw new Error(errorJson.message);
|
|
986
988
|
}
|
|
987
|
-
}
|
|
989
|
+
};
|
|
988
990
|
|
|
989
991
|
/**
|
|
990
992
|
* Get pending transactions (iOS only)
|
|
@@ -993,25 +995,25 @@ export const latestTransactionIOS = async (
|
|
|
993
995
|
*/
|
|
994
996
|
export const getPendingTransactionsIOS = async (): Promise<Purchase[]> => {
|
|
995
997
|
if (Platform.OS !== 'ios') {
|
|
996
|
-
return []
|
|
998
|
+
return [];
|
|
997
999
|
}
|
|
998
1000
|
|
|
999
1001
|
if (!iap) {
|
|
1000
1002
|
const errorJson = parseErrorStringToJsonObj(
|
|
1001
|
-
'RnIap: Service not initialized. Call initConnection() first.'
|
|
1002
|
-
)
|
|
1003
|
-
throw new Error(errorJson.message)
|
|
1003
|
+
'RnIap: Service not initialized. Call initConnection() first.',
|
|
1004
|
+
);
|
|
1005
|
+
throw new Error(errorJson.message);
|
|
1004
1006
|
}
|
|
1005
1007
|
|
|
1006
1008
|
try {
|
|
1007
|
-
const nitroPurchases = await iap.getPendingTransactionsIOS()
|
|
1008
|
-
return nitroPurchases.map(convertNitroPurchaseToPurchase)
|
|
1009
|
+
const nitroPurchases = await iap.getPendingTransactionsIOS();
|
|
1010
|
+
return nitroPurchases.map(convertNitroPurchaseToPurchase);
|
|
1009
1011
|
} catch (error) {
|
|
1010
|
-
console.error('[getPendingTransactionsIOS] Failed:', error)
|
|
1011
|
-
const errorJson = parseErrorStringToJsonObj(error)
|
|
1012
|
-
throw new Error(errorJson.message)
|
|
1012
|
+
console.error('[getPendingTransactionsIOS] Failed:', error);
|
|
1013
|
+
const errorJson = parseErrorStringToJsonObj(error);
|
|
1014
|
+
throw new Error(errorJson.message);
|
|
1013
1015
|
}
|
|
1014
|
-
}
|
|
1016
|
+
};
|
|
1015
1017
|
|
|
1016
1018
|
/**
|
|
1017
1019
|
* Show manage subscriptions screen (iOS only)
|
|
@@ -1020,25 +1022,25 @@ export const getPendingTransactionsIOS = async (): Promise<Purchase[]> => {
|
|
|
1020
1022
|
*/
|
|
1021
1023
|
export const showManageSubscriptionsIOS = async (): Promise<Purchase[]> => {
|
|
1022
1024
|
if (Platform.OS !== 'ios') {
|
|
1023
|
-
return []
|
|
1025
|
+
return [];
|
|
1024
1026
|
}
|
|
1025
1027
|
|
|
1026
1028
|
if (!iap) {
|
|
1027
1029
|
const errorJson = parseErrorStringToJsonObj(
|
|
1028
|
-
'RnIap: Service not initialized. Call initConnection() first.'
|
|
1029
|
-
)
|
|
1030
|
-
throw new Error(errorJson.message)
|
|
1030
|
+
'RnIap: Service not initialized. Call initConnection() first.',
|
|
1031
|
+
);
|
|
1032
|
+
throw new Error(errorJson.message);
|
|
1031
1033
|
}
|
|
1032
1034
|
|
|
1033
1035
|
try {
|
|
1034
|
-
const nitroPurchases = await iap.showManageSubscriptionsIOS()
|
|
1035
|
-
return nitroPurchases.map(convertNitroPurchaseToPurchase)
|
|
1036
|
+
const nitroPurchases = await iap.showManageSubscriptionsIOS();
|
|
1037
|
+
return nitroPurchases.map(convertNitroPurchaseToPurchase);
|
|
1036
1038
|
} catch (error) {
|
|
1037
|
-
console.error('[showManageSubscriptionsIOS] Failed:', error)
|
|
1038
|
-
const errorJson = parseErrorStringToJsonObj(error)
|
|
1039
|
-
throw new Error(errorJson.message)
|
|
1039
|
+
console.error('[showManageSubscriptionsIOS] Failed:', error);
|
|
1040
|
+
const errorJson = parseErrorStringToJsonObj(error);
|
|
1041
|
+
throw new Error(errorJson.message);
|
|
1040
1042
|
}
|
|
1041
|
-
}
|
|
1043
|
+
};
|
|
1042
1044
|
|
|
1043
1045
|
/**
|
|
1044
1046
|
* Check if user is eligible for intro offer (iOS only)
|
|
@@ -1047,27 +1049,27 @@ export const showManageSubscriptionsIOS = async (): Promise<Purchase[]> => {
|
|
|
1047
1049
|
* @platform iOS
|
|
1048
1050
|
*/
|
|
1049
1051
|
export const isEligibleForIntroOfferIOS = async (
|
|
1050
|
-
groupID: string
|
|
1052
|
+
groupID: string,
|
|
1051
1053
|
): Promise<boolean> => {
|
|
1052
1054
|
if (Platform.OS !== 'ios') {
|
|
1053
|
-
return false
|
|
1055
|
+
return false;
|
|
1054
1056
|
}
|
|
1055
1057
|
|
|
1056
1058
|
if (!iap) {
|
|
1057
1059
|
const errorJson = parseErrorStringToJsonObj(
|
|
1058
|
-
'RnIap: Service not initialized. Call initConnection() first.'
|
|
1059
|
-
)
|
|
1060
|
-
throw new Error(errorJson.message)
|
|
1060
|
+
'RnIap: Service not initialized. Call initConnection() first.',
|
|
1061
|
+
);
|
|
1062
|
+
throw new Error(errorJson.message);
|
|
1061
1063
|
}
|
|
1062
1064
|
|
|
1063
1065
|
try {
|
|
1064
|
-
return await iap.isEligibleForIntroOfferIOS(groupID)
|
|
1066
|
+
return await iap.isEligibleForIntroOfferIOS(groupID);
|
|
1065
1067
|
} catch (error) {
|
|
1066
|
-
console.error('[isEligibleForIntroOfferIOS] Failed:', error)
|
|
1067
|
-
const errorJson = parseErrorStringToJsonObj(error)
|
|
1068
|
-
throw new Error(errorJson.message)
|
|
1068
|
+
console.error('[isEligibleForIntroOfferIOS] Failed:', error);
|
|
1069
|
+
const errorJson = parseErrorStringToJsonObj(error);
|
|
1070
|
+
throw new Error(errorJson.message);
|
|
1069
1071
|
}
|
|
1070
|
-
}
|
|
1072
|
+
};
|
|
1071
1073
|
|
|
1072
1074
|
/**
|
|
1073
1075
|
* Get receipt data (iOS only)
|
|
@@ -1076,24 +1078,24 @@ export const isEligibleForIntroOfferIOS = async (
|
|
|
1076
1078
|
*/
|
|
1077
1079
|
export const getReceiptDataIOS = async (): Promise<string> => {
|
|
1078
1080
|
if (Platform.OS !== 'ios') {
|
|
1079
|
-
throw new Error('getReceiptDataIOS is only available on iOS')
|
|
1081
|
+
throw new Error('getReceiptDataIOS is only available on iOS');
|
|
1080
1082
|
}
|
|
1081
1083
|
|
|
1082
1084
|
if (!iap) {
|
|
1083
1085
|
const errorJson = parseErrorStringToJsonObj(
|
|
1084
|
-
'RnIap: Service not initialized. Call initConnection() first.'
|
|
1085
|
-
)
|
|
1086
|
-
throw new Error(errorJson.message)
|
|
1086
|
+
'RnIap: Service not initialized. Call initConnection() first.',
|
|
1087
|
+
);
|
|
1088
|
+
throw new Error(errorJson.message);
|
|
1087
1089
|
}
|
|
1088
1090
|
|
|
1089
1091
|
try {
|
|
1090
|
-
return await iap.getReceiptDataIOS()
|
|
1092
|
+
return await iap.getReceiptDataIOS();
|
|
1091
1093
|
} catch (error) {
|
|
1092
|
-
console.error('[getReceiptDataIOS] Failed:', error)
|
|
1093
|
-
const errorJson = parseErrorStringToJsonObj(error)
|
|
1094
|
-
throw new Error(errorJson.message)
|
|
1094
|
+
console.error('[getReceiptDataIOS] Failed:', error);
|
|
1095
|
+
const errorJson = parseErrorStringToJsonObj(error);
|
|
1096
|
+
throw new Error(errorJson.message);
|
|
1095
1097
|
}
|
|
1096
|
-
}
|
|
1098
|
+
};
|
|
1097
1099
|
|
|
1098
1100
|
/**
|
|
1099
1101
|
* Check if transaction is verified (iOS only)
|
|
@@ -1102,27 +1104,27 @@ export const getReceiptDataIOS = async (): Promise<string> => {
|
|
|
1102
1104
|
* @platform iOS
|
|
1103
1105
|
*/
|
|
1104
1106
|
export const isTransactionVerifiedIOS = async (
|
|
1105
|
-
sku: string
|
|
1107
|
+
sku: string,
|
|
1106
1108
|
): Promise<boolean> => {
|
|
1107
1109
|
if (Platform.OS !== 'ios') {
|
|
1108
|
-
return false
|
|
1110
|
+
return false;
|
|
1109
1111
|
}
|
|
1110
1112
|
|
|
1111
1113
|
if (!iap) {
|
|
1112
1114
|
const errorJson = parseErrorStringToJsonObj(
|
|
1113
|
-
'RnIap: Service not initialized. Call initConnection() first.'
|
|
1114
|
-
)
|
|
1115
|
-
throw new Error(errorJson.message)
|
|
1115
|
+
'RnIap: Service not initialized. Call initConnection() first.',
|
|
1116
|
+
);
|
|
1117
|
+
throw new Error(errorJson.message);
|
|
1116
1118
|
}
|
|
1117
1119
|
|
|
1118
1120
|
try {
|
|
1119
|
-
return await iap.isTransactionVerifiedIOS(sku)
|
|
1121
|
+
return await iap.isTransactionVerifiedIOS(sku);
|
|
1120
1122
|
} catch (error) {
|
|
1121
|
-
console.error('[isTransactionVerifiedIOS] Failed:', error)
|
|
1122
|
-
const errorJson = parseErrorStringToJsonObj(error)
|
|
1123
|
-
throw new Error(errorJson.message)
|
|
1123
|
+
console.error('[isTransactionVerifiedIOS] Failed:', error);
|
|
1124
|
+
const errorJson = parseErrorStringToJsonObj(error);
|
|
1125
|
+
throw new Error(errorJson.message);
|
|
1124
1126
|
}
|
|
1125
|
-
}
|
|
1127
|
+
};
|
|
1126
1128
|
|
|
1127
1129
|
/**
|
|
1128
1130
|
* Get transaction JWS representation (iOS only)
|
|
@@ -1131,27 +1133,27 @@ export const isTransactionVerifiedIOS = async (
|
|
|
1131
1133
|
* @platform iOS
|
|
1132
1134
|
*/
|
|
1133
1135
|
export const getTransactionJwsIOS = async (
|
|
1134
|
-
sku: string
|
|
1136
|
+
sku: string,
|
|
1135
1137
|
): Promise<string | null> => {
|
|
1136
1138
|
if (Platform.OS !== 'ios') {
|
|
1137
|
-
return null
|
|
1139
|
+
return null;
|
|
1138
1140
|
}
|
|
1139
1141
|
|
|
1140
1142
|
if (!iap) {
|
|
1141
1143
|
const errorJson = parseErrorStringToJsonObj(
|
|
1142
|
-
'RnIap: Service not initialized. Call initConnection() first.'
|
|
1143
|
-
)
|
|
1144
|
-
throw new Error(errorJson.message)
|
|
1144
|
+
'RnIap: Service not initialized. Call initConnection() first.',
|
|
1145
|
+
);
|
|
1146
|
+
throw new Error(errorJson.message);
|
|
1145
1147
|
}
|
|
1146
1148
|
|
|
1147
1149
|
try {
|
|
1148
|
-
return await iap.getTransactionJwsIOS(sku)
|
|
1150
|
+
return await iap.getTransactionJwsIOS(sku);
|
|
1149
1151
|
} catch (error) {
|
|
1150
|
-
console.error('[getTransactionJwsIOS] Failed:', error)
|
|
1151
|
-
const errorJson = parseErrorStringToJsonObj(error)
|
|
1152
|
-
throw new Error(errorJson.message)
|
|
1152
|
+
console.error('[getTransactionJwsIOS] Failed:', error);
|
|
1153
|
+
const errorJson = parseErrorStringToJsonObj(error);
|
|
1154
|
+
throw new Error(errorJson.message);
|
|
1153
1155
|
}
|
|
1154
|
-
}
|
|
1156
|
+
};
|
|
1155
1157
|
|
|
1156
1158
|
/**
|
|
1157
1159
|
* Get the storefront identifier for the user's App Store account (iOS only)
|
|
@@ -1166,18 +1168,18 @@ export const getTransactionJwsIOS = async (
|
|
|
1166
1168
|
*/
|
|
1167
1169
|
export const getStorefrontIOS = async (): Promise<string> => {
|
|
1168
1170
|
if (Platform.OS !== 'ios') {
|
|
1169
|
-
throw new Error('getStorefrontIOS is only available on iOS')
|
|
1171
|
+
throw new Error('getStorefrontIOS is only available on iOS');
|
|
1170
1172
|
}
|
|
1171
1173
|
|
|
1172
1174
|
try {
|
|
1173
1175
|
// Call the native method to get storefront
|
|
1174
|
-
const storefront = await iap.getStorefrontIOS()
|
|
1175
|
-
return storefront
|
|
1176
|
+
const storefront = await iap.getStorefrontIOS();
|
|
1177
|
+
return storefront;
|
|
1176
1178
|
} catch (error) {
|
|
1177
|
-
console.error('Failed to get storefront:', error)
|
|
1178
|
-
throw error
|
|
1179
|
+
console.error('Failed to get storefront:', error);
|
|
1180
|
+
throw error;
|
|
1179
1181
|
}
|
|
1180
|
-
}
|
|
1182
|
+
};
|
|
1181
1183
|
|
|
1182
1184
|
/**
|
|
1183
1185
|
* iOS only - Gets the original app transaction ID if the app was purchased from the App Store
|
|
@@ -1200,24 +1202,24 @@ export const getStorefrontIOS = async (): Promise<string> => {
|
|
|
1200
1202
|
*/
|
|
1201
1203
|
export const getAppTransactionIOS = async (): Promise<string | null> => {
|
|
1202
1204
|
if (Platform.OS !== 'ios') {
|
|
1203
|
-
throw new Error('getAppTransactionIOS is only available on iOS')
|
|
1205
|
+
throw new Error('getAppTransactionIOS is only available on iOS');
|
|
1204
1206
|
}
|
|
1205
1207
|
|
|
1206
1208
|
try {
|
|
1207
1209
|
// Call the native method to get app transaction
|
|
1208
|
-
const appTransaction = await iap.getAppTransactionIOS()
|
|
1209
|
-
return appTransaction
|
|
1210
|
+
const appTransaction = await iap.getAppTransactionIOS();
|
|
1211
|
+
return appTransaction;
|
|
1210
1212
|
} catch (error) {
|
|
1211
|
-
console.error('Failed to get app transaction:', error)
|
|
1212
|
-
throw error
|
|
1213
|
+
console.error('Failed to get app transaction:', error);
|
|
1214
|
+
throw error;
|
|
1213
1215
|
}
|
|
1214
|
-
}
|
|
1216
|
+
};
|
|
1215
1217
|
|
|
1216
1218
|
// Export subscription helpers
|
|
1217
1219
|
export {
|
|
1218
1220
|
getActiveSubscriptions,
|
|
1219
1221
|
hasActiveSubscriptions,
|
|
1220
|
-
} from './helpers/subscription'
|
|
1222
|
+
} from './helpers/subscription';
|
|
1221
1223
|
|
|
1222
1224
|
// Type conversion utilities
|
|
1223
1225
|
export {
|
|
@@ -1227,15 +1229,15 @@ export {
|
|
|
1227
1229
|
validateNitroProduct,
|
|
1228
1230
|
validateNitroPurchase,
|
|
1229
1231
|
checkTypeSynchronization,
|
|
1230
|
-
} from './utils/type-bridge'
|
|
1232
|
+
} from './utils/type-bridge';
|
|
1231
1233
|
|
|
1232
1234
|
// Deprecated exports for backward compatibility
|
|
1233
1235
|
/**
|
|
1234
1236
|
* @deprecated Use acknowledgePurchaseAndroid instead
|
|
1235
1237
|
*/
|
|
1236
|
-
export const acknowledgePurchase = acknowledgePurchaseAndroid
|
|
1238
|
+
export const acknowledgePurchase = acknowledgePurchaseAndroid;
|
|
1237
1239
|
|
|
1238
1240
|
/**
|
|
1239
1241
|
* @deprecated Use consumePurchaseAndroid instead
|
|
1240
1242
|
*/
|
|
1241
|
-
export const consumePurchase = consumePurchaseAndroid
|
|
1243
|
+
export const consumePurchase = consumePurchaseAndroid;
|