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.
- package/android/src/main/java/com/margelo/nitro/iap/HybridRnIap.kt +81 -22
- package/app.plugin.js +1 -1
- package/ios/HybridRnIap.swift +167 -11
- package/ios/ProductStore.swift +10 -0
- package/ios/reactnativeiap.xcodeproj/project.xcworkspace/contents.xcworkspacedata +7 -0
- package/ios/reactnativeiap.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist +8 -0
- package/lib/module/helpers/subscription.js +9 -1
- package/lib/module/helpers/subscription.js.map +1 -1
- package/lib/module/hooks/useIAP.js +9 -13
- package/lib/module/hooks/useIAP.js.map +1 -1
- package/lib/module/index.js +43 -28
- package/lib/module/index.js.map +1 -1
- package/lib/module/types.js +24 -16
- package/lib/module/types.js.map +1 -1
- package/lib/module/utils/error.js.map +1 -1
- package/lib/module/utils/type-bridge.js +64 -13
- package/lib/module/utils/type-bridge.js.map +1 -1
- package/lib/typescript/src/helpers/subscription.d.ts.map +1 -1
- package/lib/typescript/src/hooks/useIAP.d.ts.map +1 -1
- package/lib/typescript/src/index.d.ts +12 -22
- package/lib/typescript/src/index.d.ts.map +1 -1
- package/lib/typescript/src/specs/RnIap.nitro.d.ts +15 -11
- package/lib/typescript/src/specs/RnIap.nitro.d.ts.map +1 -1
- package/lib/typescript/src/types.d.ts +58 -58
- package/lib/typescript/src/types.d.ts.map +1 -1
- package/lib/typescript/src/utils/error.d.ts.map +1 -1
- package/lib/typescript/src/utils/type-bridge.d.ts.map +1 -1
- package/nitro.json +5 -1
- package/nitrogen/generated/android/c++/JHybridRnIapSpec.cpp +13 -4
- package/nitrogen/generated/android/c++/JHybridRnIapSpec.hpp +1 -1
- package/nitrogen/generated/android/c++/JNitroProduct.hpp +40 -36
- package/nitrogen/generated/android/c++/JNitroPurchase.hpp +12 -0
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/iap/HybridRnIapSpec.kt +1 -1
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/iap/NitroProduct.kt +12 -9
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/iap/NitroPurchase.kt +9 -0
- package/nitrogen/generated/ios/c++/HybridRnIapSpecSwift.hpp +1 -1
- package/nitrogen/generated/ios/swift/HybridRnIapSpec.swift +1 -1
- package/nitrogen/generated/ios/swift/HybridRnIapSpec_cxx.swift +13 -7
- package/nitrogen/generated/ios/swift/NitroProduct.swift +73 -43
- package/nitrogen/generated/ios/swift/NitroPurchase.swift +35 -2
- package/nitrogen/generated/shared/c++/HybridRnIapSpec.hpp +1 -1
- package/nitrogen/generated/shared/c++/NitroProduct.hpp +41 -37
- package/nitrogen/generated/shared/c++/NitroPurchase.hpp +13 -1
- package/package.json +9 -2
- package/plugin/build/src/withIAP.d.ts +3 -0
- package/plugin/build/src/withIAP.js +81 -0
- package/plugin/build/tsconfig.tsbuildinfo +1 -0
- package/plugin/tsconfig.tsbuildinfo +1 -1
- package/src/helpers/subscription.ts +36 -25
- package/src/hooks/useIAP.ts +188 -201
- package/src/index.ts +377 -356
- package/src/specs/RnIap.nitro.ts +15 -11
- package/src/types.ts +66 -62
- package/src/utils/error.ts +19 -19
- 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<
|
|
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<
|
|
43
|
-
std::optional<
|
|
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>
|
|
52
|
-
std::optional<double>
|
|
53
|
-
std::optional<double>
|
|
54
|
-
std::optional<double>
|
|
55
|
-
std::optional<std::string>
|
|
56
|
-
std::optional<std::string>
|
|
57
|
-
std::optional<std::string>
|
|
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>
|
|
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<
|
|
85
|
-
JSIConverter<std::optional<
|
|
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, "
|
|
94
|
-
JSIConverter<std::optional<double>>::fromJSI(runtime, obj.getProperty(runtime, "
|
|
95
|
-
JSIConverter<std::optional<double>>::fromJSI(runtime, obj.getProperty(runtime, "
|
|
96
|
-
JSIConverter<std::optional<double>>::fromJSI(runtime, obj.getProperty(runtime, "
|
|
97
|
-
JSIConverter<std::optional<std::string>>::fromJSI(runtime, obj.getProperty(runtime, "
|
|
98
|
-
JSIConverter<std::optional<std::string>>::fromJSI(runtime, obj.getProperty(runtime, "
|
|
99
|
-
JSIConverter<std::optional<std::string>>::fromJSI(runtime, obj.getProperty(runtime, "
|
|
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, "
|
|
115
|
-
obj.setProperty(runtime, "
|
|
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, "
|
|
124
|
-
obj.setProperty(runtime, "
|
|
125
|
-
obj.setProperty(runtime, "
|
|
126
|
-
obj.setProperty(runtime, "
|
|
127
|
-
obj.setProperty(runtime, "
|
|
128
|
-
obj.setProperty(runtime, "
|
|
129
|
-
obj.setProperty(runtime, "
|
|
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<
|
|
148
|
-
if (!JSIConverter<std::optional<
|
|
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, "
|
|
157
|
-
if (!JSIConverter<std::optional<double>>::canConvert(runtime, obj.getProperty(runtime, "
|
|
158
|
-
if (!JSIConverter<std::optional<double>>::canConvert(runtime, obj.getProperty(runtime, "
|
|
159
|
-
if (!JSIConverter<std::optional<double>>::canConvert(runtime, obj.getProperty(runtime, "
|
|
160
|
-
if (!JSIConverter<std::optional<std::string>>::canConvert(runtime, obj.getProperty(runtime, "
|
|
161
|
-
if (!JSIConverter<std::optional<std::string>>::canConvert(runtime, obj.getProperty(runtime, "
|
|
162
|
-
if (!JSIConverter<std::optional<std::string>>::canConvert(runtime, obj.getProperty(runtime, "
|
|
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.
|
|
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": "
|
|
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,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/
|
|
1
|
+
{"root":["./src/withiap.ts"],"version":"5.9.2"}
|
|
@@ -1,5 +1,9 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import type {
|
|
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:
|
|
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
|
+
};
|