react-native-iap 14.0.1 → 14.1.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 (45) hide show
  1. package/android/src/main/java/com/margelo/nitro/iap/HybridRnIap.kt +81 -22
  2. package/ios/HybridRnIap.swift +151 -11
  3. package/ios/ProductStore.swift +10 -0
  4. package/lib/module/helpers/subscription.js +9 -1
  5. package/lib/module/helpers/subscription.js.map +1 -1
  6. package/lib/module/hooks/useIAP.js +9 -13
  7. package/lib/module/hooks/useIAP.js.map +1 -1
  8. package/lib/module/index.js +43 -28
  9. package/lib/module/index.js.map +1 -1
  10. package/lib/module/types.js +24 -16
  11. package/lib/module/types.js.map +1 -1
  12. package/lib/module/utils/type-bridge.js +64 -13
  13. package/lib/module/utils/type-bridge.js.map +1 -1
  14. package/lib/typescript/src/helpers/subscription.d.ts.map +1 -1
  15. package/lib/typescript/src/hooks/useIAP.d.ts.map +1 -1
  16. package/lib/typescript/src/index.d.ts +12 -22
  17. package/lib/typescript/src/index.d.ts.map +1 -1
  18. package/lib/typescript/src/specs/RnIap.nitro.d.ts +15 -11
  19. package/lib/typescript/src/specs/RnIap.nitro.d.ts.map +1 -1
  20. package/lib/typescript/src/types.d.ts +58 -58
  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/nitro.json +5 -1
  24. package/nitrogen/generated/android/c++/JHybridRnIapSpec.cpp +13 -4
  25. package/nitrogen/generated/android/c++/JHybridRnIapSpec.hpp +1 -1
  26. package/nitrogen/generated/android/c++/JNitroProduct.hpp +40 -36
  27. package/nitrogen/generated/android/c++/JNitroPurchase.hpp +12 -0
  28. package/nitrogen/generated/android/kotlin/com/margelo/nitro/iap/HybridRnIapSpec.kt +1 -1
  29. package/nitrogen/generated/android/kotlin/com/margelo/nitro/iap/NitroProduct.kt +12 -9
  30. package/nitrogen/generated/android/kotlin/com/margelo/nitro/iap/NitroPurchase.kt +9 -0
  31. package/nitrogen/generated/ios/c++/HybridRnIapSpecSwift.hpp +1 -1
  32. package/nitrogen/generated/ios/swift/HybridRnIapSpec.swift +1 -1
  33. package/nitrogen/generated/ios/swift/HybridRnIapSpec_cxx.swift +13 -7
  34. package/nitrogen/generated/ios/swift/NitroProduct.swift +73 -43
  35. package/nitrogen/generated/ios/swift/NitroPurchase.swift +35 -2
  36. package/nitrogen/generated/shared/c++/HybridRnIapSpec.hpp +1 -1
  37. package/nitrogen/generated/shared/c++/NitroProduct.hpp +41 -37
  38. package/nitrogen/generated/shared/c++/NitroPurchase.hpp +13 -1
  39. package/package.json +9 -2
  40. package/src/helpers/subscription.ts +13 -2
  41. package/src/hooks/useIAP.ts +8 -21
  42. package/src/index.ts +58 -38
  43. package/src/specs/RnIap.nitro.ts +15 -11
  44. package/src/types.ts +66 -62
  45. package/src/utils/type-bridge.ts +80 -16
@@ -106,7 +106,7 @@ namespace margelo::nitro::iap {
106
106
  virtual std::shared_ptr<Promise<std::optional<NitroPurchase>>> latestTransactionIOS(const std::string& sku) = 0;
107
107
  virtual std::shared_ptr<Promise<std::vector<NitroPurchase>>> getPendingTransactionsIOS() = 0;
108
108
  virtual std::shared_ptr<Promise<bool>> syncIOS() = 0;
109
- virtual std::shared_ptr<Promise<bool>> showManageSubscriptionsIOS() = 0;
109
+ virtual std::shared_ptr<Promise<std::vector<NitroPurchase>>> showManageSubscriptionsIOS() = 0;
110
110
  virtual std::shared_ptr<Promise<bool>> isEligibleForIntroOfferIOS(const std::string& groupID) = 0;
111
111
  virtual std::shared_ptr<Promise<std::string>> getReceiptDataIOS() = 0;
112
112
  virtual std::shared_ptr<Promise<bool>> isTransactionVerifiedIOS(const std::string& sku) = 0;
@@ -39,8 +39,9 @@ namespace margelo::nitro::iap {
39
39
  std::optional<std::string> currency SWIFT_PRIVATE;
40
40
  std::optional<double> price SWIFT_PRIVATE;
41
41
  std::string platform SWIFT_PRIVATE;
42
- std::optional<bool> isFamilyShareable SWIFT_PRIVATE;
43
- std::optional<std::string> jsonRepresentation SWIFT_PRIVATE;
42
+ std::optional<std::string> typeIOS SWIFT_PRIVATE;
43
+ std::optional<bool> isFamilyShareableIOS SWIFT_PRIVATE;
44
+ std::optional<std::string> jsonRepresentationIOS SWIFT_PRIVATE;
44
45
  std::optional<std::string> subscriptionPeriodUnitIOS SWIFT_PRIVATE;
45
46
  std::optional<double> subscriptionPeriodNumberIOS SWIFT_PRIVATE;
46
47
  std::optional<std::string> introductoryPriceIOS SWIFT_PRIVATE;
@@ -48,18 +49,18 @@ namespace margelo::nitro::iap {
48
49
  std::optional<std::string> introductoryPricePaymentModeIOS SWIFT_PRIVATE;
49
50
  std::optional<double> introductoryPriceNumberOfPeriodsIOS SWIFT_PRIVATE;
50
51
  std::optional<std::string> introductoryPriceSubscriptionPeriodIOS SWIFT_PRIVATE;
51
- std::optional<std::string> originalPrice SWIFT_PRIVATE;
52
- std::optional<double> originalPriceAmountMicros SWIFT_PRIVATE;
53
- std::optional<double> introductoryPriceValue SWIFT_PRIVATE;
54
- std::optional<double> introductoryPriceCycles SWIFT_PRIVATE;
55
- std::optional<std::string> introductoryPricePeriod SWIFT_PRIVATE;
56
- std::optional<std::string> subscriptionPeriod SWIFT_PRIVATE;
57
- std::optional<std::string> freeTrialPeriod SWIFT_PRIVATE;
52
+ std::optional<std::string> originalPriceAndroid SWIFT_PRIVATE;
53
+ std::optional<double> originalPriceAmountMicrosAndroid SWIFT_PRIVATE;
54
+ std::optional<double> introductoryPriceValueAndroid SWIFT_PRIVATE;
55
+ std::optional<double> introductoryPriceCyclesAndroid SWIFT_PRIVATE;
56
+ std::optional<std::string> introductoryPricePeriodAndroid SWIFT_PRIVATE;
57
+ std::optional<std::string> subscriptionPeriodAndroid SWIFT_PRIVATE;
58
+ std::optional<std::string> freeTrialPeriodAndroid SWIFT_PRIVATE;
58
59
  std::optional<std::string> subscriptionOfferDetailsAndroid SWIFT_PRIVATE;
59
60
 
60
61
  public:
61
62
  NitroProduct() = default;
62
- explicit NitroProduct(std::string id, std::string title, std::string description, std::string type, std::optional<std::string> displayName, std::optional<std::string> displayPrice, std::optional<std::string> currency, std::optional<double> price, std::string platform, std::optional<bool> isFamilyShareable, std::optional<std::string> jsonRepresentation, std::optional<std::string> subscriptionPeriodUnitIOS, std::optional<double> subscriptionPeriodNumberIOS, std::optional<std::string> introductoryPriceIOS, std::optional<double> introductoryPriceAsAmountIOS, std::optional<std::string> introductoryPricePaymentModeIOS, std::optional<double> introductoryPriceNumberOfPeriodsIOS, std::optional<std::string> introductoryPriceSubscriptionPeriodIOS, std::optional<std::string> originalPrice, std::optional<double> originalPriceAmountMicros, std::optional<double> introductoryPriceValue, std::optional<double> introductoryPriceCycles, std::optional<std::string> introductoryPricePeriod, std::optional<std::string> subscriptionPeriod, std::optional<std::string> freeTrialPeriod, std::optional<std::string> subscriptionOfferDetailsAndroid): id(id), title(title), description(description), type(type), displayName(displayName), displayPrice(displayPrice), currency(currency), price(price), platform(platform), isFamilyShareable(isFamilyShareable), jsonRepresentation(jsonRepresentation), subscriptionPeriodUnitIOS(subscriptionPeriodUnitIOS), subscriptionPeriodNumberIOS(subscriptionPeriodNumberIOS), introductoryPriceIOS(introductoryPriceIOS), introductoryPriceAsAmountIOS(introductoryPriceAsAmountIOS), introductoryPricePaymentModeIOS(introductoryPricePaymentModeIOS), introductoryPriceNumberOfPeriodsIOS(introductoryPriceNumberOfPeriodsIOS), introductoryPriceSubscriptionPeriodIOS(introductoryPriceSubscriptionPeriodIOS), originalPrice(originalPrice), originalPriceAmountMicros(originalPriceAmountMicros), introductoryPriceValue(introductoryPriceValue), introductoryPriceCycles(introductoryPriceCycles), introductoryPricePeriod(introductoryPricePeriod), subscriptionPeriod(subscriptionPeriod), freeTrialPeriod(freeTrialPeriod), subscriptionOfferDetailsAndroid(subscriptionOfferDetailsAndroid) {}
63
+ explicit NitroProduct(std::string id, std::string title, std::string description, std::string type, std::optional<std::string> displayName, std::optional<std::string> displayPrice, std::optional<std::string> currency, std::optional<double> price, std::string platform, std::optional<std::string> typeIOS, std::optional<bool> isFamilyShareableIOS, std::optional<std::string> jsonRepresentationIOS, std::optional<std::string> subscriptionPeriodUnitIOS, std::optional<double> subscriptionPeriodNumberIOS, std::optional<std::string> introductoryPriceIOS, std::optional<double> introductoryPriceAsAmountIOS, std::optional<std::string> introductoryPricePaymentModeIOS, std::optional<double> introductoryPriceNumberOfPeriodsIOS, std::optional<std::string> introductoryPriceSubscriptionPeriodIOS, std::optional<std::string> originalPriceAndroid, std::optional<double> originalPriceAmountMicrosAndroid, std::optional<double> introductoryPriceValueAndroid, std::optional<double> introductoryPriceCyclesAndroid, std::optional<std::string> introductoryPricePeriodAndroid, std::optional<std::string> subscriptionPeriodAndroid, std::optional<std::string> freeTrialPeriodAndroid, std::optional<std::string> subscriptionOfferDetailsAndroid): id(id), title(title), description(description), type(type), displayName(displayName), displayPrice(displayPrice), currency(currency), price(price), platform(platform), typeIOS(typeIOS), isFamilyShareableIOS(isFamilyShareableIOS), jsonRepresentationIOS(jsonRepresentationIOS), subscriptionPeriodUnitIOS(subscriptionPeriodUnitIOS), subscriptionPeriodNumberIOS(subscriptionPeriodNumberIOS), introductoryPriceIOS(introductoryPriceIOS), introductoryPriceAsAmountIOS(introductoryPriceAsAmountIOS), introductoryPricePaymentModeIOS(introductoryPricePaymentModeIOS), introductoryPriceNumberOfPeriodsIOS(introductoryPriceNumberOfPeriodsIOS), introductoryPriceSubscriptionPeriodIOS(introductoryPriceSubscriptionPeriodIOS), originalPriceAndroid(originalPriceAndroid), originalPriceAmountMicrosAndroid(originalPriceAmountMicrosAndroid), introductoryPriceValueAndroid(introductoryPriceValueAndroid), introductoryPriceCyclesAndroid(introductoryPriceCyclesAndroid), introductoryPricePeriodAndroid(introductoryPricePeriodAndroid), subscriptionPeriodAndroid(subscriptionPeriodAndroid), freeTrialPeriodAndroid(freeTrialPeriodAndroid), subscriptionOfferDetailsAndroid(subscriptionOfferDetailsAndroid) {}
63
64
  };
64
65
 
65
66
  } // namespace margelo::nitro::iap
@@ -81,8 +82,9 @@ namespace margelo::nitro {
81
82
  JSIConverter<std::optional<std::string>>::fromJSI(runtime, obj.getProperty(runtime, "currency")),
82
83
  JSIConverter<std::optional<double>>::fromJSI(runtime, obj.getProperty(runtime, "price")),
83
84
  JSIConverter<std::string>::fromJSI(runtime, obj.getProperty(runtime, "platform")),
84
- JSIConverter<std::optional<bool>>::fromJSI(runtime, obj.getProperty(runtime, "isFamilyShareable")),
85
- JSIConverter<std::optional<std::string>>::fromJSI(runtime, obj.getProperty(runtime, "jsonRepresentation")),
85
+ JSIConverter<std::optional<std::string>>::fromJSI(runtime, obj.getProperty(runtime, "typeIOS")),
86
+ JSIConverter<std::optional<bool>>::fromJSI(runtime, obj.getProperty(runtime, "isFamilyShareableIOS")),
87
+ JSIConverter<std::optional<std::string>>::fromJSI(runtime, obj.getProperty(runtime, "jsonRepresentationIOS")),
86
88
  JSIConverter<std::optional<std::string>>::fromJSI(runtime, obj.getProperty(runtime, "subscriptionPeriodUnitIOS")),
87
89
  JSIConverter<std::optional<double>>::fromJSI(runtime, obj.getProperty(runtime, "subscriptionPeriodNumberIOS")),
88
90
  JSIConverter<std::optional<std::string>>::fromJSI(runtime, obj.getProperty(runtime, "introductoryPriceIOS")),
@@ -90,13 +92,13 @@ namespace margelo::nitro {
90
92
  JSIConverter<std::optional<std::string>>::fromJSI(runtime, obj.getProperty(runtime, "introductoryPricePaymentModeIOS")),
91
93
  JSIConverter<std::optional<double>>::fromJSI(runtime, obj.getProperty(runtime, "introductoryPriceNumberOfPeriodsIOS")),
92
94
  JSIConverter<std::optional<std::string>>::fromJSI(runtime, obj.getProperty(runtime, "introductoryPriceSubscriptionPeriodIOS")),
93
- JSIConverter<std::optional<std::string>>::fromJSI(runtime, obj.getProperty(runtime, "originalPrice")),
94
- JSIConverter<std::optional<double>>::fromJSI(runtime, obj.getProperty(runtime, "originalPriceAmountMicros")),
95
- JSIConverter<std::optional<double>>::fromJSI(runtime, obj.getProperty(runtime, "introductoryPriceValue")),
96
- JSIConverter<std::optional<double>>::fromJSI(runtime, obj.getProperty(runtime, "introductoryPriceCycles")),
97
- JSIConverter<std::optional<std::string>>::fromJSI(runtime, obj.getProperty(runtime, "introductoryPricePeriod")),
98
- JSIConverter<std::optional<std::string>>::fromJSI(runtime, obj.getProperty(runtime, "subscriptionPeriod")),
99
- JSIConverter<std::optional<std::string>>::fromJSI(runtime, obj.getProperty(runtime, "freeTrialPeriod")),
95
+ JSIConverter<std::optional<std::string>>::fromJSI(runtime, obj.getProperty(runtime, "originalPriceAndroid")),
96
+ JSIConverter<std::optional<double>>::fromJSI(runtime, obj.getProperty(runtime, "originalPriceAmountMicrosAndroid")),
97
+ JSIConverter<std::optional<double>>::fromJSI(runtime, obj.getProperty(runtime, "introductoryPriceValueAndroid")),
98
+ JSIConverter<std::optional<double>>::fromJSI(runtime, obj.getProperty(runtime, "introductoryPriceCyclesAndroid")),
99
+ JSIConverter<std::optional<std::string>>::fromJSI(runtime, obj.getProperty(runtime, "introductoryPricePeriodAndroid")),
100
+ JSIConverter<std::optional<std::string>>::fromJSI(runtime, obj.getProperty(runtime, "subscriptionPeriodAndroid")),
101
+ JSIConverter<std::optional<std::string>>::fromJSI(runtime, obj.getProperty(runtime, "freeTrialPeriodAndroid")),
100
102
  JSIConverter<std::optional<std::string>>::fromJSI(runtime, obj.getProperty(runtime, "subscriptionOfferDetailsAndroid"))
101
103
  );
102
104
  }
@@ -111,8 +113,9 @@ namespace margelo::nitro {
111
113
  obj.setProperty(runtime, "currency", JSIConverter<std::optional<std::string>>::toJSI(runtime, arg.currency));
112
114
  obj.setProperty(runtime, "price", JSIConverter<std::optional<double>>::toJSI(runtime, arg.price));
113
115
  obj.setProperty(runtime, "platform", JSIConverter<std::string>::toJSI(runtime, arg.platform));
114
- obj.setProperty(runtime, "isFamilyShareable", JSIConverter<std::optional<bool>>::toJSI(runtime, arg.isFamilyShareable));
115
- obj.setProperty(runtime, "jsonRepresentation", JSIConverter<std::optional<std::string>>::toJSI(runtime, arg.jsonRepresentation));
116
+ obj.setProperty(runtime, "typeIOS", JSIConverter<std::optional<std::string>>::toJSI(runtime, arg.typeIOS));
117
+ obj.setProperty(runtime, "isFamilyShareableIOS", JSIConverter<std::optional<bool>>::toJSI(runtime, arg.isFamilyShareableIOS));
118
+ obj.setProperty(runtime, "jsonRepresentationIOS", JSIConverter<std::optional<std::string>>::toJSI(runtime, arg.jsonRepresentationIOS));
116
119
  obj.setProperty(runtime, "subscriptionPeriodUnitIOS", JSIConverter<std::optional<std::string>>::toJSI(runtime, arg.subscriptionPeriodUnitIOS));
117
120
  obj.setProperty(runtime, "subscriptionPeriodNumberIOS", JSIConverter<std::optional<double>>::toJSI(runtime, arg.subscriptionPeriodNumberIOS));
118
121
  obj.setProperty(runtime, "introductoryPriceIOS", JSIConverter<std::optional<std::string>>::toJSI(runtime, arg.introductoryPriceIOS));
@@ -120,13 +123,13 @@ namespace margelo::nitro {
120
123
  obj.setProperty(runtime, "introductoryPricePaymentModeIOS", JSIConverter<std::optional<std::string>>::toJSI(runtime, arg.introductoryPricePaymentModeIOS));
121
124
  obj.setProperty(runtime, "introductoryPriceNumberOfPeriodsIOS", JSIConverter<std::optional<double>>::toJSI(runtime, arg.introductoryPriceNumberOfPeriodsIOS));
122
125
  obj.setProperty(runtime, "introductoryPriceSubscriptionPeriodIOS", JSIConverter<std::optional<std::string>>::toJSI(runtime, arg.introductoryPriceSubscriptionPeriodIOS));
123
- obj.setProperty(runtime, "originalPrice", JSIConverter<std::optional<std::string>>::toJSI(runtime, arg.originalPrice));
124
- obj.setProperty(runtime, "originalPriceAmountMicros", JSIConverter<std::optional<double>>::toJSI(runtime, arg.originalPriceAmountMicros));
125
- obj.setProperty(runtime, "introductoryPriceValue", JSIConverter<std::optional<double>>::toJSI(runtime, arg.introductoryPriceValue));
126
- obj.setProperty(runtime, "introductoryPriceCycles", JSIConverter<std::optional<double>>::toJSI(runtime, arg.introductoryPriceCycles));
127
- obj.setProperty(runtime, "introductoryPricePeriod", JSIConverter<std::optional<std::string>>::toJSI(runtime, arg.introductoryPricePeriod));
128
- obj.setProperty(runtime, "subscriptionPeriod", JSIConverter<std::optional<std::string>>::toJSI(runtime, arg.subscriptionPeriod));
129
- obj.setProperty(runtime, "freeTrialPeriod", JSIConverter<std::optional<std::string>>::toJSI(runtime, arg.freeTrialPeriod));
126
+ obj.setProperty(runtime, "originalPriceAndroid", JSIConverter<std::optional<std::string>>::toJSI(runtime, arg.originalPriceAndroid));
127
+ obj.setProperty(runtime, "originalPriceAmountMicrosAndroid", JSIConverter<std::optional<double>>::toJSI(runtime, arg.originalPriceAmountMicrosAndroid));
128
+ obj.setProperty(runtime, "introductoryPriceValueAndroid", JSIConverter<std::optional<double>>::toJSI(runtime, arg.introductoryPriceValueAndroid));
129
+ obj.setProperty(runtime, "introductoryPriceCyclesAndroid", JSIConverter<std::optional<double>>::toJSI(runtime, arg.introductoryPriceCyclesAndroid));
130
+ obj.setProperty(runtime, "introductoryPricePeriodAndroid", JSIConverter<std::optional<std::string>>::toJSI(runtime, arg.introductoryPricePeriodAndroid));
131
+ obj.setProperty(runtime, "subscriptionPeriodAndroid", JSIConverter<std::optional<std::string>>::toJSI(runtime, arg.subscriptionPeriodAndroid));
132
+ obj.setProperty(runtime, "freeTrialPeriodAndroid", JSIConverter<std::optional<std::string>>::toJSI(runtime, arg.freeTrialPeriodAndroid));
130
133
  obj.setProperty(runtime, "subscriptionOfferDetailsAndroid", JSIConverter<std::optional<std::string>>::toJSI(runtime, arg.subscriptionOfferDetailsAndroid));
131
134
  return obj;
132
135
  }
@@ -144,8 +147,9 @@ namespace margelo::nitro {
144
147
  if (!JSIConverter<std::optional<std::string>>::canConvert(runtime, obj.getProperty(runtime, "currency"))) return false;
145
148
  if (!JSIConverter<std::optional<double>>::canConvert(runtime, obj.getProperty(runtime, "price"))) return false;
146
149
  if (!JSIConverter<std::string>::canConvert(runtime, obj.getProperty(runtime, "platform"))) return false;
147
- if (!JSIConverter<std::optional<bool>>::canConvert(runtime, obj.getProperty(runtime, "isFamilyShareable"))) return false;
148
- if (!JSIConverter<std::optional<std::string>>::canConvert(runtime, obj.getProperty(runtime, "jsonRepresentation"))) return false;
150
+ if (!JSIConverter<std::optional<std::string>>::canConvert(runtime, obj.getProperty(runtime, "typeIOS"))) return false;
151
+ if (!JSIConverter<std::optional<bool>>::canConvert(runtime, obj.getProperty(runtime, "isFamilyShareableIOS"))) return false;
152
+ if (!JSIConverter<std::optional<std::string>>::canConvert(runtime, obj.getProperty(runtime, "jsonRepresentationIOS"))) return false;
149
153
  if (!JSIConverter<std::optional<std::string>>::canConvert(runtime, obj.getProperty(runtime, "subscriptionPeriodUnitIOS"))) return false;
150
154
  if (!JSIConverter<std::optional<double>>::canConvert(runtime, obj.getProperty(runtime, "subscriptionPeriodNumberIOS"))) return false;
151
155
  if (!JSIConverter<std::optional<std::string>>::canConvert(runtime, obj.getProperty(runtime, "introductoryPriceIOS"))) return false;
@@ -153,13 +157,13 @@ namespace margelo::nitro {
153
157
  if (!JSIConverter<std::optional<std::string>>::canConvert(runtime, obj.getProperty(runtime, "introductoryPricePaymentModeIOS"))) return false;
154
158
  if (!JSIConverter<std::optional<double>>::canConvert(runtime, obj.getProperty(runtime, "introductoryPriceNumberOfPeriodsIOS"))) return false;
155
159
  if (!JSIConverter<std::optional<std::string>>::canConvert(runtime, obj.getProperty(runtime, "introductoryPriceSubscriptionPeriodIOS"))) return false;
156
- if (!JSIConverter<std::optional<std::string>>::canConvert(runtime, obj.getProperty(runtime, "originalPrice"))) return false;
157
- if (!JSIConverter<std::optional<double>>::canConvert(runtime, obj.getProperty(runtime, "originalPriceAmountMicros"))) return false;
158
- if (!JSIConverter<std::optional<double>>::canConvert(runtime, obj.getProperty(runtime, "introductoryPriceValue"))) return false;
159
- if (!JSIConverter<std::optional<double>>::canConvert(runtime, obj.getProperty(runtime, "introductoryPriceCycles"))) return false;
160
- if (!JSIConverter<std::optional<std::string>>::canConvert(runtime, obj.getProperty(runtime, "introductoryPricePeriod"))) return false;
161
- if (!JSIConverter<std::optional<std::string>>::canConvert(runtime, obj.getProperty(runtime, "subscriptionPeriod"))) return false;
162
- if (!JSIConverter<std::optional<std::string>>::canConvert(runtime, obj.getProperty(runtime, "freeTrialPeriod"))) return false;
160
+ if (!JSIConverter<std::optional<std::string>>::canConvert(runtime, obj.getProperty(runtime, "originalPriceAndroid"))) return false;
161
+ if (!JSIConverter<std::optional<double>>::canConvert(runtime, obj.getProperty(runtime, "originalPriceAmountMicrosAndroid"))) return false;
162
+ if (!JSIConverter<std::optional<double>>::canConvert(runtime, obj.getProperty(runtime, "introductoryPriceValueAndroid"))) return false;
163
+ if (!JSIConverter<std::optional<double>>::canConvert(runtime, obj.getProperty(runtime, "introductoryPriceCyclesAndroid"))) return false;
164
+ if (!JSIConverter<std::optional<std::string>>::canConvert(runtime, obj.getProperty(runtime, "introductoryPricePeriodAndroid"))) return false;
165
+ if (!JSIConverter<std::optional<std::string>>::canConvert(runtime, obj.getProperty(runtime, "subscriptionPeriodAndroid"))) return false;
166
+ if (!JSIConverter<std::optional<std::string>>::canConvert(runtime, obj.getProperty(runtime, "freeTrialPeriodAndroid"))) return false;
163
167
  if (!JSIConverter<std::optional<std::string>>::canConvert(runtime, obj.getProperty(runtime, "subscriptionOfferDetailsAndroid"))) return false;
164
168
  return true;
165
169
  }
@@ -35,6 +35,9 @@ namespace margelo::nitro::iap {
35
35
  double transactionDate SWIFT_PRIVATE;
36
36
  std::optional<std::string> purchaseToken SWIFT_PRIVATE;
37
37
  std::string platform SWIFT_PRIVATE;
38
+ double quantity SWIFT_PRIVATE;
39
+ std::string purchaseState SWIFT_PRIVATE;
40
+ bool isAutoRenewing SWIFT_PRIVATE;
38
41
  std::optional<double> quantityIOS SWIFT_PRIVATE;
39
42
  std::optional<double> originalTransactionDateIOS SWIFT_PRIVATE;
40
43
  std::optional<std::string> originalTransactionIdentifierIOS SWIFT_PRIVATE;
@@ -51,7 +54,7 @@ namespace margelo::nitro::iap {
51
54
 
52
55
  public:
53
56
  NitroPurchase() = default;
54
- explicit NitroPurchase(std::string id, std::string productId, double transactionDate, std::optional<std::string> purchaseToken, std::string platform, std::optional<double> quantityIOS, std::optional<double> originalTransactionDateIOS, std::optional<std::string> originalTransactionIdentifierIOS, std::optional<std::string> appAccountToken, std::optional<std::string> purchaseTokenAndroid, std::optional<std::string> dataAndroid, std::optional<std::string> signatureAndroid, std::optional<bool> autoRenewingAndroid, std::optional<double> purchaseStateAndroid, std::optional<bool> isAcknowledgedAndroid, std::optional<std::string> packageNameAndroid, std::optional<std::string> obfuscatedAccountIdAndroid, std::optional<std::string> obfuscatedProfileIdAndroid): id(id), productId(productId), transactionDate(transactionDate), purchaseToken(purchaseToken), platform(platform), quantityIOS(quantityIOS), originalTransactionDateIOS(originalTransactionDateIOS), originalTransactionIdentifierIOS(originalTransactionIdentifierIOS), appAccountToken(appAccountToken), purchaseTokenAndroid(purchaseTokenAndroid), dataAndroid(dataAndroid), signatureAndroid(signatureAndroid), autoRenewingAndroid(autoRenewingAndroid), purchaseStateAndroid(purchaseStateAndroid), isAcknowledgedAndroid(isAcknowledgedAndroid), packageNameAndroid(packageNameAndroid), obfuscatedAccountIdAndroid(obfuscatedAccountIdAndroid), obfuscatedProfileIdAndroid(obfuscatedProfileIdAndroid) {}
57
+ explicit NitroPurchase(std::string id, std::string productId, double transactionDate, std::optional<std::string> purchaseToken, std::string platform, double quantity, std::string purchaseState, bool isAutoRenewing, std::optional<double> quantityIOS, std::optional<double> originalTransactionDateIOS, std::optional<std::string> originalTransactionIdentifierIOS, std::optional<std::string> appAccountToken, std::optional<std::string> purchaseTokenAndroid, std::optional<std::string> dataAndroid, std::optional<std::string> signatureAndroid, std::optional<bool> autoRenewingAndroid, std::optional<double> purchaseStateAndroid, std::optional<bool> isAcknowledgedAndroid, std::optional<std::string> packageNameAndroid, std::optional<std::string> obfuscatedAccountIdAndroid, std::optional<std::string> obfuscatedProfileIdAndroid): id(id), productId(productId), transactionDate(transactionDate), purchaseToken(purchaseToken), platform(platform), quantity(quantity), purchaseState(purchaseState), isAutoRenewing(isAutoRenewing), quantityIOS(quantityIOS), originalTransactionDateIOS(originalTransactionDateIOS), originalTransactionIdentifierIOS(originalTransactionIdentifierIOS), appAccountToken(appAccountToken), purchaseTokenAndroid(purchaseTokenAndroid), dataAndroid(dataAndroid), signatureAndroid(signatureAndroid), autoRenewingAndroid(autoRenewingAndroid), purchaseStateAndroid(purchaseStateAndroid), isAcknowledgedAndroid(isAcknowledgedAndroid), packageNameAndroid(packageNameAndroid), obfuscatedAccountIdAndroid(obfuscatedAccountIdAndroid), obfuscatedProfileIdAndroid(obfuscatedProfileIdAndroid) {}
55
58
  };
56
59
 
57
60
  } // namespace margelo::nitro::iap
@@ -69,6 +72,9 @@ namespace margelo::nitro {
69
72
  JSIConverter<double>::fromJSI(runtime, obj.getProperty(runtime, "transactionDate")),
70
73
  JSIConverter<std::optional<std::string>>::fromJSI(runtime, obj.getProperty(runtime, "purchaseToken")),
71
74
  JSIConverter<std::string>::fromJSI(runtime, obj.getProperty(runtime, "platform")),
75
+ JSIConverter<double>::fromJSI(runtime, obj.getProperty(runtime, "quantity")),
76
+ JSIConverter<std::string>::fromJSI(runtime, obj.getProperty(runtime, "purchaseState")),
77
+ JSIConverter<bool>::fromJSI(runtime, obj.getProperty(runtime, "isAutoRenewing")),
72
78
  JSIConverter<std::optional<double>>::fromJSI(runtime, obj.getProperty(runtime, "quantityIOS")),
73
79
  JSIConverter<std::optional<double>>::fromJSI(runtime, obj.getProperty(runtime, "originalTransactionDateIOS")),
74
80
  JSIConverter<std::optional<std::string>>::fromJSI(runtime, obj.getProperty(runtime, "originalTransactionIdentifierIOS")),
@@ -91,6 +97,9 @@ namespace margelo::nitro {
91
97
  obj.setProperty(runtime, "transactionDate", JSIConverter<double>::toJSI(runtime, arg.transactionDate));
92
98
  obj.setProperty(runtime, "purchaseToken", JSIConverter<std::optional<std::string>>::toJSI(runtime, arg.purchaseToken));
93
99
  obj.setProperty(runtime, "platform", JSIConverter<std::string>::toJSI(runtime, arg.platform));
100
+ obj.setProperty(runtime, "quantity", JSIConverter<double>::toJSI(runtime, arg.quantity));
101
+ obj.setProperty(runtime, "purchaseState", JSIConverter<std::string>::toJSI(runtime, arg.purchaseState));
102
+ obj.setProperty(runtime, "isAutoRenewing", JSIConverter<bool>::toJSI(runtime, arg.isAutoRenewing));
94
103
  obj.setProperty(runtime, "quantityIOS", JSIConverter<std::optional<double>>::toJSI(runtime, arg.quantityIOS));
95
104
  obj.setProperty(runtime, "originalTransactionDateIOS", JSIConverter<std::optional<double>>::toJSI(runtime, arg.originalTransactionDateIOS));
96
105
  obj.setProperty(runtime, "originalTransactionIdentifierIOS", JSIConverter<std::optional<std::string>>::toJSI(runtime, arg.originalTransactionIdentifierIOS));
@@ -116,6 +125,9 @@ namespace margelo::nitro {
116
125
  if (!JSIConverter<double>::canConvert(runtime, obj.getProperty(runtime, "transactionDate"))) return false;
117
126
  if (!JSIConverter<std::optional<std::string>>::canConvert(runtime, obj.getProperty(runtime, "purchaseToken"))) return false;
118
127
  if (!JSIConverter<std::string>::canConvert(runtime, obj.getProperty(runtime, "platform"))) return false;
128
+ if (!JSIConverter<double>::canConvert(runtime, obj.getProperty(runtime, "quantity"))) return false;
129
+ if (!JSIConverter<std::string>::canConvert(runtime, obj.getProperty(runtime, "purchaseState"))) return false;
130
+ if (!JSIConverter<bool>::canConvert(runtime, obj.getProperty(runtime, "isAutoRenewing"))) return false;
119
131
  if (!JSIConverter<std::optional<double>>::canConvert(runtime, obj.getProperty(runtime, "quantityIOS"))) return false;
120
132
  if (!JSIConverter<std::optional<double>>::canConvert(runtime, obj.getProperty(runtime, "originalTransactionDateIOS"))) return false;
121
133
  if (!JSIConverter<std::optional<std::string>>::canConvert(runtime, obj.getProperty(runtime, "originalTransactionIdentifierIOS"))) return false;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "react-native-iap",
3
- "version": "14.0.1",
3
+ "version": "14.1.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",
@@ -57,9 +57,13 @@
57
57
  "prepare": "npx tsx scripts/check-nitro-versions.ts && bob build && yarn nitrogen && yarn build:plugin",
58
58
  "nitrogen": "nitro-codegen",
59
59
  "specs": "nitro-codegen --logLevel=\"debug\"",
60
- "test": "yarn workspace rn-iap-example test",
60
+ "test": "jest --coverage",
61
+ "test:library": "jest --coverage",
62
+ "test:example": "yarn workspace rn-iap-example test --coverage",
61
63
  "test:plugin": "cd example-expo/plugin && bun test",
64
+ "test:all": "yarn test:library && yarn test:example",
62
65
  "test:ci": "jest --maxWorkers=2 --coverage",
66
+ "test:ci:example": "yarn workspace rn-iap-example test --coverage",
63
67
  "prepare:husky": "husky install",
64
68
  "precommit": "lint-staged",
65
69
  "ci:check": "./scripts/ci-check.sh",
@@ -85,6 +89,8 @@
85
89
  "devDependencies": {
86
90
  "@babel/plugin-proposal-private-methods": "^7.18.6",
87
91
  "@react-native/eslint-config": "0.81.0",
92
+ "@testing-library/react": "^16.3.0",
93
+ "@testing-library/react-hooks": "^8.0.1",
88
94
  "@types/jest": "^29.5.12",
89
95
  "@types/react": "^19.1.12",
90
96
  "babel-jest": "^30.1.1",
@@ -102,6 +108,7 @@
102
108
  "react-native": "0.81.1",
103
109
  "react-native-builder-bob": "^0.38.4",
104
110
  "react-native-nitro-modules": "^0.29.2",
111
+ "react-test-renderer": "^19.1.1",
105
112
  "typescript": "^5.9.2"
106
113
  },
107
114
  "peerDependencies": {
@@ -24,15 +24,26 @@ export const getActiveSubscriptions = async (
24
24
  })
25
25
  .map((purchase): ActiveSubscription => {
26
26
  const iosPurchase = purchase as PurchaseIOS
27
+ const androidPurchase = purchase as PurchaseAndroid
27
28
  return {
28
29
  productId: purchase.productId,
29
30
  isActive: true, // If it's in availablePurchases, it's active
31
+ // Backend validation fields
32
+ transactionId: purchase.transactionId || purchase.id,
33
+ purchaseToken:
34
+ androidPurchase.purchaseToken ||
35
+ androidPurchase.purchaseTokenAndroid ||
36
+ iosPurchase.purchaseToken,
37
+ transactionDate: purchase.transactionDate,
38
+ // Platform-specific fields
30
39
  expirationDateIOS: iosPurchase.expirationDateIOS
31
40
  ? new Date(iosPurchase.expirationDateIOS)
32
41
  : undefined,
33
- autoRenewingAndroid: (purchase as PurchaseAndroid)
34
- .autoRenewingAndroid,
42
+ autoRenewingAndroid:
43
+ androidPurchase.autoRenewingAndroid ??
44
+ androidPurchase.isAutoRenewing, // deprecated - use isAutoRenewing instead
35
45
  environmentIOS: iosPurchase.environmentIOS,
46
+ // Convenience fields
36
47
  willExpireSoon: false, // Would need to calculate based on expiration date
37
48
  daysUntilExpirationIOS: iosPurchase.expirationDateIOS
38
49
  ? Math.ceil(
@@ -318,24 +318,6 @@ export function useIAP(options?: UseIapOptions): UseIap {
318
318
  [clearCurrentPurchase, clearCurrentPurchaseError]
319
319
  )
320
320
 
321
- const refreshSubscriptionStatus = useCallback(
322
- async (productId: string) => {
323
- try {
324
- if (
325
- subscriptionsRefState.current.some(
326
- (sub: SubscriptionProduct) => sub.id === productId
327
- )
328
- ) {
329
- await getSubscriptionsInternal([productId])
330
- await getAvailablePurchasesInternal()
331
- }
332
- } catch (error) {
333
- console.warn('Failed to refresh subscription status:', error)
334
- }
335
- },
336
- [getAvailablePurchasesInternal, getSubscriptionsInternal]
337
- )
338
-
339
321
  const restorePurchases = useCallback(async (): Promise<void> => {
340
322
  try {
341
323
  if (Platform.OS === 'ios') {
@@ -378,8 +360,13 @@ export function useIAP(options?: UseIapOptions): UseIap {
378
360
  setCurrentPurchaseError(undefined)
379
361
  setCurrentPurchase(purchase)
380
362
 
381
- if ('expirationDateIOS' in purchase) {
382
- await refreshSubscriptionStatus(purchase.id)
363
+ // Always refresh subscription state after a purchase event
364
+ try {
365
+ await getActiveSubscriptionsInternal()
366
+ await getAvailablePurchasesInternal()
367
+ } catch (e) {
368
+ // Non-fatal: UI will still update from event data
369
+ console.warn('[useIAP] post-purchase refresh failed:', e)
383
370
  }
384
371
 
385
372
  if (optionsRef.current?.onPurchaseSuccess) {
@@ -411,7 +398,7 @@ export function useIAP(options?: UseIapOptions): UseIap {
411
398
  })
412
399
  }
413
400
  }
414
- }, [refreshSubscriptionStatus])
401
+ }, [getActiveSubscriptionsInternal, getAvailablePurchasesInternal])
415
402
 
416
403
  useEffect(() => {
417
404
  initIapWithSubscriptions()
package/src/index.ts CHANGED
@@ -24,6 +24,7 @@ import type {
24
24
  RequestPurchaseIosProps,
25
25
  RequestPurchaseAndroidProps,
26
26
  } from './types'
27
+ import type { ProductRequest } from './types'
27
28
  import {
28
29
  convertNitroProductToProduct,
29
30
  convertNitroPurchaseToPurchase,
@@ -85,36 +86,42 @@ export const endConnection = async (): Promise<boolean> => {
85
86
  * Fetch products from the store
86
87
  * @param params - Product request configuration
87
88
  * @param params.skus - Array of product SKUs to fetch
88
- * @param params.type - Type of products: 'inapp' for regular products (default) or 'subs' for subscriptions
89
+ * @param params.type - Optional filter: 'inapp' (default) for products, 'subs' for subscriptions, or 'all' for both.
89
90
  * @returns Promise<Product[]> - Array of products from the store
90
91
  *
91
92
  * @example
92
93
  * ```typescript
93
94
  * // Regular products
94
- * const products = await fetchProducts({
95
- * skus: ['product1', 'product2'],
96
- * type: 'inapp'
97
- * });
95
+ * const products = await fetchProducts({ skus: ['product1', 'product2'] });
98
96
  *
99
97
  * // Subscriptions
100
- * const subscriptions = await fetchProducts({
101
- * skus: ['sub1', 'sub2'],
102
- * type: 'subs'
103
- * });
98
+ * const subscriptions = await fetchProducts({ skus: ['sub1', 'sub2'], type: 'subs' });
104
99
  * ```
105
100
  */
106
101
  export const fetchProducts = async ({
107
102
  skus,
108
103
  type = 'inapp',
109
- }: {
110
- skus: string[]
111
- type?: 'inapp' | 'subs'
112
- }): Promise<Product[]> => {
104
+ }: ProductRequest): Promise<Product[]> => {
113
105
  try {
114
106
  if (!skus || skus.length === 0) {
115
107
  throw new Error('No SKUs provided')
116
108
  }
117
109
 
110
+ if (type === 'all') {
111
+ const [inappNitro, subsNitro] = await Promise.all([
112
+ iap.fetchProducts(skus, 'inapp'),
113
+ iap.fetchProducts(skus, 'subs'),
114
+ ])
115
+ const allNitro = [...inappNitro, ...subsNitro]
116
+ const validAll = allNitro.filter(validateNitroProduct)
117
+ if (validAll.length !== allNitro.length) {
118
+ console.warn(
119
+ `[fetchProducts] Some products failed validation: ${allNitro.length - validAll.length} invalid`
120
+ )
121
+ }
122
+ return validAll.map(convertNitroProductToProduct)
123
+ }
124
+
118
125
  const nitroProducts = await iap.fetchProducts(skus, type)
119
126
 
120
127
  // Validate and convert NitroProducts to TypeScript Products
@@ -202,8 +209,16 @@ export const requestPurchase = async ({
202
209
  const unifiedRequest: any = {}
203
210
 
204
211
  if (Platform.OS === 'ios' && request.ios) {
212
+ const iosReq = request.ios as RequestPurchaseIosProps
213
+ const autoFinishSubs =
214
+ type === 'subs' &&
215
+ iosReq.andDangerouslyFinishTransactionAutomatically == null
205
216
  unifiedRequest.ios = {
206
- ...request.ios,
217
+ ...iosReq,
218
+ // Align with native SwiftUI flow: auto-finish subscriptions by default
219
+ ...(autoFinishSubs
220
+ ? { andDangerouslyFinishTransactionAutomatically: true }
221
+ : {}),
207
222
  } as RequestPurchaseIosProps
208
223
  }
209
224
 
@@ -230,10 +245,8 @@ export const requestPurchase = async ({
230
245
  /**
231
246
  * Get available purchases (purchased items not yet consumed/finished)
232
247
  * @param params - Options for getting available purchases
233
- * @param params.alsoPublishToEventListenerIOS - Whether to also publish to event listener (iOS only)
234
- * @param params.onlyIncludeActiveItemsIOS - Whether to only include active items (iOS only)
235
- * @param params.alsoPublishToEventListener - @deprecated Use alsoPublishToEventListenerIOS instead
236
- * @param params.onlyIncludeActiveItems - @deprecated Use onlyIncludeActiveItemsIOS instead
248
+ * @param params.alsoPublishToEventListener - Whether to also publish to event listener
249
+ * @param params.onlyIncludeActiveItems - Whether to only include active items
237
250
  *
238
251
  * @example
239
252
  * ```typescript
@@ -243,27 +256,20 @@ export const requestPurchase = async ({
243
256
  * ```
244
257
  */
245
258
  export const getAvailablePurchases = async ({
246
- alsoPublishToEventListener = false,
247
- onlyIncludeActiveItems = true,
248
- alsoPublishToEventListenerIOS,
249
- onlyIncludeActiveItemsIOS,
259
+ alsoPublishToEventListenerIOS = false,
260
+ onlyIncludeActiveItemsIOS = true,
250
261
  }: PurchaseOptions = {}): Promise<Purchase[]> => {
251
262
  try {
252
263
  // Create unified options
253
264
  const options: any = {}
254
265
 
255
266
  if (Platform.OS === 'ios') {
256
- // Use new IOS suffixed parameters if provided, fallback to deprecated ones
267
+ // Provide both new and deprecated keys for compatibility
257
268
  options.ios = {
258
- alsoPublishToEventListenerIOS:
259
- alsoPublishToEventListenerIOS ?? alsoPublishToEventListener,
260
- onlyIncludeActiveItemsIOS:
261
- onlyIncludeActiveItemsIOS ?? onlyIncludeActiveItems,
262
- // Keep deprecated parameters for backward compatibility
263
- alsoPublishToEventListener:
264
- alsoPublishToEventListenerIOS ?? alsoPublishToEventListener,
265
- onlyIncludeActiveItems:
266
- onlyIncludeActiveItemsIOS ?? onlyIncludeActiveItems,
269
+ alsoPublishToEventListenerIOS,
270
+ onlyIncludeActiveItemsIOS,
271
+ alsoPublishToEventListener: alsoPublishToEventListenerIOS,
272
+ onlyIncludeActiveItems: onlyIncludeActiveItemsIOS,
267
273
  }
268
274
  } else if (Platform.OS === 'android') {
269
275
  // For Android, we need to call twice for inapp and subs
@@ -360,6 +366,19 @@ export const finishTransaction = async ({
360
366
  // It's a PurchaseResult
361
367
  return result as NitroPurchaseResult
362
368
  } catch (error) {
369
+ // If iOS transaction has already been auto-finished natively, treat as success
370
+ if (Platform.OS === 'ios') {
371
+ const err = parseErrorStringToJsonObj(error)
372
+ const msg = (err?.message || '').toString()
373
+ const code = (err?.code || '').toString()
374
+ if (
375
+ msg.includes('Transaction not found') ||
376
+ code === 'E_ITEM_UNAVAILABLE'
377
+ ) {
378
+ // Consider already finished
379
+ return true
380
+ }
381
+ }
363
382
  console.error('Failed to finish transaction:', error)
364
383
  throw error
365
384
  }
@@ -623,7 +642,7 @@ export const validateReceipt = async (
623
642
  accessToken: string
624
643
  isSub?: boolean
625
644
  }
626
- ): Promise<ReceiptValidationResultIOS | ReceiptValidationResultAndroid> => {
645
+ ): Promise<import('./types').ReceiptValidationResult> => {
627
646
  if (!iap) {
628
647
  const errorJson = parseErrorStringToJsonObj(
629
648
  'RnIap: Service not initialized. Call initConnection() first.'
@@ -665,7 +684,7 @@ export const validateReceipt = async (
665
684
  gracePeriodEndDate: androidResult.gracePeriodEndDate,
666
685
  parentProductId: androidResult.parentProductId,
667
686
  productId: androidResult.productId,
668
- productType: androidResult.productType,
687
+ productType: androidResult.productType === 'subs' ? 'subs' : 'inapp',
669
688
  purchaseDate: androidResult.purchaseDate,
670
689
  quantity: androidResult.quantity,
671
690
  receiptId: androidResult.receiptId,
@@ -969,12 +988,12 @@ export const getPendingTransactionsIOS = async (): Promise<Purchase[]> => {
969
988
 
970
989
  /**
971
990
  * Show manage subscriptions screen (iOS only)
972
- * @returns Promise<boolean> - Success flag
991
+ * @returns Promise<Purchase[]> - Subscriptions where auto-renewal status changed
973
992
  * @platform iOS
974
993
  */
975
- export const showManageSubscriptionsIOS = async (): Promise<boolean> => {
994
+ export const showManageSubscriptionsIOS = async (): Promise<Purchase[]> => {
976
995
  if (Platform.OS !== 'ios') {
977
- return false
996
+ return []
978
997
  }
979
998
 
980
999
  if (!iap) {
@@ -985,7 +1004,8 @@ export const showManageSubscriptionsIOS = async (): Promise<boolean> => {
985
1004
  }
986
1005
 
987
1006
  try {
988
- return await iap.showManageSubscriptionsIOS()
1007
+ const nitroPurchases = await iap.showManageSubscriptionsIOS()
1008
+ return nitroPurchases.map(convertNitroPurchaseToPurchase)
989
1009
  } catch (error) {
990
1010
  console.error('[showManageSubscriptionsIOS] Failed:', error)
991
1011
  const errorJson = parseErrorStringToJsonObj(error)
@@ -198,6 +198,9 @@ export interface NitroPurchase {
198
198
  transactionDate: number
199
199
  purchaseToken?: string
200
200
  platform: string
201
+ quantity: number
202
+ purchaseState: string
203
+ isAutoRenewing: boolean
201
204
 
202
205
  // iOS specific fields
203
206
  quantityIOS?: number
@@ -233,8 +236,9 @@ export interface NitroProduct {
233
236
  platform: string
234
237
 
235
238
  // iOS specific fields
236
- isFamilyShareable?: boolean
237
- jsonRepresentation?: string
239
+ typeIOS?: string
240
+ isFamilyShareableIOS?: boolean
241
+ jsonRepresentationIOS?: string
238
242
  subscriptionPeriodUnitIOS?: string
239
243
  subscriptionPeriodNumberIOS?: number
240
244
  introductoryPriceIOS?: string
@@ -244,13 +248,13 @@ export interface NitroProduct {
244
248
  introductoryPriceSubscriptionPeriodIOS?: string
245
249
 
246
250
  // Android specific fields
247
- originalPrice?: string
248
- originalPriceAmountMicros?: number
249
- introductoryPriceValue?: number
250
- introductoryPriceCycles?: number
251
- introductoryPricePeriod?: string
252
- subscriptionPeriod?: string
253
- freeTrialPeriod?: string
251
+ originalPriceAndroid?: string
252
+ originalPriceAmountMicrosAndroid?: number
253
+ introductoryPriceValueAndroid?: number
254
+ introductoryPriceCyclesAndroid?: number
255
+ introductoryPricePeriodAndroid?: string
256
+ subscriptionPeriodAndroid?: string
257
+ freeTrialPeriodAndroid?: string
254
258
  subscriptionOfferDetailsAndroid?: string // Android subscription offer details as JSON string
255
259
  }
256
260
 
@@ -452,10 +456,10 @@ export interface RnIap
452
456
 
453
457
  /**
454
458
  * Show manage subscriptions screen (iOS only)
455
- * @returns Promise<boolean> - Success flag
459
+ * @returns Promise<NitroPurchase[]> - Array of updated subscriptions with renewal info
456
460
  * @platform iOS
457
461
  */
458
- showManageSubscriptionsIOS(): Promise<boolean>
462
+ showManageSubscriptionsIOS(): Promise<NitroPurchase[]>
459
463
 
460
464
  /**
461
465
  * Check if user is eligible for intro offer (iOS only)