react-native-iap 15.2.4 → 15.3.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (34) hide show
  1. package/README.md +29 -49
  2. package/android/build.gradle +92 -22
  3. package/android/gradle.properties +5 -1
  4. package/android/src/main/java/com/margelo/nitro/iap/HybridRnIap.kt +1 -1
  5. package/android/src/main/java/com/margelo/nitro/iap/RnIapLog.kt +3 -1
  6. package/ios/HybridRnIap.swift +12 -6
  7. package/lib/module/index.js +73 -158
  8. package/lib/module/index.js.map +1 -1
  9. package/lib/typescript/src/hooks/useIAP.d.ts +15 -15
  10. package/lib/typescript/src/index.d.ts +59 -88
  11. package/lib/typescript/src/index.d.ts.map +1 -1
  12. package/lib/typescript/src/specs/RnIap.nitro.d.ts +2 -15
  13. package/lib/typescript/src/specs/RnIap.nitro.d.ts.map +1 -1
  14. package/lib/typescript/src/types.d.ts +47 -47
  15. package/nitro.json +0 -1
  16. package/nitrogen/generated/android/c++/JHybridRnIapSpec.cpp +7 -7
  17. package/nitrogen/generated/android/c++/JHybridRnIapSpec.hpp +1 -1
  18. package/nitrogen/generated/android/c++/{JNitroPurchaseUpdatedListenerOptions.hpp → JPurchaseUpdatedListenerOptions.hpp} +10 -10
  19. package/nitrogen/generated/android/kotlin/com/margelo/nitro/iap/HybridRnIapSpec.kt +2 -2
  20. package/nitrogen/generated/android/kotlin/com/margelo/nitro/iap/{NitroPurchaseUpdatedListenerOptions.kt → PurchaseUpdatedListenerOptions.kt} +5 -5
  21. package/nitrogen/generated/ios/NitroIap-Swift-Cxx-Bridge.hpp +10 -10
  22. package/nitrogen/generated/ios/NitroIap-Swift-Cxx-Umbrella.hpp +3 -3
  23. package/nitrogen/generated/ios/c++/HybridRnIapSpecSwift.hpp +4 -4
  24. package/nitrogen/generated/ios/swift/HybridRnIapSpec.swift +1 -1
  25. package/nitrogen/generated/ios/swift/HybridRnIapSpec_cxx.swift +1 -1
  26. package/nitrogen/generated/ios/swift/{NitroPurchaseUpdatedListenerOptions.swift → PurchaseUpdatedListenerOptions.swift} +5 -5
  27. package/nitrogen/generated/shared/c++/HybridRnIapSpec.hpp +4 -4
  28. package/nitrogen/generated/shared/c++/{NitroPurchaseUpdatedListenerOptions.hpp → PurchaseUpdatedListenerOptions.hpp} +11 -11
  29. package/openiap-versions.json +2 -2
  30. package/package.json +4 -6
  31. package/src/hooks/useIAP.ts +15 -15
  32. package/src/index.ts +93 -204
  33. package/src/specs/RnIap.nitro.ts +2 -15
  34. package/src/types.ts +47 -47
@@ -28,13 +28,14 @@ import { parseAppTransactionPayload } from "./utils.js";
28
28
 
29
29
  export * from "./types.js";
30
30
  export * from "./utils/error.js";
31
- const LEGACY_INAPP_WARNING = "[react-native-iap] `type: 'inapp'` is deprecated and will be removed in v14.4.0. Use 'in-app' instead.";
31
+ const LEGACY_INAPP_WARNING = "[react-native-iap] `type: 'inapp'` is deprecated and will be removed in a future major version. Use 'in-app' instead.";
32
32
  const toErrorMessage = error => {
33
33
  if (typeof error === 'object' && error !== null && 'message' in error && error.message != null) {
34
34
  return String(error.message);
35
35
  }
36
36
  return String(error ?? '');
37
37
  };
38
+ const unsupportedPlatformError = () => new Error(`Unsupported platform: ${Platform.OS}`);
38
39
  // ActiveSubscription and PurchaseError types are already exported via 'export * from ./types'
39
40
 
40
41
  // Export hooks
@@ -330,7 +331,7 @@ export const promotedProductListenerIOS = listener => {
330
331
  * const subscription = userChoiceBillingListenerAndroid((details) => {
331
332
  * console.log('User chose alternative billing');
332
333
  * console.log('Products:', details.products);
333
- * console.log('Token:', details.externalTransactionToken);
334
+ * console.log('External transaction token received; send it to your backend without logging it.');
334
335
  *
335
336
  * // Send token to backend for Google Play reporting
336
337
  * await reportToGooglePlay(details.externalTransactionToken);
@@ -397,7 +398,7 @@ export const userChoiceBillingListenerAndroid = listener => {
397
398
  * ```typescript
398
399
  * const subscription = developerProvidedBillingListenerAndroid((details) => {
399
400
  * console.log('User chose developer billing');
400
- * console.log('Token:', details.externalTransactionToken);
401
+ * console.log('External transaction token received; send it to your backend without logging it.');
401
402
  *
402
403
  * // Process payment through your external payment system
403
404
  * await processExternalPayment();
@@ -548,7 +549,7 @@ export const subscriptionBillingIssueListener = listener => {
548
549
  * @remarks This is a regular promise-based call. Don't confuse with `request*` APIs
549
550
  * (`requestPurchase`), which are event-based.
550
551
  *
551
- * @see {@link https://www.openiap.dev/docs/apis/fetch-products}
552
+ * @see {@link https://openiap.dev/docs/apis/fetch-products}
552
553
  */
553
554
  export const fetchProducts = async request => {
554
555
  const {
@@ -655,7 +656,7 @@ export const fetchProducts = async request => {
655
656
  * }
656
657
  * ```
657
658
  *
658
- * @see {@link https://www.openiap.dev/docs/apis/get-available-purchases}
659
+ * @see {@link https://openiap.dev/docs/apis/get-available-purchases}
659
660
  */
660
661
  export const getAvailablePurchases = async options => {
661
662
  const alsoPublishToEventListenerIOS = Boolean(options?.alsoPublishToEventListenerIOS ?? false);
@@ -700,7 +701,7 @@ export const getAvailablePurchases = async options => {
700
701
  }
701
702
  return validPurchases.map(convertNitroPurchaseToPurchase);
702
703
  } else {
703
- throw new Error('Unsupported platform');
704
+ throw unsupportedPlatformError();
704
705
  }
705
706
  } catch (error) {
706
707
  RnIapConsole.error('Failed to get available purchases:', error);
@@ -713,7 +714,7 @@ export const getAvailablePurchases = async options => {
713
714
  * @returns Promise<Product | null> - The promoted product or null if none available
714
715
  * @platform iOS
715
716
  *
716
- * @see {@link https://www.openiap.dev/docs/apis/ios/get-promoted-product-ios}
717
+ * @see {@link https://openiap.dev/docs/apis/ios/get-promoted-product-ios}
717
718
  */
718
719
  export const getPromotedProductIOS = async () => {
719
720
  if (Platform.OS !== 'ios') {
@@ -750,7 +751,7 @@ export const requestPromotedProductIOS = getPromotedProductIOS;
750
751
  * console.log('User storefront:', storefront); // e.g., 'USA', 'GBR', 'KOR'
751
752
  * ```
752
753
  *
753
- * @see {@link https://www.openiap.dev/docs/apis/ios/get-storefront-ios}
754
+ * @see {@link https://openiap.dev/docs/apis/ios/get-storefront-ios}
754
755
  */
755
756
  export const getStorefrontIOS = async () => {
756
757
  if (Platform.OS !== 'ios') {
@@ -768,7 +769,7 @@ export const getStorefrontIOS = async () => {
768
769
  /**
769
770
  * Return the user's storefront country code.
770
771
  *
771
- * @see {@link https://www.openiap.dev/docs/apis/get-storefront}
772
+ * @see {@link https://openiap.dev/docs/apis/get-storefront}
772
773
  */
773
774
  export const getStorefront = async () => {
774
775
  if (Platform.OS !== 'ios' && Platform.OS !== 'android') {
@@ -811,7 +812,7 @@ export const getStorefront = async () => {
811
812
  * }
812
813
  * ```
813
814
  *
814
- * @see {@link https://www.openiap.dev/docs/apis/ios/get-app-transaction-ios}
815
+ * @see {@link https://openiap.dev/docs/apis/ios/get-app-transaction-ios}
815
816
  */
816
817
  export const getAppTransactionIOS = async () => {
817
818
  if (Platform.OS !== 'ios') {
@@ -846,7 +847,7 @@ export const getAppTransactionIOS = async () => {
846
847
  * @throws Error when called on non-iOS platforms or when IAP is not initialized
847
848
  * @platform iOS
848
849
  *
849
- * @see {@link https://www.openiap.dev/docs/apis/ios/subscription-status-ios}
850
+ * @see {@link https://openiap.dev/docs/apis/ios/subscription-status-ios}
850
851
  */
851
852
  export const subscriptionStatusIOS = async sku => {
852
853
  if (Platform.OS !== 'ios') {
@@ -874,7 +875,7 @@ export const subscriptionStatusIOS = async sku => {
874
875
  * @returns Promise<Purchase | null> - Current entitlement or null
875
876
  * @platform iOS
876
877
  *
877
- * @see {@link https://www.openiap.dev/docs/apis/ios/current-entitlement-ios}
878
+ * @see {@link https://openiap.dev/docs/apis/ios/current-entitlement-ios}
878
879
  */
879
880
  export const currentEntitlementIOS = async sku => {
880
881
  if (Platform.OS !== 'ios') {
@@ -905,7 +906,7 @@ export const currentEntitlementIOS = async sku => {
905
906
  * @returns Promise<Purchase | null> - Latest transaction or null
906
907
  * @platform iOS
907
908
  *
908
- * @see {@link https://www.openiap.dev/docs/apis/ios/latest-transaction-ios}
909
+ * @see {@link https://openiap.dev/docs/apis/ios/latest-transaction-ios}
909
910
  */
910
911
  export const latestTransactionIOS = async sku => {
911
912
  if (Platform.OS !== 'ios') {
@@ -935,7 +936,7 @@ export const latestTransactionIOS = async sku => {
935
936
  * @returns Promise<Purchase[]> - Array of pending transactions
936
937
  * @platform iOS
937
938
  *
938
- * @see {@link https://www.openiap.dev/docs/apis/ios/get-pending-transactions-ios}
939
+ * @see {@link https://openiap.dev/docs/apis/ios/get-pending-transactions-ios}
939
940
  */
940
941
  export const getPendingTransactionsIOS = async () => {
941
942
  if (Platform.OS !== 'ios') {
@@ -959,7 +960,7 @@ export const getPendingTransactionsIOS = async () => {
959
960
  /**
960
961
  * List every StoreKit transaction (finished + unfinished) for the current user.
961
962
  *
962
- * @see {@link https://www.openiap.dev/docs/apis/ios/get-all-transactions-ios}
963
+ * @see {@link https://openiap.dev/docs/apis/ios/get-all-transactions-ios}
963
964
  */
964
965
  export const getAllTransactionsIOS = async () => {
965
966
  if (Platform.OS !== 'ios') {
@@ -985,7 +986,7 @@ export const getAllTransactionsIOS = async () => {
985
986
  * @returns Promise<Purchase[]> - Subscriptions where auto-renewal status changed
986
987
  * @platform iOS
987
988
  *
988
- * @see {@link https://www.openiap.dev/docs/apis/ios/show-manage-subscriptions-ios}
989
+ * @see {@link https://openiap.dev/docs/apis/ios/show-manage-subscriptions-ios}
989
990
  */
990
991
  export const showManageSubscriptionsIOS = async () => {
991
992
  if (Platform.OS !== 'ios') {
@@ -1012,7 +1013,7 @@ export const showManageSubscriptionsIOS = async () => {
1012
1013
  * @returns Promise<boolean> - Eligibility status
1013
1014
  * @platform iOS
1014
1015
  *
1015
- * @see {@link https://www.openiap.dev/docs/apis/ios/is-eligible-for-intro-offer-ios}
1016
+ * @see {@link https://openiap.dev/docs/apis/ios/is-eligible-for-intro-offer-ios}
1016
1017
  */
1017
1018
  export const isEligibleForIntroOfferIOS = async groupID => {
1018
1019
  if (Platform.OS !== 'ios') {
@@ -1037,7 +1038,7 @@ export const isEligibleForIntroOfferIOS = async groupID => {
1037
1038
  * @returns Promise<string> - Base64 encoded receipt data
1038
1039
  * @platform iOS
1039
1040
  *
1040
- * @see {@link https://www.openiap.dev/docs/apis/ios/get-receipt-data-ios}
1041
+ * @see {@link https://openiap.dev/docs/apis/ios/get-receipt-data-ios}
1041
1042
  */
1042
1043
  export const getReceiptDataIOS = async () => {
1043
1044
  if (Platform.OS !== 'ios') {
@@ -1106,7 +1107,7 @@ export const requestReceiptRefreshIOS = async () => {
1106
1107
  * @returns Promise<boolean> - Verification status
1107
1108
  * @platform iOS
1108
1109
  *
1109
- * @see {@link https://www.openiap.dev/docs/apis/ios/is-transaction-verified-ios}
1110
+ * @see {@link https://openiap.dev/docs/apis/ios/is-transaction-verified-ios}
1110
1111
  */
1111
1112
  export const isTransactionVerifiedIOS = async sku => {
1112
1113
  if (Platform.OS !== 'ios') {
@@ -1132,7 +1133,7 @@ export const isTransactionVerifiedIOS = async sku => {
1132
1133
  * @returns Promise<string | null> - JWS representation or null
1133
1134
  * @platform iOS
1134
1135
  *
1135
- * @see {@link https://www.openiap.dev/docs/apis/ios/get-transaction-jws-ios}
1136
+ * @see {@link https://openiap.dev/docs/apis/ios/get-transaction-jws-ios}
1136
1137
  */
1137
1138
  export const getTransactionJwsIOS = async sku => {
1138
1139
  if (Platform.OS !== 'ios') {
@@ -1173,7 +1174,7 @@ export const getTransactionJwsIOS = async sku => {
1173
1174
  * @remarks When using `useIAP()`, connection is auto-managed on mount/unmount —
1174
1175
  * pass options to the hook instead of calling this directly.
1175
1176
  *
1176
- * @see {@link https://www.openiap.dev/docs/apis/init-connection}
1177
+ * @see {@link https://openiap.dev/docs/apis/init-connection}
1177
1178
  */
1178
1179
  export const initConnection = async config => {
1179
1180
  try {
@@ -1193,7 +1194,7 @@ export const initConnection = async config => {
1193
1194
  /**
1194
1195
  * Close the store connection and release resources.
1195
1196
  *
1196
- * @see {@link https://www.openiap.dev/docs/apis/end-connection}
1197
+ * @see {@link https://openiap.dev/docs/apis/end-connection}
1197
1198
  */
1198
1199
  export const endConnection = async () => {
1199
1200
  try {
@@ -1216,7 +1217,7 @@ export const endConnection = async () => {
1216
1217
  /**
1217
1218
  * Restore non-consumable and active subscription purchases.
1218
1219
  *
1219
- * @see {@link https://www.openiap.dev/docs/apis/restore-purchases}
1220
+ * @see {@link https://openiap.dev/docs/apis/restore-purchases}
1220
1221
  */
1221
1222
  export const restorePurchases = async () => {
1222
1223
  try {
@@ -1263,7 +1264,7 @@ export const restorePurchases = async () => {
1263
1264
  * @remarks Event-based. Listen for the result via {@link purchaseUpdatedListener} /
1264
1265
  * {@link purchaseErrorListener}, or use `useIAP({ onPurchaseSuccess, onPurchaseError })`.
1265
1266
  *
1266
- * @see {@link https://www.openiap.dev/docs/apis/request-purchase}
1267
+ * @see {@link https://openiap.dev/docs/apis/request-purchase}
1267
1268
  */
1268
1269
  export const requestPurchase = async request => {
1269
1270
  try {
@@ -1290,7 +1291,7 @@ export const requestPurchase = async request => {
1290
1291
  throw new Error('Invalid request for Android. The `skus` property is required and must be a non-empty array.');
1291
1292
  }
1292
1293
  } else {
1293
- throw new Error('Unsupported platform');
1294
+ throw unsupportedPlatformError();
1294
1295
  }
1295
1296
  const unifiedRequest = {};
1296
1297
 
@@ -1317,6 +1318,18 @@ export const requestPurchase = async request => {
1317
1318
  if (iosRequest.advancedCommerceData) {
1318
1319
  iosPayload.advancedCommerceData = iosRequest.advancedCommerceData;
1319
1320
  }
1321
+ if (isSubs) {
1322
+ const subscriptionRequest = iosRequest;
1323
+ if (subscriptionRequest.introductoryOfferEligibility !== undefined) {
1324
+ iosPayload.introductoryOfferEligibility = subscriptionRequest.introductoryOfferEligibility;
1325
+ }
1326
+ if (subscriptionRequest.promotionalOfferJWS) {
1327
+ iosPayload.promotionalOfferJWS = subscriptionRequest.promotionalOfferJWS;
1328
+ }
1329
+ if (subscriptionRequest.winBackOffer) {
1330
+ iosPayload.winBackOffer = subscriptionRequest.winBackOffer;
1331
+ }
1332
+ }
1320
1333
  unifiedRequest.ios = iosPayload;
1321
1334
  }
1322
1335
 
@@ -1398,7 +1411,7 @@ export const requestPurchase = async request => {
1398
1411
  * @remarks **Critical:** Android purchases must be finalized within 3 days or Google
1399
1412
  * auto-refunds. iOS unfinished transactions replay on every app launch.
1400
1413
  *
1401
- * @see {@link https://www.openiap.dev/docs/apis/finish-transaction}
1414
+ * @see {@link https://openiap.dev/docs/apis/finish-transaction}
1402
1415
  */
1403
1416
  export const finishTransaction = async args => {
1404
1417
  const {
@@ -1428,7 +1441,7 @@ export const finishTransaction = async args => {
1428
1441
  }
1429
1442
  };
1430
1443
  } else {
1431
- throw new Error('Unsupported platform');
1444
+ throw unsupportedPlatformError();
1432
1445
  }
1433
1446
  const result = await IAP.instance.finishTransaction(params);
1434
1447
  const success = getSuccessFromPurchaseVariant(result, 'finishTransaction');
@@ -1462,7 +1475,7 @@ export const finishTransaction = async args => {
1462
1475
  * await acknowledgePurchaseAndroid('purchase_token_here');
1463
1476
  * ```
1464
1477
  *
1465
- * @see {@link https://www.openiap.dev/docs/apis/android/acknowledge-purchase-android}
1478
+ * @see {@link https://openiap.dev/docs/apis/android/acknowledge-purchase-android}
1466
1479
  */
1467
1480
  export const acknowledgePurchaseAndroid = async purchaseToken => {
1468
1481
  try {
@@ -1498,7 +1511,7 @@ export const acknowledgePurchaseAndroid = async purchaseToken => {
1498
1511
  * await consumePurchaseAndroid('purchase_token_here');
1499
1512
  * ```
1500
1513
  *
1501
- * @see {@link https://www.openiap.dev/docs/apis/android/consume-purchase-android}
1514
+ * @see {@link https://openiap.dev/docs/apis/android/consume-purchase-android}
1502
1515
  */
1503
1516
  export const consumePurchaseAndroid = async purchaseToken => {
1504
1517
  try {
@@ -1552,7 +1565,7 @@ export const consumePurchaseAndroid = async purchaseToken => {
1552
1565
  * });
1553
1566
  * ```
1554
1567
  *
1555
- * @see {@link https://www.openiap.dev/docs/apis/validate-receipt}
1568
+ * @see {@link https://openiap.dev/docs/apis/validate-receipt}
1556
1569
  */
1557
1570
  export const validateReceipt = async options => {
1558
1571
  const {
@@ -1661,7 +1674,7 @@ export const validateReceipt = async options => {
1661
1674
  * @param options - Receipt validation options containing the SKU
1662
1675
  * @returns Promise resolving to receipt validation result
1663
1676
  *
1664
- * @see {@link https://www.openiap.dev/docs/features/validation#verify-purchase}
1677
+ * @see {@link https://openiap.dev/docs/features/validation#verify-purchase}
1665
1678
  */
1666
1679
  export const verifyPurchase = validateReceipt;
1667
1680
 
@@ -1672,7 +1685,7 @@ export const verifyPurchase = validateReceipt;
1672
1685
  * consumers who imported `validateReceiptIOS` — which is still declared on the
1673
1686
  * OpenIAP Query interface — keep working. Throws on non-iOS platforms.
1674
1687
  *
1675
- * @see {@link https://www.openiap.dev/docs/apis/ios/validate-receipt-ios}
1688
+ * @see {@link https://openiap.dev/docs/apis/ios/validate-receipt-ios}
1676
1689
  */
1677
1690
  export const validateReceiptIOS = async options => {
1678
1691
  if (Platform.OS !== 'ios') {
@@ -1703,7 +1716,7 @@ export const validateReceiptIOS = async options => {
1703
1716
  * });
1704
1717
  * ```
1705
1718
  *
1706
- * @see {@link https://www.openiap.dev/docs/features/validation#verify-purchase-with-provider}
1719
+ * @see {@link https://openiap.dev/docs/features/validation#verify-purchase-with-provider}
1707
1720
  */
1708
1721
  export const verifyPurchaseWithProvider = async options => {
1709
1722
  try {
@@ -1744,7 +1757,7 @@ export const verifyPurchaseWithProvider = async options => {
1744
1757
  * @returns Promise<boolean>
1745
1758
  * @platform iOS
1746
1759
  *
1747
- * @see {@link https://www.openiap.dev/docs/apis/ios/sync-ios}
1760
+ * @see {@link https://openiap.dev/docs/apis/ios/sync-ios}
1748
1761
  */
1749
1762
  export const syncIOS = async () => {
1750
1763
  if (Platform.OS !== 'ios') {
@@ -1770,7 +1783,7 @@ export const syncIOS = async () => {
1770
1783
  * @returns Promise<boolean> - Indicates whether the redemption sheet was presented
1771
1784
  * @platform iOS
1772
1785
  *
1773
- * @see {@link https://www.openiap.dev/docs/apis/ios/present-code-redemption-sheet-ios}
1786
+ * @see {@link https://openiap.dev/docs/apis/ios/present-code-redemption-sheet-ios}
1774
1787
  */
1775
1788
  export const presentCodeRedemptionSheetIOS = async () => {
1776
1789
  if (Platform.OS !== 'ios') {
@@ -1811,7 +1824,7 @@ export const presentCodeRedemptionSheetIOS = async () => {
1811
1824
  * @returns Promise<boolean> - true when the request triggers successfully
1812
1825
  * @platform iOS
1813
1826
  *
1814
- * @see {@link https://www.openiap.dev/docs/apis/ios/request-purchase-on-promoted-product-ios}
1827
+ * @see {@link https://openiap.dev/docs/apis/ios/request-purchase-on-promoted-product-ios}
1815
1828
  */
1816
1829
  export const requestPurchaseOnPromotedProductIOS = async () => {
1817
1830
  if (Platform.OS !== 'ios') {
@@ -1846,7 +1859,7 @@ export const requestPurchaseOnPromotedProductIOS = async () => {
1846
1859
  * @returns Promise<boolean>
1847
1860
  * @platform iOS
1848
1861
  *
1849
- * @see {@link https://www.openiap.dev/docs/apis/ios/clear-transaction-ios}
1862
+ * @see {@link https://openiap.dev/docs/apis/ios/clear-transaction-ios}
1850
1863
  */
1851
1864
  export const clearTransactionIOS = async () => {
1852
1865
  if (Platform.OS !== 'ios') {
@@ -1873,7 +1886,7 @@ export const clearTransactionIOS = async () => {
1873
1886
  * @returns Promise<string | null> - The refund status or null if not available
1874
1887
  * @platform iOS
1875
1888
  *
1876
- * @see {@link https://www.openiap.dev/docs/apis/ios/begin-refund-request-ios}
1889
+ * @see {@link https://openiap.dev/docs/apis/ios/begin-refund-request-ios}
1877
1890
  */
1878
1891
  export const beginRefundRequestIOS = async sku => {
1879
1892
  if (Platform.OS !== 'ios') {
@@ -1898,7 +1911,7 @@ export const beginRefundRequestIOS = async sku => {
1898
1911
  * Deeplinks to native interface that allows users to manage their subscriptions
1899
1912
  * Cross-platform alias aligning with expo-iap
1900
1913
  *
1901
- * @see {@link https://www.openiap.dev/docs/apis/deep-link-to-subscriptions}
1914
+ * @see {@link https://openiap.dev/docs/apis/deep-link-to-subscriptions}
1902
1915
  */
1903
1916
  export const deepLinkToSubscriptions = async options => {
1904
1917
  const resolvedOptions = options ?? undefined;
@@ -1910,16 +1923,14 @@ export const deepLinkToSubscriptions = async options => {
1910
1923
  return;
1911
1924
  }
1912
1925
  if (Platform.OS === 'ios') {
1913
- try {
1914
- if (typeof IAP.instance.deepLinkToSubscriptionsIOS === 'function') {
1915
- await IAP.instance.deepLinkToSubscriptionsIOS();
1916
- } else {
1917
- await IAP.instance.showManageSubscriptionsIOS();
1918
- }
1919
- } catch (error) {
1920
- RnIapConsole.warn('[deepLinkToSubscriptions] Failed on iOS:', error);
1926
+ if (typeof IAP.instance.deepLinkToSubscriptionsIOS === 'function') {
1927
+ await IAP.instance.deepLinkToSubscriptionsIOS();
1928
+ } else {
1929
+ await IAP.instance.showManageSubscriptionsIOS();
1921
1930
  }
1931
+ return;
1922
1932
  }
1933
+ throw unsupportedPlatformError();
1923
1934
  };
1924
1935
  export const deepLinkToSubscriptionsIOS = async () => {
1925
1936
  if (Platform.OS !== 'ios') {
@@ -1956,7 +1967,7 @@ export const deepLinkToSubscriptionsIOS = async () => {
1956
1967
  * @param subscriptionIds - Optional array of subscription IDs to filter by
1957
1968
  * @returns Promise<ActiveSubscription[]> - Array of active subscriptions
1958
1969
  *
1959
- * @see {@link https://www.openiap.dev/docs/apis/get-active-subscriptions}
1970
+ * @see {@link https://openiap.dev/docs/apis/get-active-subscriptions}
1960
1971
  */
1961
1972
  export const getActiveSubscriptions = async subscriptionIds => {
1962
1973
  try {
@@ -1977,7 +1988,7 @@ export const getActiveSubscriptions = async subscriptionIds => {
1977
1988
  environmentIOS: sub.environmentIOS ?? null,
1978
1989
  willExpireSoon: sub.willExpireSoon ?? null,
1979
1990
  daysUntilExpirationIOS: sub.daysUntilExpirationIOS ?? null,
1980
- // 🆕 renewalInfoIOS - subscription lifecycle information (iOS only)
1991
+ // renewalInfoIOS contains subscription lifecycle information on iOS.
1981
1992
  renewalInfoIOS: sub.renewalInfoIOS ? {
1982
1993
  willAutoRenew: sub.renewalInfoIOS.willAutoRenew ?? false,
1983
1994
  autoRenewPreference: sub.renewalInfoIOS.autoRenewPreference ?? null,
@@ -2012,90 +2023,6 @@ export const getActiveSubscriptions = async subscriptionIds => {
2012
2023
  }
2013
2024
  };
2014
2025
 
2015
- // OLD IMPLEMENTATION - REPLACED WITH NATIVE CALL
2016
- /*
2017
- export const getActiveSubscriptions_OLD: QueryField<
2018
- 'getActiveSubscriptions'
2019
- > = async (subscriptionIds) => {
2020
- try {
2021
- // Get all available purchases first
2022
- const allPurchases = await getAvailablePurchases();
2023
-
2024
- // For the critical bug fix: this function was previously returning ALL purchases
2025
- // Now we properly filter for subscriptions only
2026
-
2027
- // In production with real data, Android subscription filtering is done via platform-specific calls
2028
- // But for backward compatibility and test support, we also check platform-specific fields
2029
-
2030
- // Since expirationDateIOS and subscriptionGroupIdIOS are not available in NitroPurchase,
2031
- // we need to rely on other indicators or assume all purchases are subscriptions
2032
- // when called from getActiveSubscriptions
2033
- const purchases = allPurchases;
2034
-
2035
- // Filter for subscriptions and map to ActiveSubscription format
2036
- const subscriptions = purchases
2037
- .filter((purchase) => {
2038
- // Filter by subscription IDs if provided
2039
- if (subscriptionIds && subscriptionIds.length > 0) {
2040
- return subscriptionIds.includes(purchase.productId);
2041
- }
2042
- return true;
2043
- })
2044
- .map((purchase): ActiveSubscription => {
2045
- // Safe access to platform-specific fields with type guards
2046
- const expirationDateIOS =
2047
- 'expirationDateIOS' in purchase
2048
- ? ((purchase as PurchaseIOS).expirationDateIOS ?? null)
2049
- : null;
2050
-
2051
- const environmentIOS =
2052
- 'environmentIOS' in purchase
2053
- ? ((purchase as PurchaseIOS).environmentIOS ?? null)
2054
- : null;
2055
-
2056
- const autoRenewingAndroid =
2057
- 'autoRenewingAndroid' in purchase || 'isAutoRenewing' in purchase
2058
- ? ((purchase as PurchaseAndroid).autoRenewingAndroid ??
2059
- (purchase as PurchaseAndroid).isAutoRenewing) // deprecated - use isAutoRenewing instead
2060
- : null;
2061
-
2062
- // 🆕 Extract renewalInfoIOS if available
2063
- const renewalInfoIOS =
2064
- 'renewalInfoIOS' in purchase
2065
- ? ((purchase as PurchaseIOS).renewalInfoIOS ?? null)
2066
- : null;
2067
-
2068
- return {
2069
- productId: purchase.productId,
2070
- isActive: true, // If it's in availablePurchases, it's active
2071
- // Backend validation fields - use transactionId ?? id for proper field mapping
2072
- transactionId: purchase.transactionId ?? purchase.id,
2073
- purchaseToken: purchase.purchaseToken,
2074
- transactionDate: purchase.transactionDate,
2075
- // Platform-specific fields
2076
- expirationDateIOS,
2077
- autoRenewingAndroid,
2078
- environmentIOS,
2079
- renewalInfoIOS,
2080
- // Convenience fields
2081
- willExpireSoon: false, // Would need to calculate based on expiration date
2082
- daysUntilExpirationIOS:
2083
- expirationDateIOS != null
2084
- ? Math.ceil(
2085
- (expirationDateIOS - Date.now()) / (1000 * 60 * 60 * 24),
2086
- )
2087
- : null,
2088
- };
2089
- });
2090
-
2091
- return subscriptions;
2092
- } catch (error) {
2093
- RnIapConsole.error('Failed to get active subscriptions:', error);
2094
- const errorJson = parseErrorStringToJsonObj(error);
2095
- throw new Error(errorJson.message);
2096
- }
2097
- };
2098
-
2099
2026
  /**
2100
2027
  * Check if the user has any active subscriptions (OpenIAP compliant)
2101
2028
  * Returns true if the user has at least one active subscription, false otherwise.
@@ -2104,7 +2031,7 @@ export const getActiveSubscriptions_OLD: QueryField<
2104
2031
  * @param subscriptionIds - Optional array of subscription IDs to check
2105
2032
  * @returns Promise<boolean> - True if there are active subscriptions
2106
2033
  *
2107
- * @see {@link https://www.openiap.dev/docs/apis/has-active-subscriptions}
2034
+ * @see {@link https://openiap.dev/docs/apis/has-active-subscriptions}
2108
2035
  */
2109
2036
  export const hasActiveSubscriptions = async subscriptionIds => {
2110
2037
  try {
@@ -2208,7 +2135,7 @@ const normalizeProductQueryType = type => {
2208
2135
  * }
2209
2136
  * ```
2210
2137
  *
2211
- * @see {@link https://www.openiap.dev/docs/apis/android/check-alternative-billing-availability-android}
2138
+ * @see {@link https://openiap.dev/docs/apis/android/check-alternative-billing-availability-android}
2212
2139
  */
2213
2140
  export const checkAlternativeBillingAvailabilityAndroid = async () => {
2214
2141
  if (Platform.OS !== 'android') {
@@ -2245,7 +2172,7 @@ export const checkAlternativeBillingAvailabilityAndroid = async () => {
2245
2172
  * }
2246
2173
  * ```
2247
2174
  *
2248
- * @see {@link https://www.openiap.dev/docs/apis/android/show-alternative-billing-dialog-android}
2175
+ * @see {@link https://openiap.dev/docs/apis/android/show-alternative-billing-dialog-android}
2249
2176
  */
2250
2177
  export const showAlternativeBillingDialogAndroid = async () => {
2251
2178
  if (Platform.OS !== 'android') {
@@ -2282,7 +2209,7 @@ export const showAlternativeBillingDialogAndroid = async () => {
2282
2209
  * }
2283
2210
  * ```
2284
2211
  *
2285
- * @see {@link https://www.openiap.dev/docs/apis/android/create-alternative-billing-token-android}
2212
+ * @see {@link https://openiap.dev/docs/apis/android/create-alternative-billing-token-android}
2286
2213
  */
2287
2214
  export const createAlternativeBillingTokenAndroid = async sku => {
2288
2215
  if (Platform.OS !== 'android') {
@@ -2296,18 +2223,6 @@ export const createAlternativeBillingTokenAndroid = async sku => {
2296
2223
  }
2297
2224
  };
2298
2225
 
2299
- /**
2300
- * Parameters for launching an external link (Android 8.2.0+).
2301
- */
2302
-
2303
- /**
2304
- * Result of checking billing program availability (Android 8.2.0+).
2305
- */
2306
-
2307
- /**
2308
- * Reporting details for external transactions (Android 8.2.0+).
2309
- */
2310
-
2311
2226
  /**
2312
2227
  * Enable a billing program before initConnection (Android only).
2313
2228
  * Must be called BEFORE initConnection() to configure the BillingClient.
@@ -2351,7 +2266,7 @@ export const enableBillingProgramAndroid = program => {
2351
2266
  * }
2352
2267
  * ```
2353
2268
  *
2354
- * @see {@link https://www.openiap.dev/docs/apis/android/is-billing-program-available-android}
2269
+ * @see {@link https://openiap.dev/docs/apis/android/is-billing-program-available-android}
2355
2270
  */
2356
2271
  export const isBillingProgramAvailableAndroid = async program => {
2357
2272
  if (Platform.OS !== 'android') {
@@ -2388,7 +2303,7 @@ export const isBillingProgramAvailableAndroid = async program => {
2388
2303
  * });
2389
2304
  * ```
2390
2305
  *
2391
- * @see {@link https://www.openiap.dev/docs/apis/android/create-billing-program-reporting-details-android}
2306
+ * @see {@link https://openiap.dev/docs/apis/android/create-billing-program-reporting-details-android}
2392
2307
  */
2393
2308
  export const createBillingProgramReportingDetailsAndroid = async program => {
2394
2309
  if (Platform.OS !== 'android') {
@@ -2427,7 +2342,7 @@ export const createBillingProgramReportingDetailsAndroid = async program => {
2427
2342
  * }
2428
2343
  * ```
2429
2344
  *
2430
- * @see {@link https://www.openiap.dev/docs/apis/android/launch-external-link-android}
2345
+ * @see {@link https://openiap.dev/docs/apis/android/launch-external-link-android}
2431
2346
  */
2432
2347
  export const launchExternalLinkAndroid = async params => {
2433
2348
  if (Platform.OS !== 'android') {
@@ -2469,7 +2384,7 @@ export const launchExternalLinkAndroid = async params => {
2469
2384
  * }
2470
2385
  * ```
2471
2386
  *
2472
- * @see {@link https://www.openiap.dev/docs/apis/ios/can-present-external-purchase-notice-ios}
2387
+ * @see {@link https://openiap.dev/docs/apis/ios/can-present-external-purchase-notice-ios}
2473
2388
  */
2474
2389
  export const canPresentExternalPurchaseNoticeIOS = async () => {
2475
2390
  if (Platform.OS !== 'ios') {
@@ -2499,7 +2414,7 @@ export const canPresentExternalPurchaseNoticeIOS = async () => {
2499
2414
  * }
2500
2415
  * ```
2501
2416
  *
2502
- * @see {@link https://www.openiap.dev/docs/apis/ios/present-external-purchase-notice-sheet-ios}
2417
+ * @see {@link https://openiap.dev/docs/apis/ios/present-external-purchase-notice-sheet-ios}
2503
2418
  */
2504
2419
  export const presentExternalPurchaseNoticeSheetIOS = async () => {
2505
2420
  if (Platform.OS !== 'ios') {
@@ -2528,7 +2443,7 @@ export const presentExternalPurchaseNoticeSheetIOS = async () => {
2528
2443
  * }
2529
2444
  * ```
2530
2445
  *
2531
- * @see {@link https://www.openiap.dev/docs/apis/ios/present-external-purchase-link-ios}
2446
+ * @see {@link https://openiap.dev/docs/apis/ios/present-external-purchase-link-ios}
2532
2447
  */
2533
2448
  export const presentExternalPurchaseLinkIOS = async url => {
2534
2449
  if (Platform.OS !== 'ios') {
@@ -2562,7 +2477,7 @@ export const presentExternalPurchaseLinkIOS = async url => {
2562
2477
  * }
2563
2478
  * ```
2564
2479
  *
2565
- * @see {@link https://www.openiap.dev/docs/apis/ios/is-eligible-for-external-purchase-custom-link-ios}
2480
+ * @see {@link https://openiap.dev/docs/apis/ios/is-eligible-for-external-purchase-custom-link-ios}
2566
2481
  */
2567
2482
  export const isEligibleForExternalPurchaseCustomLinkIOS = async () => {
2568
2483
  if (Platform.OS !== 'ios') {
@@ -2595,7 +2510,7 @@ export const isEligibleForExternalPurchaseCustomLinkIOS = async () => {
2595
2510
  * }
2596
2511
  * ```
2597
2512
  *
2598
- * @see {@link https://www.openiap.dev/docs/apis/ios/get-external-purchase-custom-link-token-ios}
2513
+ * @see {@link https://openiap.dev/docs/apis/ios/get-external-purchase-custom-link-token-ios}
2599
2514
  */
2600
2515
  export const getExternalPurchaseCustomLinkTokenIOS = async tokenType => {
2601
2516
  if (Platform.OS !== 'ios') {
@@ -2628,7 +2543,7 @@ export const getExternalPurchaseCustomLinkTokenIOS = async tokenType => {
2628
2543
  * }
2629
2544
  * ```
2630
2545
  *
2631
- * @see {@link https://www.openiap.dev/docs/apis/ios/show-external-purchase-custom-link-notice-ios}
2546
+ * @see {@link https://openiap.dev/docs/apis/ios/show-external-purchase-custom-link-notice-ios}
2632
2547
  */
2633
2548
  export const showExternalPurchaseCustomLinkNoticeIOS = async noticeType => {
2634
2549
  if (Platform.OS !== 'ios') {