react-native-iap 14.0.1 → 14.1.1-rc.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 (55) hide show
  1. package/android/src/main/java/com/margelo/nitro/iap/HybridRnIap.kt +81 -22
  2. package/app.plugin.js +1 -1
  3. package/ios/HybridRnIap.swift +167 -11
  4. package/ios/ProductStore.swift +10 -0
  5. package/ios/reactnativeiap.xcodeproj/project.xcworkspace/contents.xcworkspacedata +7 -0
  6. package/ios/reactnativeiap.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist +8 -0
  7. package/lib/module/helpers/subscription.js +9 -1
  8. package/lib/module/helpers/subscription.js.map +1 -1
  9. package/lib/module/hooks/useIAP.js +9 -13
  10. package/lib/module/hooks/useIAP.js.map +1 -1
  11. package/lib/module/index.js +43 -28
  12. package/lib/module/index.js.map +1 -1
  13. package/lib/module/types.js +24 -16
  14. package/lib/module/types.js.map +1 -1
  15. package/lib/module/utils/error.js.map +1 -1
  16. package/lib/module/utils/type-bridge.js +64 -13
  17. package/lib/module/utils/type-bridge.js.map +1 -1
  18. package/lib/typescript/src/helpers/subscription.d.ts.map +1 -1
  19. package/lib/typescript/src/hooks/useIAP.d.ts.map +1 -1
  20. package/lib/typescript/src/index.d.ts +12 -22
  21. package/lib/typescript/src/index.d.ts.map +1 -1
  22. package/lib/typescript/src/specs/RnIap.nitro.d.ts +15 -11
  23. package/lib/typescript/src/specs/RnIap.nitro.d.ts.map +1 -1
  24. package/lib/typescript/src/types.d.ts +58 -58
  25. package/lib/typescript/src/types.d.ts.map +1 -1
  26. package/lib/typescript/src/utils/error.d.ts.map +1 -1
  27. package/lib/typescript/src/utils/type-bridge.d.ts.map +1 -1
  28. package/nitro.json +5 -1
  29. package/nitrogen/generated/android/c++/JHybridRnIapSpec.cpp +13 -4
  30. package/nitrogen/generated/android/c++/JHybridRnIapSpec.hpp +1 -1
  31. package/nitrogen/generated/android/c++/JNitroProduct.hpp +40 -36
  32. package/nitrogen/generated/android/c++/JNitroPurchase.hpp +12 -0
  33. package/nitrogen/generated/android/kotlin/com/margelo/nitro/iap/HybridRnIapSpec.kt +1 -1
  34. package/nitrogen/generated/android/kotlin/com/margelo/nitro/iap/NitroProduct.kt +12 -9
  35. package/nitrogen/generated/android/kotlin/com/margelo/nitro/iap/NitroPurchase.kt +9 -0
  36. package/nitrogen/generated/ios/c++/HybridRnIapSpecSwift.hpp +1 -1
  37. package/nitrogen/generated/ios/swift/HybridRnIapSpec.swift +1 -1
  38. package/nitrogen/generated/ios/swift/HybridRnIapSpec_cxx.swift +13 -7
  39. package/nitrogen/generated/ios/swift/NitroProduct.swift +73 -43
  40. package/nitrogen/generated/ios/swift/NitroPurchase.swift +35 -2
  41. package/nitrogen/generated/shared/c++/HybridRnIapSpec.hpp +1 -1
  42. package/nitrogen/generated/shared/c++/NitroProduct.hpp +41 -37
  43. package/nitrogen/generated/shared/c++/NitroPurchase.hpp +13 -1
  44. package/package.json +9 -2
  45. package/plugin/build/src/withIAP.d.ts +3 -0
  46. package/plugin/build/src/withIAP.js +81 -0
  47. package/plugin/build/tsconfig.tsbuildinfo +1 -0
  48. package/plugin/tsconfig.tsbuildinfo +1 -1
  49. package/src/helpers/subscription.ts +36 -25
  50. package/src/hooks/useIAP.ts +188 -201
  51. package/src/index.ts +377 -356
  52. package/src/specs/RnIap.nitro.ts +15 -11
  53. package/src/types.ts +66 -62
  54. package/src/utils/error.ts +19 -19
  55. package/src/utils/type-bridge.ts +138 -75
@@ -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.1-rc.1",
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": {
@@ -0,0 +1,3 @@
1
+ import type { ConfigPlugin } from 'expo/config-plugins';
2
+ declare const _default: ConfigPlugin<void>;
3
+ export default _default;
@@ -0,0 +1,81 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ const config_plugins_1 = require("expo/config-plugins");
4
+ const pkg = require('../../package.json');
5
+ // Global flag to prevent duplicate logs
6
+ let hasLoggedPluginExecution = false;
7
+ const addLineToGradle = (content, anchor, lineToAdd, offset = 1) => {
8
+ const lines = content.split('\n');
9
+ const index = lines.findIndex((line) => line.match(anchor));
10
+ if (index === -1) {
11
+ console.warn(`Anchor "${anchor}" not found in build.gradle. Appending to end.`);
12
+ lines.push(lineToAdd);
13
+ }
14
+ else {
15
+ lines.splice(index + offset, 0, lineToAdd);
16
+ }
17
+ return lines.join('\n');
18
+ };
19
+ const modifyAppBuildGradle = (gradle) => {
20
+ let modified = gradle;
21
+ // Add billing library dependencies to app-level build.gradle
22
+ const billingDep = ` implementation "com.android.billingclient:billing-ktx:8.0.0"`;
23
+ const gmsDep = ` implementation "com.google.android.gms:play-services-base:18.1.0"`;
24
+ let hasAddedDependency = false;
25
+ if (!modified.includes(billingDep)) {
26
+ modified = addLineToGradle(modified, /dependencies\s*{/, billingDep);
27
+ hasAddedDependency = true;
28
+ }
29
+ if (!modified.includes(gmsDep)) {
30
+ modified = addLineToGradle(modified, /dependencies\s*{/, gmsDep, 1);
31
+ hasAddedDependency = true;
32
+ }
33
+ // Log only once and only if we actually added dependencies
34
+ if (hasAddedDependency && !hasLoggedPluginExecution) {
35
+ console.log('🛠️ react-native-iap: Added billing dependencies to build.gradle');
36
+ }
37
+ return modified;
38
+ };
39
+ const withIapAndroid = (config) => {
40
+ // Add IAP dependencies to app build.gradle
41
+ config = (0, config_plugins_1.withAppBuildGradle)(config, (config) => {
42
+ config.modResults.contents = modifyAppBuildGradle(config.modResults.contents);
43
+ return config;
44
+ });
45
+ config = (0, config_plugins_1.withAndroidManifest)(config, (config) => {
46
+ const manifest = config.modResults;
47
+ if (!manifest.manifest['uses-permission']) {
48
+ manifest.manifest['uses-permission'] = [];
49
+ }
50
+ const permissions = manifest.manifest['uses-permission'];
51
+ const billingPerm = { $: { 'android:name': 'com.android.vending.BILLING' } };
52
+ const alreadyExists = permissions.some((p) => p.$['android:name'] === 'com.android.vending.BILLING');
53
+ if (!alreadyExists) {
54
+ permissions.push(billingPerm);
55
+ if (!hasLoggedPluginExecution) {
56
+ console.log('✅ Added com.android.vending.BILLING to AndroidManifest.xml');
57
+ }
58
+ }
59
+ else {
60
+ if (!hasLoggedPluginExecution) {
61
+ console.log('ℹ️ com.android.vending.BILLING already exists in AndroidManifest.xml');
62
+ }
63
+ }
64
+ return config;
65
+ });
66
+ return config;
67
+ };
68
+ const withIAP = (config, _props) => {
69
+ try {
70
+ const result = withIapAndroid(config);
71
+ // Set flag after first execution to prevent duplicate logs
72
+ hasLoggedPluginExecution = true;
73
+ return result;
74
+ }
75
+ catch (error) {
76
+ config_plugins_1.WarningAggregator.addWarningAndroid('react-native-iap', `react-native-iap plugin encountered an error: ${error}`);
77
+ console.error('react-native-iap plugin error:', error);
78
+ return config;
79
+ }
80
+ };
81
+ exports.default = (0, config_plugins_1.createRunOncePlugin)(withIAP, pkg.name, pkg.version);
@@ -0,0 +1 @@
1
+ {"root":["../src/withiap.ts"],"version":"5.9.2"}
@@ -1 +1 @@
1
- {"root":["./src/withIAP.ts"],"version":"5.9.2"}
1
+ {"root":["./src/withiap.ts"],"version":"5.9.2"}
@@ -1,5 +1,9 @@
1
- import { getAvailablePurchases } from '../'
2
- import type { ActiveSubscription, PurchaseIOS, PurchaseAndroid } from '../types'
1
+ import {getAvailablePurchases} from '../';
2
+ import type {
3
+ ActiveSubscription,
4
+ PurchaseIOS,
5
+ PurchaseAndroid,
6
+ } from '../types';
3
7
 
4
8
  /**
5
9
  * Get active subscriptions
@@ -7,48 +11,55 @@ import type { ActiveSubscription, PurchaseIOS, PurchaseAndroid } from '../types'
7
11
  * @returns Promise<ActiveSubscription[]> - Array of active subscriptions
8
12
  */
9
13
  export const getActiveSubscriptions = async (
10
- subscriptionIds?: string[]
14
+ subscriptionIds?: string[],
11
15
  ): Promise<ActiveSubscription[]> => {
12
16
  try {
13
17
  // Get available purchases and filter for subscriptions
14
- const purchases = await getAvailablePurchases()
15
-
18
+ const purchases = await getAvailablePurchases();
19
+
16
20
  // Filter for subscriptions and map to ActiveSubscription format
17
21
  const subscriptions = purchases
18
22
  .filter((purchase) => {
19
23
  // Filter by subscription IDs if provided
20
24
  if (subscriptionIds && subscriptionIds.length > 0) {
21
- return subscriptionIds.includes(purchase.productId)
25
+ return subscriptionIds.includes(purchase.productId);
22
26
  }
23
- return true
27
+ return true;
24
28
  })
25
29
  .map((purchase): ActiveSubscription => {
26
- const iosPurchase = purchase as PurchaseIOS
30
+ const iosPurchase = purchase as PurchaseIOS;
31
+ const androidPurchase = purchase as PurchaseAndroid;
27
32
  return {
28
33
  productId: purchase.productId,
29
34
  isActive: true, // If it's in availablePurchases, it's active
35
+ // Backend validation fields
36
+ transactionId: purchase.transactionId || purchase.id,
37
+ purchaseToken:
38
+ androidPurchase.purchaseToken || androidPurchase.purchaseTokenAndroid || iosPurchase.purchaseToken,
39
+ transactionDate: purchase.transactionDate,
40
+ // Platform-specific fields
30
41
  expirationDateIOS: iosPurchase.expirationDateIOS
31
42
  ? new Date(iosPurchase.expirationDateIOS)
32
43
  : undefined,
33
- autoRenewingAndroid: (purchase as PurchaseAndroid)
34
- .autoRenewingAndroid,
44
+ autoRenewingAndroid: androidPurchase.autoRenewingAndroid ?? 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(
39
- (iosPurchase.expirationDateIOS - Date.now()) /
40
- (1000 * 60 * 60 * 24)
50
+ (iosPurchase.expirationDateIOS - Date.now()) / (1000 * 60 * 60 * 24),
41
51
  )
42
52
  : undefined,
43
- }
44
- })
45
-
46
- return subscriptions
53
+ };
54
+ });
55
+
56
+ return subscriptions;
47
57
  } catch (error) {
48
- console.error('Failed to get active subscriptions:', error)
49
- throw error
58
+ console.error('Failed to get active subscriptions:', error);
59
+ throw error;
50
60
  }
51
- }
61
+ };
62
+
52
63
 
53
64
  /**
54
65
  * Check if there are any active subscriptions
@@ -56,13 +67,13 @@ export const getActiveSubscriptions = async (
56
67
  * @returns Promise<boolean> - True if there are active subscriptions
57
68
  */
58
69
  export const hasActiveSubscriptions = async (
59
- subscriptionIds?: string[]
70
+ subscriptionIds?: string[],
60
71
  ): Promise<boolean> => {
61
72
  try {
62
- const activeSubscriptions = await getActiveSubscriptions(subscriptionIds)
63
- return activeSubscriptions.length > 0
73
+ const activeSubscriptions = await getActiveSubscriptions(subscriptionIds);
74
+ return activeSubscriptions.length > 0;
64
75
  } catch (error) {
65
- console.error('Failed to check active subscriptions:', error)
66
- return false
76
+ console.error('Failed to check active subscriptions:', error);
77
+ return false;
67
78
  }
68
- }
79
+ };