react-native-iap 16.0.2 → 16.2.0

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 (86) hide show
  1. package/README.md +4 -32
  2. package/android/gradle.properties +3 -3
  3. package/android/src/main/cpp/cpp-adapter.cpp +4 -1
  4. package/android/src/main/java/com/margelo/nitro/iap/HybridRnIap.kt +7 -7
  5. package/android/src/main/java/com/margelo/nitro/iap/NitroIapPackage.java +2 -6
  6. package/ios/RnIapHelper.swift +22 -0
  7. package/lib/module/hooks/useIAP.js +12 -4
  8. package/lib/module/hooks/useIAP.js.map +1 -1
  9. package/lib/module/index.js +6 -6
  10. package/lib/module/index.js.map +1 -1
  11. package/lib/module/types.js.map +1 -1
  12. package/lib/module/utils/type-bridge.js.map +1 -1
  13. package/lib/typescript/src/hooks/useIAP.d.ts +1 -3
  14. package/lib/typescript/src/hooks/useIAP.d.ts.map +1 -1
  15. package/lib/typescript/src/index.d.ts +13 -13
  16. package/lib/typescript/src/index.d.ts.map +1 -1
  17. package/lib/typescript/src/index.kepler.d.ts +7 -7
  18. package/lib/typescript/src/index.kepler.d.ts.map +1 -1
  19. package/lib/typescript/src/specs/RnIap.nitro.d.ts +5 -3
  20. package/lib/typescript/src/specs/RnIap.nitro.d.ts.map +1 -1
  21. package/lib/typescript/src/types.d.ts +23 -7
  22. package/lib/typescript/src/types.d.ts.map +1 -1
  23. package/lib/typescript/src/utils/available-purchases.d.ts +1 -1
  24. package/lib/typescript/src/utils/available-purchases.d.ts.map +1 -1
  25. package/lib/typescript/src/utils/error.d.ts +1 -1
  26. package/lib/typescript/src/utils/error.d.ts.map +1 -1
  27. package/lib/typescript/src/utils/errorMapping.d.ts +1 -1
  28. package/lib/typescript/src/utils/errorMapping.d.ts.map +1 -1
  29. package/lib/typescript/src/utils/purchase.d.ts +1 -1
  30. package/lib/typescript/src/utils/purchase.d.ts.map +1 -1
  31. package/lib/typescript/src/utils/type-bridge.d.ts +2 -2
  32. package/lib/typescript/src/utils/type-bridge.d.ts.map +1 -1
  33. package/lib/typescript/src/utils.d.ts +1 -1
  34. package/lib/typescript/src/utils.d.ts.map +1 -1
  35. package/lib/typescript/src/vega-adapter.d.ts +1 -1
  36. package/lib/typescript/src/vega-adapter.d.ts.map +1 -1
  37. package/lib/typescript/src/vega.d.ts +1 -1
  38. package/lib/typescript/src/vega.d.ts.map +1 -1
  39. package/lib/typescript/src/vega.kepler.d.ts +1 -1
  40. package/lib/typescript/src/vega.kepler.d.ts.map +1 -1
  41. package/nitrogen/generated/android/NitroIap+autolinking.cmake +1 -0
  42. package/nitrogen/generated/android/c++/JAdvancedCommerceInfoIOS.hpp +10 -1
  43. package/nitrogen/generated/android/c++/JFunc_void_NitroPurchase.hpp +5 -0
  44. package/nitrogen/generated/android/c++/JHybridRnIapSpec.cpp +9 -0
  45. package/nitrogen/generated/android/c++/JNitroPurchase.hpp +5 -0
  46. package/nitrogen/generated/android/c++/JNitroPurchaseVerificationResultIOS.hpp +5 -0
  47. package/nitrogen/generated/android/c++/JPurchase.hpp +5 -0
  48. package/nitrogen/generated/android/c++/JPurchaseIOS.hpp +5 -0
  49. package/nitrogen/generated/android/c++/JRequestPurchaseResult.hpp +5 -0
  50. package/nitrogen/generated/android/c++/JSubscriptionPeriodIOS.hpp +67 -0
  51. package/nitrogen/generated/android/c++/JSubscriptionPeriodValueIOS.hpp +62 -0
  52. package/nitrogen/generated/android/c++/JVariant_NitroPurchaseVerificationResultIOS_NitroPurchaseVerificationResultAndroid.hpp +5 -0
  53. package/nitrogen/generated/android/c++/JVariant_NullType_AdvancedCommerceInfoIOS.hpp +5 -0
  54. package/nitrogen/generated/android/c++/JVariant_NullType_NitroPurchase.hpp +5 -0
  55. package/nitrogen/generated/android/c++/JVariant_NullType_SubscriptionPeriodValueIOS.cpp +26 -0
  56. package/nitrogen/generated/android/c++/JVariant_NullType_SubscriptionPeriodValueIOS.hpp +73 -0
  57. package/nitrogen/generated/android/kotlin/com/margelo/nitro/iap/AdvancedCommerceInfoIOS.kt +7 -2
  58. package/nitrogen/generated/android/kotlin/com/margelo/nitro/iap/Func_void_DeveloperProvidedBillingDetailsAndroid.kt +0 -2
  59. package/nitrogen/generated/android/kotlin/com/margelo/nitro/iap/Func_void_NitroProduct.kt +0 -2
  60. package/nitrogen/generated/android/kotlin/com/margelo/nitro/iap/Func_void_NitroPurchase.kt +0 -2
  61. package/nitrogen/generated/android/kotlin/com/margelo/nitro/iap/Func_void_NitroPurchaseResult.kt +0 -2
  62. package/nitrogen/generated/android/kotlin/com/margelo/nitro/iap/Func_void_UserChoiceBillingDetails.kt +0 -2
  63. package/nitrogen/generated/android/kotlin/com/margelo/nitro/iap/HybridRnIapSpec.kt +2 -0
  64. package/nitrogen/generated/android/kotlin/com/margelo/nitro/iap/SubscriptionPeriodIOS.kt +26 -0
  65. package/nitrogen/generated/android/kotlin/com/margelo/nitro/iap/SubscriptionPeriodValueIOS.kt +56 -0
  66. package/nitrogen/generated/android/kotlin/com/margelo/nitro/iap/Variant_NullType_SubscriptionPeriodValueIOS.kt +62 -0
  67. package/nitrogen/generated/ios/NitroIap-Swift-Cxx-Bridge.hpp +50 -0
  68. package/nitrogen/generated/ios/NitroIap-Swift-Cxx-Umbrella.hpp +6 -0
  69. package/nitrogen/generated/ios/c++/HybridRnIapSpecSwift.hpp +6 -0
  70. package/nitrogen/generated/ios/swift/AdvancedCommerceInfoIOS.swift +38 -1
  71. package/nitrogen/generated/ios/swift/SubscriptionPeriodIOS.swift +52 -0
  72. package/nitrogen/generated/ios/swift/SubscriptionPeriodValueIOS.swift +34 -0
  73. package/nitrogen/generated/ios/swift/Variant_NullType_SubscriptionPeriodValueIOS.swift +30 -0
  74. package/nitrogen/generated/shared/c++/AdvancedCommerceInfoIOS.hpp +8 -1
  75. package/nitrogen/generated/shared/c++/SubscriptionPeriodIOS.hpp +88 -0
  76. package/nitrogen/generated/shared/c++/SubscriptionPeriodValueIOS.hpp +88 -0
  77. package/openiap-versions.json +3 -3
  78. package/package.json +34 -37
  79. package/src/hooks/useIAP.ts +50 -31
  80. package/src/index.ts +19 -22
  81. package/src/specs/RnIap.nitro.ts +9 -15
  82. package/src/types.ts +23 -7
  83. package/src/utils/type-bridge.ts +0 -2
  84. package/lib/module/types/react-test-renderer.d.js +0 -2
  85. package/lib/module/types/react-test-renderer.d.js.map +0 -1
  86. package/src/types/react-test-renderer.d.ts +0 -7
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "react-native-iap",
3
- "version": "16.0.2",
3
+ "version": "16.2.0",
4
4
  "description": "React Native In-App Purchases module for iOS and Android using Nitro",
5
5
  "main": "./lib/module/index.js",
6
6
  "types": "./lib/typescript/src/index.d.ts",
@@ -47,11 +47,11 @@
47
47
  "typecheck:lib": "yarn tsc --noEmit",
48
48
  "clean": "rm -rf android/build node_modules/**/android/build lib nitrogen/generated",
49
49
  "lint": "eslint --ext .ts,.tsx,.js,.jsx src",
50
- "lint:eslint": "eslint --fix 'src/**/*.{ts,tsx}'",
50
+ "lint:eslint": "eslint --no-warn-ignored --fix 'src/**/*.{ts,tsx}'",
51
51
  "lint:prettier": "prettier --write \"**/*.{md,js,jsx,ts,tsx}\"",
52
52
  "lint:tsc": "tsc -p tsconfig.json --noEmit --skipLibCheck",
53
53
  "lint:ci": "yarn lint:tsc && yarn lint:eslint && yarn lint:prettier",
54
- "prepare": "npx tsx scripts/check-nitro-versions.ts && bob build && yarn nitrogen",
54
+ "prepare": "tsx scripts/check-nitro-versions.ts && bob build && yarn nitrogen",
55
55
  "nitrogen": "node --stack-size=65536 node_modules/nitrogen/lib/index.js",
56
56
  "specs": "yarn nitrogen --logLevel=\"debug\"",
57
57
  "test": "jest --coverage",
@@ -61,7 +61,7 @@
61
61
  "test:ci": "jest --maxWorkers=2 --coverage",
62
62
  "test:ci:example": "yarn workspace rn-iap-example test --coverage",
63
63
  "verify:consumer-install": "node ../../scripts/verify-npm-consumer-install.mjs --package . --package-name react-native-iap --required openiap-versions.json --required lib/module/index.js --required lib/typescript/src/index.d.ts --required android/build.gradle --required NitroIap.podspec --required nitro.json",
64
- "prepare:husky": "husky install",
64
+ "prepare:husky": "husky",
65
65
  "precommit": "lint-staged",
66
66
  "ci:check": "./scripts/ci-check.sh",
67
67
  "generate:types": "node scripts/update-types.mjs",
@@ -87,39 +87,40 @@
87
87
  "registry": "https://registry.npmjs.org/"
88
88
  },
89
89
  "devDependencies": {
90
- "@babel/plugin-proposal-private-methods": "^7.18.6",
91
- "@commitlint/cli": "^19.8.1",
92
- "@commitlint/config-conventional": "^19.8.1",
93
- "@react-native/eslint-config": "0.81.0",
94
- "@testing-library/react": "^16.3.0",
95
- "@testing-library/react-hooks": "^8.0.1",
96
- "@types/jest": "^29.5.12",
97
- "@types/node": "^24.4.0",
98
- "@types/react": "^19.1.12",
99
- "babel-jest": "^30.1.1",
100
- "eslint": "^8.57.0",
101
- "eslint-config-expo": "^9.2.0",
102
- "eslint-config-prettier": "^9.1.0",
103
- "eslint-plugin-prettier": "^5.2.1",
104
- "expo": "^53.0.20",
105
- "husky": "^8.0.3",
106
- "jest": "^30.1.1",
107
- "lint-staged": "^15.2.0",
108
- "nitrogen": "^0.36.1",
109
- "prettier": "^3.3.3",
110
- "react": "19.1.0",
111
- "react-native": "0.81.1",
112
- "react-native-builder-bob": "^0.38.4",
113
- "react-native-nitro-modules": "^0.36.1",
114
- "react-test-renderer": "^19.1.1",
115
- "typescript": "^5.9.2"
90
+ "@babel/core": "^7.29.7",
91
+ "@commitlint/cli": "^21.2.1",
92
+ "@commitlint/config-conventional": "^21.2.0",
93
+ "@react-native/babel-preset": "0.86.2",
94
+ "@react-native/jest-preset": "0.86.2",
95
+ "@types/jest": "^29.5.14",
96
+ "@types/node": "^26.2.0",
97
+ "@types/react": "^19.2.18",
98
+ "babel-jest": "^29.7.0",
99
+ "eslint": "^9.39.5",
100
+ "eslint-config-expo": "^57.0.1",
101
+ "eslint-config-prettier": "^10.1.8",
102
+ "eslint-plugin-prettier": "^5.5.6",
103
+ "expo": "^57.0.11",
104
+ "globals": "^17.9.0",
105
+ "husky": "^9.1.7",
106
+ "jest": "^29.7.0",
107
+ "lint-staged": "^17.3.0",
108
+ "nitrogen": "^0.36.5",
109
+ "prettier": "^3.9.6",
110
+ "react": "19.2.8",
111
+ "react-native": "0.86.2",
112
+ "react-native-builder-bob": "^0.43.0",
113
+ "react-native-nitro-modules": "^0.36.5",
114
+ "test-renderer": "^1.2.0",
115
+ "tsx": "^4.23.11",
116
+ "typescript": "^5.9.3"
116
117
  },
117
118
  "peerDependencies": {
118
- "@amazon-devices/keplerscript-appstore-iap-lib": "~2.12.13",
119
+ "@amazon-devices/keplerscript-appstore-iap-lib": "~2.13.0",
119
120
  "@amazon-devices/package-manager-lib": "~1.0.1767254401",
120
121
  "react": "*",
121
122
  "react-native": "*",
122
- "react-native-nitro-modules": "^0.36.1"
123
+ "react-native-nitro-modules": "^0.36.5"
123
124
  },
124
125
  "peerDependenciesMeta": {
125
126
  "@amazon-devices/keplerscript-appstore-iap-lib": {
@@ -132,10 +133,6 @@
132
133
  "workspaces": [
133
134
  "example"
134
135
  ],
135
- "eslintIgnore": [
136
- "node_modules/",
137
- "lib/"
138
- ],
139
136
  "react-native-builder-bob": {
140
137
  "source": "src",
141
138
  "output": "lib",
@@ -176,6 +173,6 @@
176
173
  },
177
174
  "packageManager": "yarn@3.6.1",
178
175
  "resolutions": {
179
- "nitrogen@^0.36.1": "patch:nitrogen@npm%3A0.36.1#./.yarn/patches/nitrogen-npm-0.36.1-abe3b64156.patch"
176
+ "nitrogen@^0.36.5": "patch:nitrogen@npm%3A0.36.5#./.yarn/patches/nitrogen-npm-0.36.5-array-equatable.patch"
180
177
  }
181
178
  }
@@ -47,8 +47,6 @@ import type {
47
47
  VerifyPurchaseWithProviderProps,
48
48
  VerifyPurchaseWithProviderResult,
49
49
  PurchaseOptions,
50
- } from '../types';
51
- import type {
52
50
  ActiveSubscription,
53
51
  Product,
54
52
  Purchase,
@@ -57,8 +55,8 @@ import type {
57
55
  ProductSubscription,
58
56
  MutationField,
59
57
  QueryField,
58
+ MutationFinishTransactionArgs,
60
59
  } from '../types';
61
- import type {MutationFinishTransactionArgs} from '../types';
62
60
 
63
61
  // Types for event subscriptions
64
62
  interface EventSubscription {
@@ -354,7 +352,8 @@ export function useIAP(options?: UseIapOptions): UseIap {
354
352
  }>({});
355
353
 
356
354
  // Track if component is mounted to prevent listener leaks on early unmount
357
- const isMountedRef = useRef<boolean>(true);
355
+ const isMountedRef = useRef<boolean>(false);
356
+ const initializationGenerationRef = useRef(0);
358
357
 
359
358
  const subscriptionsRefState = useRef<ProductSubscription[]>([]);
360
359
 
@@ -693,37 +692,56 @@ export function useIAP(options?: UseIapOptions): UseIap {
693
692
  subscriptionsRef.current.subscriptionBillingIssue = undefined;
694
693
  }, []);
695
694
 
696
- const initIapWithSubscriptions = useCallback(async (): Promise<void> => {
697
- const config = buildAndroidConfig();
698
-
699
- try {
700
- const result = await initConnection(config);
701
-
702
- if (!isMountedRef.current) {
695
+ const initIapWithSubscriptions = useCallback(
696
+ async (generation: number): Promise<void> => {
697
+ if (
698
+ !isMountedRef.current ||
699
+ initializationGenerationRef.current !== generation
700
+ ) {
703
701
  return;
704
702
  }
705
703
 
706
- if (!result) {
707
- cleanupListeners();
708
- setConnected(false);
709
- RnIapConsole.warn('[useIAP] initConnection returned false');
710
- return;
711
- }
704
+ const config = buildAndroidConfig();
712
705
 
713
- // Android retains events emitted during connection setup in bounded
714
- // native queues; registration flushes that backlog after Nitro is ready.
715
- // Other platforms preserve the existing post-init listener ordering.
716
- registerListeners();
717
- setConnected(true);
718
- } catch (error) {
719
- RnIapConsole.error('initConnection failed:', error);
720
- cleanupListeners();
721
- if (isMountedRef.current) {
722
- setConnected(false);
706
+ try {
707
+ const result = await initConnection(config);
708
+
709
+ if (
710
+ !isMountedRef.current ||
711
+ initializationGenerationRef.current !== generation
712
+ ) {
713
+ return;
714
+ }
715
+
716
+ if (!result) {
717
+ cleanupListeners();
718
+ setConnected(false);
719
+ RnIapConsole.warn('[useIAP] initConnection returned false');
720
+ return;
721
+ }
722
+
723
+ // Android retains events emitted during connection setup in bounded
724
+ // native queues; registration flushes that backlog after Nitro is ready.
725
+ // Other platforms preserve the existing post-init listener ordering.
726
+ registerListeners();
727
+ setConnected(true);
728
+ } catch (error) {
729
+ if (
730
+ !isMountedRef.current ||
731
+ initializationGenerationRef.current !== generation
732
+ ) {
733
+ return;
734
+ }
735
+ RnIapConsole.error('initConnection failed:', error);
736
+ cleanupListeners();
737
+ if (isMountedRef.current) {
738
+ setConnected(false);
739
+ }
740
+ invokeOnError(error);
723
741
  }
724
- invokeOnError(error);
725
- }
726
- }, [buildAndroidConfig, registerListeners, cleanupListeners, invokeOnError]);
742
+ },
743
+ [buildAndroidConfig, registerListeners, cleanupListeners, invokeOnError],
744
+ );
727
745
 
728
746
  const reconnect = useCallback(async (): Promise<boolean> => {
729
747
  const config = buildAndroidConfig();
@@ -755,8 +773,9 @@ export function useIAP(options?: UseIapOptions): UseIap {
755
773
  }, [buildAndroidConfig, registerListeners, cleanupListeners, invokeOnError]);
756
774
 
757
775
  useEffect(() => {
776
+ const generation = ++initializationGenerationRef.current;
758
777
  isMountedRef.current = true;
759
- initIapWithSubscriptions();
778
+ void Promise.resolve().then(() => initIapWithSubscriptions(generation));
760
779
 
761
780
  return () => {
762
781
  isMountedRef.current = false;
package/src/index.ts CHANGED
@@ -1,7 +1,6 @@
1
1
  // External dependencies
2
2
  import {Platform} from 'react-native';
3
- // Side-effect import ensures Nitro installs its dispatcher before IAP is used (no-op in tests)
4
- import 'react-native-nitro-modules';
3
+ // Importing NitroModules installs its dispatcher before IAP is used (no-op in tests).
5
4
  import {NitroModules} from 'react-native-nitro-modules';
6
5
 
7
6
  // Internal modules
@@ -16,9 +15,21 @@ import type {
16
15
  } from './specs/RnIap.nitro';
17
16
  import {ErrorCode} from './types';
18
17
  import type {
18
+ AppTransaction,
19
19
  AndroidSubscriptionOfferInput,
20
+ ActiveSubscription,
21
+ BillingChoiceInfoAndroid,
22
+ BillingProgramAndroid,
23
+ BillingProgramInformationDialogParamsAndroid,
24
+ BillingProgramReportingDetailsAndroid,
25
+ BillingResultAndroid,
26
+ DeveloperBillingTypeAndroid,
27
+ DeveloperProvidedBillingDetailsAndroid,
20
28
  DiscountOfferInputIOS,
21
29
  FetchProductsResult,
30
+ GetBillingChoiceInfoParamsAndroid,
31
+ InAppMessageParamsAndroid,
32
+ InAppMessageResultAndroid,
22
33
  MutationField,
23
34
  Product,
24
35
  ProductIOS,
@@ -29,7 +40,6 @@ import type {
29
40
  PurchaseUpdatedListenerOptions,
30
41
  PurchaseIOS,
31
42
  QueryField,
32
- AppTransaction,
33
43
  VerifyPurchaseResultAndroid,
34
44
  VerifyPurchaseResultIOS,
35
45
  RequestPurchaseAndroidProps,
@@ -38,8 +48,6 @@ import type {
38
48
  RequestSubscriptionAndroidProps,
39
49
  RequestSubscriptionIosProps,
40
50
  RequestSubscriptionPropsByPlatforms,
41
- ActiveSubscription,
42
- DeveloperProvidedBillingDetailsAndroid,
43
51
  UserChoiceBillingDetails,
44
52
  } from './types';
45
53
  import {
@@ -69,20 +77,8 @@ import {getVegaIapModule, isVegaOS} from './vega';
69
77
  // Billing Programs API (Android 8.2.0+)
70
78
  // ------------------------------
71
79
 
72
- // Note: BillingProgramAndroid, ExternalLinkLaunchModeAndroid, and ExternalLinkTypeAndroid
80
+ // BillingProgramAndroid, ExternalLinkLaunchModeAndroid, and ExternalLinkTypeAndroid
73
81
  // are exported from './types' (auto-generated from openiap-gql).
74
- // Import them here for use in this file's interfaces and functions.
75
- import type {
76
- BillingChoiceInfoAndroid,
77
- BillingProgramAndroid,
78
- BillingProgramInformationDialogParamsAndroid,
79
- BillingProgramReportingDetailsAndroid,
80
- BillingResultAndroid,
81
- DeveloperBillingTypeAndroid,
82
- GetBillingChoiceInfoParamsAndroid,
83
- InAppMessageParamsAndroid,
84
- InAppMessageResultAndroid,
85
- } from './types';
86
82
 
87
83
  // Export all types
88
84
  export type {
@@ -888,8 +884,7 @@ export const fetchProducts: QueryField<'fetchProducts'> = async (request) => {
888
884
 
889
885
  if (normalizedType === 'all') {
890
886
  const converted = (await fetchAndConvert('all')) as (
891
- | Product
892
- | ProductSubscription
887
+ Product | ProductSubscription
893
888
  )[];
894
889
 
895
890
  RnIapConsole.debug(
@@ -2263,8 +2258,10 @@ export const syncIOS: MutationField<'syncIOS'> = async () => {
2263
2258
 
2264
2259
  /**
2265
2260
  * Present the code redemption sheet for offer codes (iOS only)
2266
- * @returns The verified redeemed purchase on iOS 27+, or null after the
2267
- * legacy sheet is presented on earlier iOS versions.
2261
+ * @returns The verified redeemed purchase when built with Xcode 27+ and
2262
+ * running on Apple 27+. Earlier iOS/visionOS system sheets return null;
2263
+ * Catalyst 16–26 surfaces StoreKitError.unknown, and Catalyst 15 is a no-op
2264
+ * that returns null.
2268
2265
  * @platform iOS
2269
2266
  *
2270
2267
  * @see {@link https://openiap.dev/docs/apis/ios/present-code-redemption-sheet-ios}
@@ -128,22 +128,16 @@ export type BillingChoiceImageLayoutAndroid =
128
128
  | 'rectangular-two-by-two';
129
129
 
130
130
  export type BillingChoiceScreenTypeAndroid =
131
- | 'unspecified'
132
- | 'developer-rendered'
133
- | 'google-rendered';
131
+ 'unspecified' | 'developer-rendered' | 'google-rendered';
134
132
 
135
133
  export type DeveloperBillingTypeAndroid =
136
- | 'developer-billing-type-unspecified'
137
- | 'in-app'
138
- | 'external-link';
134
+ 'developer-billing-type-unspecified' | 'in-app' | 'external-link';
139
135
 
140
136
  export type InAppMessageCategoryAndroid =
141
- | 'unknown-in-app-message-category-id'
142
- | 'transactional';
137
+ 'unknown-in-app-message-category-id' | 'transactional';
143
138
 
144
139
  export type InAppMessageResponseCodeAndroid =
145
- | 'no-action-needed'
146
- | 'subscription-status-updated';
140
+ 'no-action-needed' | 'subscription-status-updated';
147
141
 
148
142
  // Developer Billing Launch Mode (Android 8.3.0+)
149
143
  // Defined locally for Nitro codegen
@@ -162,9 +156,7 @@ export type ExternalLinkLaunchModeAndroid =
162
156
  // External Link Type (Android 8.2.0+)
163
157
  // Defined locally for Nitro codegen
164
158
  export type ExternalLinkTypeAndroid =
165
- | 'unspecified'
166
- | 'link-to-digital-content-offer'
167
- | 'link-to-app-download';
159
+ 'unspecified' | 'link-to-digital-content-offer' | 'link-to-app-download';
168
160
 
169
161
  // ╔══════════════════════════════════════════════════════════════════════════╗
170
162
  // ║ PARAMS ║
@@ -836,8 +828,10 @@ export interface RnIap extends HybridObject<{ios: 'swift'; android: 'kotlin'}> {
836
828
 
837
829
  /**
838
830
  * Present the code redemption sheet for offer codes (iOS only)
839
- * @returns The verified redeemed purchase on iOS 27+, or null after the
840
- * legacy sheet is presented on earlier iOS versions.
831
+ * @returns The verified redeemed purchase when built with Xcode 27+ and
832
+ * running on Apple 27+. Earlier iOS/visionOS system sheets return null;
833
+ * Catalyst 16–26 surfaces StoreKitError.unknown, and Catalyst 15 is a no-op
834
+ * that returns null.
841
835
  * @platform iOS
842
836
  */
843
837
  presentCodeRedemptionSheetIOS(): Promise<NitroPurchase | null>;
package/src/types.ts CHANGED
@@ -46,6 +46,8 @@ export interface AdvancedCommerceInfoIOS {
46
46
  estimatedTax?: (string | null);
47
47
  /** The items purchased as part of this transaction */
48
48
  items: AdvancedCommerceItemIOS[];
49
+ /** Subscription period for this transaction */
50
+ period?: (SubscriptionPeriodValueIOS | null);
49
51
  /** Request reference identifier for tracking */
50
52
  requestReferenceId?: (string | null);
51
53
  /** Tax code for the transaction */
@@ -809,11 +811,15 @@ export interface Mutation {
809
811
  openRedeemOfferCodeAndroid: Promise<boolean>;
810
812
  /**
811
813
  * Show the App Store offer code redemption sheet.
812
- * On iOS 27+, Mac Catalyst 27+, and visionOS 27+, returns the verified
813
- * transaction produced by the redemption. Earlier iOS and Mac Catalyst
814
- * versions present the legacy sheet and return null; reconcile purchases
815
- * through the normal transaction listener or an explicit available-purchases
816
- * refresh.
814
+ * When built with Xcode 27+ and running on iOS 27+, Mac Catalyst 27+, or
815
+ * visionOS 27+, returns the verified transaction produced by the redemption.
816
+ * StoreKit 2's scene-based sheet returns null after presentation on iOS 16–26,
817
+ * visionOS 1–26, and those platforms on Apple 27 when built with an older SDK.
818
+ * iOS 15 uses the StoreKit 1 sheet and also returns null. On Mac Catalyst, the
819
+ * scene-based API throws StoreKitError.unknown, while the Catalyst 15 StoreKit 1
820
+ * call has no effect and returns null. Reconcile null results from a presented
821
+ * sheet through the normal transaction listener or an explicit
822
+ * available-purchases refresh.
817
823
  * See: https://openiap.dev/docs/apis/ios/present-code-redemption-sheet-ios
818
824
  */
819
825
  presentCodeRedemptionSheetIOS?: Promise<(PurchaseIOS | null)>;
@@ -1427,7 +1433,12 @@ export interface Query {
1427
1433
  */
1428
1434
  getPendingTransactionsIOS: Promise<PurchaseIOS[]>;
1429
1435
  /**
1430
- * Read the App Store-promoted product, if any (iOS 11+).
1436
+ * Read the App Store-promoted product, if any (iOS 15+).
1437
+ * OpenIAP consumes PurchaseIntent.intents on iOS 16.4+ and uses the
1438
+ * StoreKit 1 observer only on iOS 15–16.3. When PurchaseIntent carries an
1439
+ * externally redeemed win-back offer, OpenIAP preserves it for the next
1440
+ * matching requestPurchase unless the caller supplies an explicit win-back or
1441
+ * promotional offer.
1431
1442
  * See: https://openiap.dev/docs/apis/ios/get-promoted-product-ios
1432
1443
  */
1433
1444
  getPromotedProductIOS?: Promise<(ProductIOS | null)>;
@@ -1864,7 +1875,12 @@ export interface Subscription {
1864
1875
  * openiap-google 2.3.0 (requires Play Billing 9.1.0+).
1865
1876
  */
1866
1877
  developerProvidedBillingAndroid: DeveloperProvidedBillingDetailsAndroid;
1867
- /** Fires when the App Store surfaces a promoted product (iOS only) */
1878
+ /**
1879
+ * Fires when the App Store surfaces a promoted product (iOS only).
1880
+ * A win-back offer attached to PurchaseIntent is preserved for the next
1881
+ * matching requestPurchase unless the caller supplies an explicit win-back or
1882
+ * promotional offer.
1883
+ */
1868
1884
  promotedProductIOS: string;
1869
1885
  /** Fires when a purchase fails or is cancelled */
1870
1886
  purchaseError: PurchaseError;
@@ -19,8 +19,6 @@ import type {
19
19
  ProductTypeIOS,
20
20
  PurchaseState,
21
21
  SubscriptionPeriodIOS,
22
- } from '../types';
23
- import type {
24
22
  Product,
25
23
  ProductSubscription,
26
24
  Purchase,
@@ -1,2 +0,0 @@
1
- "use strict";
2
- //# sourceMappingURL=react-test-renderer.d.js.map
@@ -1 +0,0 @@
1
- {"version":3,"names":[],"sourceRoot":"../../../src","sources":["types/react-test-renderer.d.ts"],"mappings":"","ignoreList":[]}
@@ -1,7 +0,0 @@
1
- declare module 'react-test-renderer' {
2
- export function act(
3
- callback: () => void | Promise<void>,
4
- ): void | Promise<void>;
5
- const TestRenderer: any;
6
- export default TestRenderer;
7
- }