react-native-iap 14.3.5-rc.1 → 14.3.5

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (79) hide show
  1. package/NitroIap.podspec +1 -1
  2. package/README.md +1 -1
  3. package/android/CMakeLists.txt +4 -0
  4. package/android/build.gradle +2 -2
  5. package/android/src/main/cpp/cpp-adapter.cpp +8 -0
  6. package/android/src/main/java/com/margelo/nitro/iap/HybridRnIap.kt +93 -51
  7. package/ios/HybridRnIap.swift +38 -30
  8. package/lib/module/hooks/useIAP.js +3 -5
  9. package/lib/module/hooks/useIAP.js.map +1 -1
  10. package/lib/module/index.js +54 -55
  11. package/lib/module/index.js.map +1 -1
  12. package/lib/module/types.js +1 -1
  13. package/lib/module/utils/type-bridge.js.map +1 -1
  14. package/lib/typescript/src/hooks/useIAP.d.ts +4 -4
  15. package/lib/typescript/src/hooks/useIAP.d.ts.map +1 -1
  16. package/lib/typescript/src/index.d.ts +8 -7
  17. package/lib/typescript/src/index.d.ts.map +1 -1
  18. package/lib/typescript/src/specs/RnIap.nitro.d.ts +2 -1
  19. package/lib/typescript/src/specs/RnIap.nitro.d.ts.map +1 -1
  20. package/lib/typescript/src/types.d.ts +141 -146
  21. package/lib/typescript/src/types.d.ts.map +1 -1
  22. package/lib/typescript/src/utils/type-bridge.d.ts.map +1 -1
  23. package/nitrogen/generated/android/NitroIap+autolinking.cmake +9 -4
  24. package/nitrogen/generated/android/c++/JHybridRnIapSpec.cpp +32 -5
  25. package/nitrogen/generated/android/c++/JHybridRnIapSpec.hpp +1 -1
  26. package/nitrogen/generated/android/c++/JIapPlatform.hpp +59 -0
  27. package/nitrogen/generated/android/c++/JPurchase.cpp +26 -0
  28. package/nitrogen/generated/android/c++/JPurchase.hpp +80 -0
  29. package/nitrogen/generated/android/c++/JPurchaseAndroid.hpp +140 -0
  30. package/nitrogen/generated/android/c++/JPurchaseIOS.hpp +194 -0
  31. package/nitrogen/generated/android/c++/JPurchaseOfferIOS.hpp +61 -0
  32. package/nitrogen/generated/android/c++/JPurchaseState.hpp +71 -0
  33. package/nitrogen/generated/android/c++/JRequestPurchaseResult.hpp +89 -0
  34. package/nitrogen/generated/android/c++/JVariant_PurchaseAndroid_PurchaseIOS.cpp +26 -0
  35. package/nitrogen/generated/android/c++/JVariant_PurchaseAndroid_PurchaseIOS.hpp +80 -0
  36. package/nitrogen/generated/android/kotlin/com/margelo/nitro/iap/HybridRnIapSpec.kt +1 -1
  37. package/nitrogen/generated/android/kotlin/com/margelo/nitro/iap/IapPlatform.kt +21 -0
  38. package/nitrogen/generated/android/kotlin/com/margelo/nitro/iap/Purchase.kt +42 -0
  39. package/nitrogen/generated/android/kotlin/com/margelo/nitro/iap/PurchaseAndroid.kt +77 -0
  40. package/nitrogen/generated/android/kotlin/com/margelo/nitro/iap/PurchaseIOS.kt +116 -0
  41. package/nitrogen/generated/android/kotlin/com/margelo/nitro/iap/PurchaseOfferIOS.kt +35 -0
  42. package/nitrogen/generated/android/kotlin/com/margelo/nitro/iap/PurchaseState.kt +25 -0
  43. package/nitrogen/generated/android/kotlin/com/margelo/nitro/iap/RequestPurchaseResult.kt +32 -0
  44. package/nitrogen/generated/android/kotlin/com/margelo/nitro/iap/Variant_PurchaseAndroid_PurchaseIOS.kt +42 -0
  45. package/nitrogen/generated/ios/NitroIap-Swift-Cxx-Bridge.cpp +13 -5
  46. package/nitrogen/generated/ios/NitroIap-Swift-Cxx-Bridge.hpp +186 -25
  47. package/nitrogen/generated/ios/NitroIap-Swift-Cxx-Umbrella.hpp +18 -0
  48. package/nitrogen/generated/ios/c++/HybridRnIapSpecSwift.hpp +20 -2
  49. package/nitrogen/generated/ios/swift/Func_void_RequestPurchaseResult.swift +47 -0
  50. package/nitrogen/generated/ios/swift/HybridRnIapSpec.swift +1 -1
  51. package/nitrogen/generated/ios/swift/HybridRnIapSpec_cxx.swift +7 -7
  52. package/nitrogen/generated/ios/swift/IapPlatform.swift +40 -0
  53. package/nitrogen/generated/ios/swift/Purchase.swift +18 -0
  54. package/nitrogen/generated/ios/swift/PurchaseAndroid.swift +399 -0
  55. package/nitrogen/generated/ios/swift/PurchaseIOS.swift +768 -0
  56. package/nitrogen/generated/ios/swift/PurchaseOfferIOS.swift +57 -0
  57. package/nitrogen/generated/ios/swift/PurchaseState.swift +56 -0
  58. package/nitrogen/generated/ios/swift/RequestPurchaseResult.swift +148 -0
  59. package/nitrogen/generated/ios/swift/Variant_PurchaseAndroid_PurchaseIOS.swift +18 -0
  60. package/nitrogen/generated/shared/c++/HybridRnIapSpec.hpp +4 -1
  61. package/nitrogen/generated/shared/c++/IapPlatform.hpp +76 -0
  62. package/nitrogen/generated/shared/c++/PurchaseAndroid.hpp +138 -0
  63. package/nitrogen/generated/shared/c++/PurchaseIOS.hpp +193 -0
  64. package/nitrogen/generated/shared/c++/PurchaseOfferIOS.hpp +75 -0
  65. package/nitrogen/generated/shared/c++/PurchaseState.hpp +92 -0
  66. package/nitrogen/generated/shared/c++/RequestPurchaseResult.hpp +78 -0
  67. package/package.json +5 -4
  68. package/plugin/build/withIAP.js +1 -1
  69. package/plugin/src/withIAP.ts +1 -1
  70. package/plugin/tsconfig.tsbuildinfo +1 -1
  71. package/src/hooks/useIAP.ts +13 -11
  72. package/src/index.ts +73 -77
  73. package/src/specs/RnIap.nitro.ts +4 -1
  74. package/src/types.ts +168 -178
  75. package/src/utils/type-bridge.ts +3 -1
  76. package/lib/index.d.ts +0 -8
  77. package/lib/index.js +0 -36
  78. package/lib/specs/RnIap.nitro.d.ts +0 -7
  79. package/lib/specs/RnIap.nitro.js +0 -1
package/src/index.ts CHANGED
@@ -12,14 +12,17 @@ import type {
12
12
  NitroReceiptValidationResultIOS,
13
13
  NitroReceiptValidationResultAndroid,
14
14
  } from './specs/RnIap.nitro';
15
- import type {ProductQueryType} from './types';
15
+ import type {
16
+ ProductQueryType,
17
+ RequestPurchaseProps,
18
+ RequestPurchaseResult,
19
+ } from './types';
16
20
  import type {
17
21
  Product,
18
22
  ProductRequest,
19
23
  Purchase,
20
24
  PurchaseAndroid,
21
25
  PurchaseOptions,
22
- PurchaseParams,
23
26
  PurchaseError,
24
27
  ReceiptValidationResultAndroid,
25
28
  ReceiptValidationResultIOS,
@@ -27,6 +30,7 @@ import type {
27
30
  RequestPurchaseIosProps,
28
31
  RequestPurchasePropsByPlatforms,
29
32
  RequestSubscriptionAndroidProps,
33
+ RequestSubscriptionIosProps,
30
34
  RequestSubscriptionPropsByPlatforms,
31
35
  SubscriptionStatusIOS,
32
36
  } from './types';
@@ -50,38 +54,56 @@ export type {
50
54
  export * from './types';
51
55
  export * from './utils/error';
52
56
 
53
- // Internal constants/helpers for bridging legacy Nitro expectations
54
- const NITRO_PRODUCT_TYPE_INAPP = 'inapp';
55
- const NITRO_PRODUCT_TYPE_SUBS = 'subs';
56
- const PRODUCT_QUERY_TYPE_ALL: ProductQueryType = 'all';
57
- const PRODUCT_QUERY_TYPE_IN_APP: ProductQueryType = 'in-app';
58
- const PRODUCT_QUERY_TYPE_SUBS: ProductQueryType = 'subs';
57
+ export type ProductTypeInput = 'inapp' | 'in-app' | 'subs';
58
+
59
+ const LEGACY_INAPP_WARNING =
60
+ "[react-native-iap] `type: 'inapp'` is deprecated and will be removed in v14.4.0. Use 'in-app' instead.";
59
61
 
60
62
  function toNitroProductType(
61
- type?: ProductQueryType | null,
62
- ): typeof NITRO_PRODUCT_TYPE_INAPP | typeof NITRO_PRODUCT_TYPE_SUBS {
63
- return type === PRODUCT_QUERY_TYPE_SUBS
64
- ? NITRO_PRODUCT_TYPE_SUBS
65
- : NITRO_PRODUCT_TYPE_INAPP;
63
+ type?: ProductTypeInput | ProductQueryType | null,
64
+ ): 'inapp' | 'subs' {
65
+ if (type === 'subs') {
66
+ return 'subs';
67
+ }
68
+ if (type === 'inapp') {
69
+ console.warn(LEGACY_INAPP_WARNING);
70
+ return 'inapp';
71
+ }
72
+ if (type === 'all') {
73
+ return 'inapp';
74
+ }
75
+ return 'inapp';
66
76
  }
67
77
 
68
78
  function isSubscriptionQuery(type?: ProductQueryType | null): boolean {
69
- return type === PRODUCT_QUERY_TYPE_SUBS;
79
+ return type === 'subs';
70
80
  }
71
81
 
72
82
  function normalizeProductQueryType(
73
83
  type?: ProductQueryType | string | null,
74
84
  ): ProductQueryType {
75
- if (type === PRODUCT_QUERY_TYPE_ALL || type === 'all') {
76
- return PRODUCT_QUERY_TYPE_ALL;
85
+ if (type === 'all' || type === 'subs' || type === 'in-app') {
86
+ return type;
77
87
  }
78
- if (type === PRODUCT_QUERY_TYPE_SUBS || type === 'subs') {
79
- return PRODUCT_QUERY_TYPE_SUBS;
80
- }
81
- if (type === PRODUCT_QUERY_TYPE_IN_APP || type === 'inapp') {
82
- return PRODUCT_QUERY_TYPE_IN_APP;
88
+
89
+ if (typeof type === 'string') {
90
+ const normalized = type.trim().toLowerCase().replace(/_/g, '-');
91
+
92
+ if (normalized === 'all') {
93
+ return 'all';
94
+ }
95
+ if (normalized === 'subs') {
96
+ return 'subs';
97
+ }
98
+ if (normalized === 'inapp') {
99
+ console.warn(LEGACY_INAPP_WARNING);
100
+ return 'in-app';
101
+ }
102
+ if (normalized === 'in-app') {
103
+ return 'in-app';
104
+ }
83
105
  }
84
- return PRODUCT_QUERY_TYPE_IN_APP;
106
+ return 'in-app';
85
107
  }
86
108
 
87
109
  export interface EventSubscription {
@@ -177,7 +199,7 @@ export const endConnection = async (): Promise<boolean> => {
177
199
  * Fetch products from the store
178
200
  * @param params - Product request configuration
179
201
  * @param params.skus - Array of product SKUs to fetch
180
- * @param params.type - Optional filter: 'inapp' (default) for products, 'subs' for subscriptions, or 'all' for both.
202
+ * @param params.type - Optional filter: 'in-app' (default) for products, 'subs' for subscriptions, or 'all' for both.
181
203
  * @returns Promise<Product[]> - Array of products from the store
182
204
  *
183
205
  * @example
@@ -191,7 +213,7 @@ export const endConnection = async (): Promise<boolean> => {
191
213
  */
192
214
  export const fetchProducts = async ({
193
215
  skus,
194
- type = PRODUCT_QUERY_TYPE_IN_APP,
216
+ type = 'in-app',
195
217
  }: ProductRequest): Promise<Product[]> => {
196
218
  try {
197
219
  if (!skus || skus.length === 0) {
@@ -200,10 +222,10 @@ export const fetchProducts = async ({
200
222
 
201
223
  const normalizedType = normalizeProductQueryType(type);
202
224
 
203
- if (normalizedType === PRODUCT_QUERY_TYPE_ALL) {
225
+ if (normalizedType === 'all') {
204
226
  const [inappNitro, subsNitro] = await Promise.all([
205
- IAP.instance.fetchProducts(skus, NITRO_PRODUCT_TYPE_INAPP),
206
- IAP.instance.fetchProducts(skus, NITRO_PRODUCT_TYPE_SUBS),
227
+ IAP.instance.fetchProducts(skus, 'inapp'),
228
+ IAP.instance.fetchProducts(skus, 'subs'),
207
229
  ]);
208
230
  const allNitro = [...inappNitro, ...subsNitro];
209
231
  const validAll = allNitro.filter(validateNitroProduct);
@@ -240,7 +262,7 @@ export const fetchProducts = async ({
240
262
  * Request a purchase for products or subscriptions
241
263
  * @param params - Purchase request configuration
242
264
  * @param params.request - Platform-specific purchase parameters
243
- * @param params.type - Type of purchase: 'inapp' for products (default) or 'subs' for subscriptions
265
+ * @param params.type - Type of purchase: 'in-app' for products (default) or 'subs' for subscriptions
244
266
  *
245
267
  * @example
246
268
  * ```typescript
@@ -250,7 +272,7 @@ export const fetchProducts = async ({
250
272
  * ios: { sku: productId },
251
273
  * android: { skus: [productId] }
252
274
  * },
253
- * type: 'inapp'
275
+ * type: 'in-app'
254
276
  * });
255
277
  *
256
278
  * // Subscription purchase
@@ -271,49 +293,20 @@ export const fetchProducts = async ({
271
293
  * ⚠️ Important: This is an event-based operation, not promise-based.
272
294
  * Listen for events through purchaseUpdatedListener or purchaseErrorListener.
273
295
  * @param params - Purchase request configuration
274
- * @param params.requestPurchase - Platform-specific purchase parameters (in-app)
275
- * @param params.requestSubscription - Platform-specific subscription parameters (subs)
296
+ * @param params.request - Platform-specific request parameters
276
297
  * @param params.type - Type of purchase (defaults to in-app)
277
298
  */
278
299
  export const requestPurchase = async (
279
- params: PurchaseParams,
280
- ): Promise<void> => {
300
+ params: RequestPurchaseProps,
301
+ ): Promise<RequestPurchaseResult> => {
281
302
  try {
282
- const {requestPurchase: purchaseRequest, requestSubscription} = params;
283
- const normalizedPurchaseRequest = purchaseRequest ?? undefined;
284
- const normalizedSubscriptionRequest = requestSubscription ?? undefined;
285
-
286
- const effectiveType = normalizeProductQueryType(params.type);
287
- const isSubs = isSubscriptionQuery(effectiveType);
288
- let request:
303
+ const normalizedType = normalizeProductQueryType(params.type);
304
+ const isSubs = isSubscriptionQuery(normalizedType);
305
+ const request = params.request as
289
306
  | RequestPurchasePropsByPlatforms
290
307
  | RequestSubscriptionPropsByPlatforms
291
308
  | undefined;
292
309
 
293
- if (isSubs) {
294
- if (
295
- __DEV__ &&
296
- normalizedPurchaseRequest &&
297
- !normalizedSubscriptionRequest
298
- ) {
299
- console.warn(
300
- '[react-native-iap] `requestPurchase` was provided for a subscription request. Did you mean to use `requestSubscription`?',
301
- );
302
- }
303
- request = normalizedSubscriptionRequest ?? normalizedPurchaseRequest;
304
- } else {
305
- if (
306
- __DEV__ &&
307
- normalizedSubscriptionRequest &&
308
- !normalizedPurchaseRequest
309
- ) {
310
- console.warn(
311
- '[react-native-iap] `requestSubscription` was provided for an in-app purchase request. Did you mean to use `requestPurchase`?',
312
- );
313
- }
314
- request = normalizedPurchaseRequest ?? normalizedSubscriptionRequest;
315
- }
316
-
317
310
  if (!request) {
318
311
  throw new Error('Missing purchase request configuration');
319
312
  }
@@ -341,16 +334,19 @@ export const requestPurchase = async (
341
334
  const unifiedRequest: any = {};
342
335
 
343
336
  if (Platform.OS === 'ios' && request.ios) {
344
- const iosReq = request.ios as RequestPurchaseIosProps;
345
- const autoFinishSubs =
346
- isSubs && iosReq.andDangerouslyFinishTransactionAutomatically == null;
347
- unifiedRequest.ios = {
348
- ...iosReq,
349
- // Align with native SwiftUI flow: auto-finish subscriptions by default
350
- ...(autoFinishSubs
351
- ? {andDangerouslyFinishTransactionAutomatically: true}
352
- : {}),
353
- } as RequestPurchaseIosProps;
337
+ if (isSubs) {
338
+ const iosReq = request.ios as RequestSubscriptionIosProps;
339
+ const autoFinishSubs =
340
+ iosReq.andDangerouslyFinishTransactionAutomatically == null;
341
+ unifiedRequest.ios = {
342
+ ...iosReq,
343
+ ...(autoFinishSubs
344
+ ? {andDangerouslyFinishTransactionAutomatically: true}
345
+ : {}),
346
+ } as RequestSubscriptionIosProps;
347
+ } else {
348
+ unifiedRequest.ios = request.ios as RequestPurchaseIosProps;
349
+ }
354
350
  }
355
351
 
356
352
  if (Platform.OS === 'android' && request.android) {
@@ -359,14 +355,14 @@ export const requestPurchase = async (
359
355
  unifiedRequest.android = {
360
356
  ...subsRequest,
361
357
  subscriptionOffers: subsRequest.subscriptionOffers || [],
362
- } as RequestPurchaseAndroidProps;
358
+ } as RequestSubscriptionAndroidProps;
363
359
  } else {
364
- unifiedRequest.android = request.android;
360
+ unifiedRequest.android = request.android as RequestPurchaseAndroidProps;
365
361
  }
366
362
  }
367
363
 
368
364
  // Call unified method - returns void, listen for events instead
369
- await IAP.instance.requestPurchase(unifiedRequest);
365
+ return await IAP.instance.requestPurchase(unifiedRequest);
370
366
  } catch (error) {
371
367
  console.error('Failed to request purchase:', error);
372
368
  throw error;
@@ -1,4 +1,5 @@
1
1
  import type {HybridObject} from 'react-native-nitro-modules';
2
+ import type {RequestPurchaseResult} from '../types';
2
3
 
3
4
  // ╔══════════════════════════════════════════════════════════════════════════╗
4
5
  // ║ PARAMS ║
@@ -307,7 +308,9 @@ export interface RnIap extends HybridObject<{ios: 'swift'; android: 'kotlin'}> {
307
308
  * @param request - Platform-specific purchase request parameters
308
309
  * @returns Promise<void> - Always returns void, listen for events instead
309
310
  */
310
- requestPurchase(request: NitroPurchaseRequest): Promise<void>;
311
+ requestPurchase(
312
+ request: NitroPurchaseRequest,
313
+ ): Promise<RequestPurchaseResult>;
311
314
 
312
315
  /**
313
316
  * Get available purchases (unified method for both platforms)