react-native-iap 16.3.0 → 16.3.2
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/README.md +3 -3
- package/android/src/main/java/com/margelo/nitro/iap/HybridRnIap.kt +111 -15
- package/android/src/main/java/com/margelo/nitro/iap/RnIapLog.kt +5 -1
- package/ios/HybridRnIap.swift +1 -1
- package/ios/RnIapLog.swift +6 -6
- package/lib/module/index.js +51 -6
- package/lib/module/index.js.map +1 -1
- package/lib/module/index.kepler.js +9 -0
- package/lib/module/index.kepler.js.map +1 -1
- package/lib/module/kit-api.js +3 -1
- package/lib/module/kit-api.js.map +1 -1
- package/lib/module/types.js +2 -0
- package/lib/module/types.js.map +1 -1
- package/lib/module/vega-adapter.js +3 -4
- package/lib/module/vega-adapter.js.map +1 -1
- package/lib/typescript/src/index.d.ts.map +1 -1
- package/lib/typescript/src/index.kepler.d.ts.map +1 -1
- package/lib/typescript/src/kit-api.d.ts +119 -2
- package/lib/typescript/src/kit-api.d.ts.map +1 -1
- package/lib/typescript/src/specs/RnIap.nitro.d.ts +9 -3
- package/lib/typescript/src/specs/RnIap.nitro.d.ts.map +1 -1
- package/lib/typescript/src/types.d.ts +33 -9
- package/lib/typescript/src/types.d.ts.map +1 -1
- package/lib/typescript/src/vega-adapter.d.ts.map +1 -1
- package/nitrogen/generated/android/NitroIap+autolinking.cmake +1 -1
- package/nitrogen/generated/android/c++/JHybridRnIapSpec.cpp +8 -4
- package/nitrogen/generated/android/c++/JHybridRnIapSpec.hpp +1 -1
- package/nitrogen/generated/android/c++/JNitroPurchaseVerificationResultAndroid.hpp +5 -1
- package/nitrogen/generated/android/c++/JNitroPurchaseVerificationResultHorizon.hpp +69 -0
- package/nitrogen/generated/android/c++/JVariant_NitroPurchaseVerificationResultIOS_NitroPurchaseVerificationResultAndroid_NitroPurchaseVerificationResultHorizon.cpp +30 -0
- package/nitrogen/generated/android/c++/{JVariant_NitroPurchaseVerificationResultIOS_NitroPurchaseVerificationResultAndroid.hpp → JVariant_NitroPurchaseVerificationResultIOS_NitroPurchaseVerificationResultAndroid_NitroPurchaseVerificationResultHorizon.hpp} +33 -16
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/iap/HybridRnIapSpec.kt +1 -1
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/iap/NitroPurchaseVerificationResultAndroid.kt +8 -3
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/iap/NitroPurchaseVerificationResultHorizon.kt +61 -0
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/iap/{Variant_NitroPurchaseVerificationResultIOS_NitroPurchaseVerificationResultAndroid.kt → Variant_NitroPurchaseVerificationResultIOS_NitroPurchaseVerificationResultAndroid_NitroPurchaseVerificationResultHorizon.kt} +21 -8
- package/nitrogen/generated/ios/NitroIap-Swift-Cxx-Bridge.cpp +4 -4
- package/nitrogen/generated/ios/NitroIap-Swift-Cxx-Bridge.hpp +43 -34
- package/nitrogen/generated/ios/NitroIap-Swift-Cxx-Umbrella.hpp +3 -0
- package/nitrogen/generated/ios/c++/HybridRnIapSpecSwift.hpp +4 -1
- package/nitrogen/generated/ios/swift/{Func_void_std__variant_NitroPurchaseVerificationResultIOS__NitroPurchaseVerificationResultAndroid_.swift → Func_void_std__variant_NitroPurchaseVerificationResultIOS__NitroPurchaseVerificationResultAndroid__NitroPurchaseVerificationResultHorizon_.swift} +14 -11
- package/nitrogen/generated/ios/swift/HybridRnIapSpec.swift +1 -1
- package/nitrogen/generated/ios/swift/HybridRnIapSpec_cxx.swift +11 -9
- package/nitrogen/generated/ios/swift/NitroPurchaseVerificationResultAndroid.swift +7 -2
- package/nitrogen/generated/ios/swift/NitroPurchaseVerificationResultHorizon.swift +71 -0
- package/nitrogen/generated/ios/swift/{Variant_NitroPurchaseVerificationResultIOS_NitroPurchaseVerificationResultAndroid.swift → Variant_NitroPurchaseVerificationResultIOS_NitroPurchaseVerificationResultAndroid_NitroPurchaseVerificationResultHorizon.swift} +6 -4
- package/nitrogen/generated/shared/c++/HybridRnIapSpec.hpp +4 -1
- package/nitrogen/generated/shared/c++/NitroPurchaseVerificationResultAndroid.hpp +5 -1
- package/nitrogen/generated/shared/c++/NitroPurchaseVerificationResultHorizon.hpp +93 -0
- package/openiap-versions.json +3 -3
- package/package.json +3 -2
- package/src/index.kepler.ts +10 -2
- package/src/index.ts +88 -18
- package/src/kit-api.ts +125 -4
- package/src/specs/RnIap.nitro.ts +12 -2
- package/src/types.ts +34 -9
- package/src/vega-adapter.ts +6 -11
- package/nitrogen/generated/android/c++/JVariant_NitroPurchaseVerificationResultIOS_NitroPurchaseVerificationResultAndroid.cpp +0 -26
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
///
|
|
2
|
-
///
|
|
2
|
+
/// Variant_NitroPurchaseVerificationResultIOS_NitroPurchaseVerificationResultAndroid_NitroPurchaseVerificationResultHorizon.swift
|
|
3
3
|
/// This file was generated by nitrogen. DO NOT MODIFY THIS FILE.
|
|
4
4
|
/// https://github.com/mrousavy/nitro
|
|
5
5
|
/// Copyright © Marc Rousavy @ Margelo
|
|
@@ -9,19 +9,21 @@
|
|
|
9
9
|
|
|
10
10
|
/**
|
|
11
11
|
* An Swift enum with associated values representing a Variant/Union type.
|
|
12
|
-
* JS type: `struct | struct`
|
|
12
|
+
* JS type: `struct | struct | struct`
|
|
13
13
|
*/
|
|
14
14
|
@frozen
|
|
15
|
-
public indirect enum
|
|
15
|
+
public indirect enum Variant_NitroPurchaseVerificationResultIOS_NitroPurchaseVerificationResultAndroid_NitroPurchaseVerificationResultHorizon {
|
|
16
16
|
case first(NitroPurchaseVerificationResultIOS)
|
|
17
17
|
case second(NitroPurchaseVerificationResultAndroid)
|
|
18
|
+
case third(NitroPurchaseVerificationResultHorizon)
|
|
18
19
|
}
|
|
19
20
|
|
|
20
|
-
public extension
|
|
21
|
+
public extension Variant_NitroPurchaseVerificationResultIOS_NitroPurchaseVerificationResultAndroid_NitroPurchaseVerificationResultHorizon {
|
|
21
22
|
func asType<T>(_ type: T.Type = T.self) -> T? {
|
|
22
23
|
switch self {
|
|
23
24
|
case .first(let value): return value as? T
|
|
24
25
|
case .second(let value): return value as? T
|
|
26
|
+
case .third(let value): return value as? T
|
|
25
27
|
}
|
|
26
28
|
}
|
|
27
29
|
func isType<T>(_ type: T.Type = T.self) -> Bool {
|
|
@@ -41,6 +41,8 @@ namespace margelo::nitro::iap { struct NitroSubscriptionStatus; }
|
|
|
41
41
|
namespace margelo::nitro::iap { struct NitroPurchaseVerificationResultIOS; }
|
|
42
42
|
// Forward declaration of `NitroPurchaseVerificationResultAndroid` to properly resolve imports.
|
|
43
43
|
namespace margelo::nitro::iap { struct NitroPurchaseVerificationResultAndroid; }
|
|
44
|
+
// Forward declaration of `NitroPurchaseVerificationResultHorizon` to properly resolve imports.
|
|
45
|
+
namespace margelo::nitro::iap { struct NitroPurchaseVerificationResultHorizon; }
|
|
44
46
|
// Forward declaration of `NitroPurchaseVerificationParams` to properly resolve imports.
|
|
45
47
|
namespace margelo::nitro::iap { struct NitroPurchaseVerificationParams; }
|
|
46
48
|
// Forward declaration of `NitroVerifyPurchaseWithProviderResult` to properly resolve imports.
|
|
@@ -109,6 +111,7 @@ namespace margelo::nitro::iap { enum class ExternalPurchaseCustomLinkNoticeTypeI
|
|
|
109
111
|
#include "NitroSubscriptionStatus.hpp"
|
|
110
112
|
#include "NitroPurchaseVerificationResultIOS.hpp"
|
|
111
113
|
#include "NitroPurchaseVerificationResultAndroid.hpp"
|
|
114
|
+
#include "NitroPurchaseVerificationResultHorizon.hpp"
|
|
112
115
|
#include "NitroPurchaseVerificationParams.hpp"
|
|
113
116
|
#include "NitroVerifyPurchaseWithProviderResult.hpp"
|
|
114
117
|
#include "NitroVerifyPurchaseWithProviderProps.hpp"
|
|
@@ -196,7 +199,7 @@ namespace margelo::nitro::iap {
|
|
|
196
199
|
virtual std::shared_ptr<Promise<std::string>> requestReceiptRefreshIOS() = 0;
|
|
197
200
|
virtual std::shared_ptr<Promise<bool>> isTransactionVerifiedIOS(const std::string& sku) = 0;
|
|
198
201
|
virtual std::shared_ptr<Promise<std::variant<nitro::NullType, std::string>>> getTransactionJwsIOS(const std::string& sku) = 0;
|
|
199
|
-
virtual std::shared_ptr<Promise<std::variant<NitroPurchaseVerificationResultIOS, NitroPurchaseVerificationResultAndroid>>> verifyPurchase(const NitroPurchaseVerificationParams& params) = 0;
|
|
202
|
+
virtual std::shared_ptr<Promise<std::variant<NitroPurchaseVerificationResultIOS, NitroPurchaseVerificationResultAndroid, NitroPurchaseVerificationResultHorizon>>> verifyPurchase(const NitroPurchaseVerificationParams& params) = 0;
|
|
200
203
|
virtual std::shared_ptr<Promise<NitroVerifyPurchaseWithProviderResult>> verifyPurchaseWithProvider(const NitroVerifyPurchaseWithProviderProps& params) = 0;
|
|
201
204
|
virtual std::shared_ptr<Promise<std::string>> getStorefront() = 0;
|
|
202
205
|
virtual std::shared_ptr<Promise<void>> deepLinkToSubscriptionsAndroid(const NitroDeepLinkOptionsAndroid& options) = 0;
|
|
@@ -42,6 +42,7 @@ namespace margelo::nitro::iap {
|
|
|
42
42
|
*/
|
|
43
43
|
struct NitroPurchaseVerificationResultAndroid final {
|
|
44
44
|
public:
|
|
45
|
+
bool isValid SWIFT_PRIVATE;
|
|
45
46
|
bool autoRenewing SWIFT_PRIVATE;
|
|
46
47
|
bool betaProduct SWIFT_PRIVATE;
|
|
47
48
|
std::optional<std::variant<nitro::NullType, double>> cancelDate SWIFT_PRIVATE;
|
|
@@ -63,7 +64,7 @@ namespace margelo::nitro::iap {
|
|
|
63
64
|
|
|
64
65
|
public:
|
|
65
66
|
NitroPurchaseVerificationResultAndroid() = default;
|
|
66
|
-
explicit NitroPurchaseVerificationResultAndroid(bool autoRenewing, bool betaProduct, std::optional<std::variant<nitro::NullType, double>> cancelDate, std::optional<std::variant<nitro::NullType, std::string>> cancelReason, std::optional<std::variant<nitro::NullType, double>> deferredDate, std::optional<std::variant<nitro::NullType, std::string>> deferredSku, double freeTrialEndDate, double gracePeriodEndDate, std::string parentProductId, std::string productId, std::string productType, double purchaseDate, double quantity, std::string receiptId, double renewalDate, std::string term, std::string termSku, bool testTransaction): autoRenewing(autoRenewing), betaProduct(betaProduct), cancelDate(cancelDate), cancelReason(cancelReason), deferredDate(deferredDate), deferredSku(deferredSku), freeTrialEndDate(freeTrialEndDate), gracePeriodEndDate(gracePeriodEndDate), parentProductId(parentProductId), productId(productId), productType(productType), purchaseDate(purchaseDate), quantity(quantity), receiptId(receiptId), renewalDate(renewalDate), term(term), termSku(termSku), testTransaction(testTransaction) {}
|
|
67
|
+
explicit NitroPurchaseVerificationResultAndroid(bool isValid, bool autoRenewing, bool betaProduct, std::optional<std::variant<nitro::NullType, double>> cancelDate, std::optional<std::variant<nitro::NullType, std::string>> cancelReason, std::optional<std::variant<nitro::NullType, double>> deferredDate, std::optional<std::variant<nitro::NullType, std::string>> deferredSku, double freeTrialEndDate, double gracePeriodEndDate, std::string parentProductId, std::string productId, std::string productType, double purchaseDate, double quantity, std::string receiptId, double renewalDate, std::string term, std::string termSku, bool testTransaction): isValid(isValid), autoRenewing(autoRenewing), betaProduct(betaProduct), cancelDate(cancelDate), cancelReason(cancelReason), deferredDate(deferredDate), deferredSku(deferredSku), freeTrialEndDate(freeTrialEndDate), gracePeriodEndDate(gracePeriodEndDate), parentProductId(parentProductId), productId(productId), productType(productType), purchaseDate(purchaseDate), quantity(quantity), receiptId(receiptId), renewalDate(renewalDate), term(term), termSku(termSku), testTransaction(testTransaction) {}
|
|
67
68
|
|
|
68
69
|
public:
|
|
69
70
|
friend bool operator==(const NitroPurchaseVerificationResultAndroid& lhs, const NitroPurchaseVerificationResultAndroid& rhs) = default;
|
|
@@ -79,6 +80,7 @@ namespace margelo::nitro {
|
|
|
79
80
|
static inline margelo::nitro::iap::NitroPurchaseVerificationResultAndroid fromJSI(jsi::Runtime& runtime, const jsi::Value& arg) {
|
|
80
81
|
jsi::Object obj = arg.asObject(runtime);
|
|
81
82
|
return margelo::nitro::iap::NitroPurchaseVerificationResultAndroid(
|
|
83
|
+
JSIConverter<bool>::fromJSI(runtime, obj.getProperty(runtime, PropNameIDCache::get(runtime, "isValid"))),
|
|
82
84
|
JSIConverter<bool>::fromJSI(runtime, obj.getProperty(runtime, PropNameIDCache::get(runtime, "autoRenewing"))),
|
|
83
85
|
JSIConverter<bool>::fromJSI(runtime, obj.getProperty(runtime, PropNameIDCache::get(runtime, "betaProduct"))),
|
|
84
86
|
JSIConverter<std::optional<std::variant<nitro::NullType, double>>>::fromJSI(runtime, obj.getProperty(runtime, PropNameIDCache::get(runtime, "cancelDate"))),
|
|
@@ -101,6 +103,7 @@ namespace margelo::nitro {
|
|
|
101
103
|
}
|
|
102
104
|
static inline jsi::Value toJSI(jsi::Runtime& runtime, const margelo::nitro::iap::NitroPurchaseVerificationResultAndroid& arg) {
|
|
103
105
|
jsi::Object obj(runtime);
|
|
106
|
+
obj.setProperty(runtime, PropNameIDCache::get(runtime, "isValid"), JSIConverter<bool>::toJSI(runtime, arg.isValid));
|
|
104
107
|
obj.setProperty(runtime, PropNameIDCache::get(runtime, "autoRenewing"), JSIConverter<bool>::toJSI(runtime, arg.autoRenewing));
|
|
105
108
|
obj.setProperty(runtime, PropNameIDCache::get(runtime, "betaProduct"), JSIConverter<bool>::toJSI(runtime, arg.betaProduct));
|
|
106
109
|
obj.setProperty(runtime, PropNameIDCache::get(runtime, "cancelDate"), JSIConverter<std::optional<std::variant<nitro::NullType, double>>>::toJSI(runtime, arg.cancelDate));
|
|
@@ -129,6 +132,7 @@ namespace margelo::nitro {
|
|
|
129
132
|
if (!nitro::isPlainObject(runtime, obj)) {
|
|
130
133
|
return false;
|
|
131
134
|
}
|
|
135
|
+
if (!JSIConverter<bool>::canConvert(runtime, obj.getProperty(runtime, PropNameIDCache::get(runtime, "isValid")))) return false;
|
|
132
136
|
if (!JSIConverter<bool>::canConvert(runtime, obj.getProperty(runtime, PropNameIDCache::get(runtime, "autoRenewing")))) return false;
|
|
133
137
|
if (!JSIConverter<bool>::canConvert(runtime, obj.getProperty(runtime, PropNameIDCache::get(runtime, "betaProduct")))) return false;
|
|
134
138
|
if (!JSIConverter<std::optional<std::variant<nitro::NullType, double>>>::canConvert(runtime, obj.getProperty(runtime, PropNameIDCache::get(runtime, "cancelDate")))) return false;
|
|
@@ -0,0 +1,93 @@
|
|
|
1
|
+
///
|
|
2
|
+
/// NitroPurchaseVerificationResultHorizon.hpp
|
|
3
|
+
/// This file was generated by nitrogen. DO NOT MODIFY THIS FILE.
|
|
4
|
+
/// https://github.com/mrousavy/nitro
|
|
5
|
+
/// Copyright © Marc Rousavy @ Margelo
|
|
6
|
+
///
|
|
7
|
+
|
|
8
|
+
#pragma once
|
|
9
|
+
|
|
10
|
+
#if __has_include(<NitroModules/JSIConverter.hpp>)
|
|
11
|
+
#include <NitroModules/JSIConverter.hpp>
|
|
12
|
+
#else
|
|
13
|
+
#error NitroModules cannot be found! Are you sure you installed NitroModules properly?
|
|
14
|
+
#endif
|
|
15
|
+
#if __has_include(<NitroModules/NitroDefines.hpp>)
|
|
16
|
+
#include <NitroModules/NitroDefines.hpp>
|
|
17
|
+
#else
|
|
18
|
+
#error NitroModules cannot be found! Are you sure you installed NitroModules properly?
|
|
19
|
+
#endif
|
|
20
|
+
#if __has_include(<NitroModules/JSIHelpers.hpp>)
|
|
21
|
+
#include <NitroModules/JSIHelpers.hpp>
|
|
22
|
+
#else
|
|
23
|
+
#error NitroModules cannot be found! Are you sure you installed NitroModules properly?
|
|
24
|
+
#endif
|
|
25
|
+
#if __has_include(<NitroModules/PropNameIDCache.hpp>)
|
|
26
|
+
#include <NitroModules/PropNameIDCache.hpp>
|
|
27
|
+
#else
|
|
28
|
+
#error NitroModules cannot be found! Are you sure you installed NitroModules properly?
|
|
29
|
+
#endif
|
|
30
|
+
|
|
31
|
+
|
|
32
|
+
|
|
33
|
+
#include <NitroModules/Null.hpp>
|
|
34
|
+
#include <variant>
|
|
35
|
+
#include <optional>
|
|
36
|
+
|
|
37
|
+
namespace margelo::nitro::iap {
|
|
38
|
+
|
|
39
|
+
/**
|
|
40
|
+
* A struct which can be represented as a JavaScript object (NitroPurchaseVerificationResultHorizon).
|
|
41
|
+
*/
|
|
42
|
+
struct NitroPurchaseVerificationResultHorizon final {
|
|
43
|
+
public:
|
|
44
|
+
bool isValid SWIFT_PRIVATE;
|
|
45
|
+
std::optional<std::variant<nitro::NullType, double>> grantTime SWIFT_PRIVATE;
|
|
46
|
+
bool success SWIFT_PRIVATE;
|
|
47
|
+
|
|
48
|
+
public:
|
|
49
|
+
NitroPurchaseVerificationResultHorizon() = default;
|
|
50
|
+
explicit NitroPurchaseVerificationResultHorizon(bool isValid, std::optional<std::variant<nitro::NullType, double>> grantTime, bool success): isValid(isValid), grantTime(grantTime), success(success) {}
|
|
51
|
+
|
|
52
|
+
public:
|
|
53
|
+
friend bool operator==(const NitroPurchaseVerificationResultHorizon& lhs, const NitroPurchaseVerificationResultHorizon& rhs) = default;
|
|
54
|
+
};
|
|
55
|
+
|
|
56
|
+
} // namespace margelo::nitro::iap
|
|
57
|
+
|
|
58
|
+
namespace margelo::nitro {
|
|
59
|
+
|
|
60
|
+
// C++ NitroPurchaseVerificationResultHorizon <> JS NitroPurchaseVerificationResultHorizon (object)
|
|
61
|
+
template <>
|
|
62
|
+
struct JSIConverter<margelo::nitro::iap::NitroPurchaseVerificationResultHorizon> final {
|
|
63
|
+
static inline margelo::nitro::iap::NitroPurchaseVerificationResultHorizon fromJSI(jsi::Runtime& runtime, const jsi::Value& arg) {
|
|
64
|
+
jsi::Object obj = arg.asObject(runtime);
|
|
65
|
+
return margelo::nitro::iap::NitroPurchaseVerificationResultHorizon(
|
|
66
|
+
JSIConverter<bool>::fromJSI(runtime, obj.getProperty(runtime, PropNameIDCache::get(runtime, "isValid"))),
|
|
67
|
+
JSIConverter<std::optional<std::variant<nitro::NullType, double>>>::fromJSI(runtime, obj.getProperty(runtime, PropNameIDCache::get(runtime, "grantTime"))),
|
|
68
|
+
JSIConverter<bool>::fromJSI(runtime, obj.getProperty(runtime, PropNameIDCache::get(runtime, "success")))
|
|
69
|
+
);
|
|
70
|
+
}
|
|
71
|
+
static inline jsi::Value toJSI(jsi::Runtime& runtime, const margelo::nitro::iap::NitroPurchaseVerificationResultHorizon& arg) {
|
|
72
|
+
jsi::Object obj(runtime);
|
|
73
|
+
obj.setProperty(runtime, PropNameIDCache::get(runtime, "isValid"), JSIConverter<bool>::toJSI(runtime, arg.isValid));
|
|
74
|
+
obj.setProperty(runtime, PropNameIDCache::get(runtime, "grantTime"), JSIConverter<std::optional<std::variant<nitro::NullType, double>>>::toJSI(runtime, arg.grantTime));
|
|
75
|
+
obj.setProperty(runtime, PropNameIDCache::get(runtime, "success"), JSIConverter<bool>::toJSI(runtime, arg.success));
|
|
76
|
+
return obj;
|
|
77
|
+
}
|
|
78
|
+
static inline bool canConvert(jsi::Runtime& runtime, const jsi::Value& value) {
|
|
79
|
+
if (!value.isObject()) {
|
|
80
|
+
return false;
|
|
81
|
+
}
|
|
82
|
+
jsi::Object obj = value.getObject(runtime);
|
|
83
|
+
if (!nitro::isPlainObject(runtime, obj)) {
|
|
84
|
+
return false;
|
|
85
|
+
}
|
|
86
|
+
if (!JSIConverter<bool>::canConvert(runtime, obj.getProperty(runtime, PropNameIDCache::get(runtime, "isValid")))) return false;
|
|
87
|
+
if (!JSIConverter<std::optional<std::variant<nitro::NullType, double>>>::canConvert(runtime, obj.getProperty(runtime, PropNameIDCache::get(runtime, "grantTime")))) return false;
|
|
88
|
+
if (!JSIConverter<bool>::canConvert(runtime, obj.getProperty(runtime, PropNameIDCache::get(runtime, "success")))) return false;
|
|
89
|
+
return true;
|
|
90
|
+
}
|
|
91
|
+
};
|
|
92
|
+
|
|
93
|
+
} // namespace margelo::nitro
|
package/openiap-versions.json
CHANGED
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "react-native-iap",
|
|
3
|
-
"version": "16.3.
|
|
3
|
+
"version": "16.3.2",
|
|
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",
|
|
@@ -173,6 +173,7 @@
|
|
|
173
173
|
},
|
|
174
174
|
"packageManager": "yarn@3.6.1",
|
|
175
175
|
"resolutions": {
|
|
176
|
-
"nitrogen@^0.36.5": "patch:nitrogen@npm%3A0.36.5#./.yarn/patches/nitrogen-npm-0.36.5-array-equatable.patch"
|
|
176
|
+
"nitrogen@^0.36.5": "patch:nitrogen@npm%3A0.36.5#./.yarn/patches/nitrogen-npm-0.36.5-array-equatable.patch",
|
|
177
|
+
"uuid@^7.0.3": "11.1.1"
|
|
177
178
|
}
|
|
178
179
|
}
|
package/src/index.kepler.ts
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import {getVegaIapModule} from './vega';
|
|
2
|
+
import {ErrorCode} from './types';
|
|
2
3
|
import type {
|
|
3
4
|
MutationField,
|
|
4
5
|
Product,
|
|
@@ -27,6 +28,7 @@ import {
|
|
|
27
28
|
validateNitroPurchase,
|
|
28
29
|
} from './utils/type-bridge';
|
|
29
30
|
import {convertAndroidPurchasesOrThrow} from './utils/available-purchases';
|
|
31
|
+
import {createPurchaseError} from './utils/errorMapping';
|
|
30
32
|
|
|
31
33
|
export * from './types';
|
|
32
34
|
export * from './utils/error';
|
|
@@ -129,13 +131,19 @@ export const fetchProducts = async (
|
|
|
129
131
|
const normalizedType = normalizeProductQueryType(type);
|
|
130
132
|
const nitroProducts = await getModule().fetchProducts(skus, normalizedType);
|
|
131
133
|
return mapProducts(nitroProducts, normalizedType) as
|
|
132
|
-
|
|
|
133
|
-
| ProductSubscription[];
|
|
134
|
+
Product[] | ProductSubscription[];
|
|
134
135
|
};
|
|
135
136
|
|
|
136
137
|
export const requestPurchase: MutationField<'requestPurchase'> = async (
|
|
137
138
|
request,
|
|
138
139
|
) => {
|
|
140
|
+
const type = normalizeProductQueryType(request.type);
|
|
141
|
+
if (type === 'all') {
|
|
142
|
+
throw createPurchaseError({
|
|
143
|
+
code: ErrorCode.DeveloperError,
|
|
144
|
+
message: 'Product type all is only supported for product queries.',
|
|
145
|
+
});
|
|
146
|
+
}
|
|
139
147
|
const perPlatformRequest = request.request as
|
|
140
148
|
| RequestPurchasePropsByPlatforms
|
|
141
149
|
| RequestSubscriptionPropsByPlatforms
|
package/src/index.ts
CHANGED
|
@@ -9,6 +9,7 @@ import type {
|
|
|
9
9
|
NitroPurchaseVerificationParams,
|
|
10
10
|
NitroPurchaseVerificationResultIOS,
|
|
11
11
|
NitroPurchaseVerificationResultAndroid,
|
|
12
|
+
NitroPurchaseVerificationResultHorizon,
|
|
12
13
|
NitroPurchaseUpdatedListenerOptions,
|
|
13
14
|
NitroSubscriptionStatus,
|
|
14
15
|
RnIap,
|
|
@@ -41,6 +42,7 @@ import type {
|
|
|
41
42
|
PurchaseIOS,
|
|
42
43
|
QueryField,
|
|
43
44
|
VerifyPurchaseResultAndroid,
|
|
45
|
+
VerifyPurchaseResultHorizon,
|
|
44
46
|
VerifyPurchaseResultIOS,
|
|
45
47
|
RequestPurchaseAndroidProps,
|
|
46
48
|
RequestPurchaseIosProps,
|
|
@@ -884,7 +886,10 @@ export const fetchProducts: QueryField<'fetchProducts'> = async (request) => {
|
|
|
884
886
|
|
|
885
887
|
try {
|
|
886
888
|
if (!skus?.length) {
|
|
887
|
-
throw
|
|
889
|
+
throw createPurchaseError({
|
|
890
|
+
message: 'No SKUs provided',
|
|
891
|
+
code: ErrorCode.EmptySkuList,
|
|
892
|
+
});
|
|
888
893
|
}
|
|
889
894
|
|
|
890
895
|
const normalizedType = normalizeProductQueryType(type);
|
|
@@ -1673,6 +1678,12 @@ export const requestPurchase: MutationField<'requestPurchase'> = async (
|
|
|
1673
1678
|
try {
|
|
1674
1679
|
const {request: platformRequest, type} = request;
|
|
1675
1680
|
const normalizedType = normalizeProductQueryType(type ?? 'in-app');
|
|
1681
|
+
if (normalizedType === 'all') {
|
|
1682
|
+
throw createPurchaseError({
|
|
1683
|
+
code: ErrorCode.DeveloperError,
|
|
1684
|
+
message: 'Product type all is only supported for product queries.',
|
|
1685
|
+
});
|
|
1686
|
+
}
|
|
1676
1687
|
const isSubs = isSubscriptionQuery(normalizedType);
|
|
1677
1688
|
const perPlatformRequest = platformRequest as
|
|
1678
1689
|
| RequestPurchasePropsByPlatforms
|
|
@@ -1691,15 +1702,23 @@ export const requestPurchase: MutationField<'requestPurchase'> = async (
|
|
|
1691
1702
|
|
|
1692
1703
|
if (Platform.OS === 'ios') {
|
|
1693
1704
|
if (!iosRequestSource?.sku) {
|
|
1694
|
-
throw
|
|
1695
|
-
'Invalid request for iOS. The `sku` property is required.',
|
|
1696
|
-
|
|
1705
|
+
throw createPurchaseError({
|
|
1706
|
+
message: 'Invalid request for iOS. The `sku` property is required.',
|
|
1707
|
+
code: ErrorCode.EmptySkuList,
|
|
1708
|
+
});
|
|
1697
1709
|
}
|
|
1698
1710
|
} else if (isAndroidStoreRuntime()) {
|
|
1699
|
-
|
|
1700
|
-
|
|
1701
|
-
|
|
1702
|
-
|
|
1711
|
+
const skus = androidRequestSource?.skus as unknown;
|
|
1712
|
+
if (
|
|
1713
|
+
!Array.isArray(skus) ||
|
|
1714
|
+
skus.length === 0 ||
|
|
1715
|
+
skus.some((sku) => typeof sku !== 'string' || sku.trim() === '')
|
|
1716
|
+
) {
|
|
1717
|
+
throw createPurchaseError({
|
|
1718
|
+
message:
|
|
1719
|
+
'Invalid request for Android. The `skus` property must contain only non-empty strings.',
|
|
1720
|
+
code: ErrorCode.EmptySkuList,
|
|
1721
|
+
});
|
|
1703
1722
|
}
|
|
1704
1723
|
} else {
|
|
1705
1724
|
throw unsupportedPlatformError();
|
|
@@ -1756,6 +1775,29 @@ export const requestPurchase: MutationField<'requestPurchase'> = async (
|
|
|
1756
1775
|
}
|
|
1757
1776
|
|
|
1758
1777
|
if (isAndroidStoreRuntime() && androidRequestSource) {
|
|
1778
|
+
const rawAndroidRequest = androidRequestSource as unknown as Record<
|
|
1779
|
+
string,
|
|
1780
|
+
unknown
|
|
1781
|
+
>;
|
|
1782
|
+
const subscriptionOnlyFields = [
|
|
1783
|
+
'subscriptionOffers',
|
|
1784
|
+
'subscriptionProductReplacementParams',
|
|
1785
|
+
'purchaseToken',
|
|
1786
|
+
'originalExternalTransactionId',
|
|
1787
|
+
];
|
|
1788
|
+
if (
|
|
1789
|
+
(!isSubs &&
|
|
1790
|
+
subscriptionOnlyFields.some(
|
|
1791
|
+
(field) => rawAndroidRequest[field] != null,
|
|
1792
|
+
)) ||
|
|
1793
|
+
(isSubs && rawAndroidRequest.offerToken != null)
|
|
1794
|
+
) {
|
|
1795
|
+
throw createPurchaseError({
|
|
1796
|
+
message:
|
|
1797
|
+
'Invalid request for Android. Purchase options must match the selected product type.',
|
|
1798
|
+
code: ErrorCode.DeveloperError,
|
|
1799
|
+
});
|
|
1800
|
+
}
|
|
1759
1801
|
const androidRequest = isSubs
|
|
1760
1802
|
? (androidRequestSource as RequestSubscriptionAndroidProps)
|
|
1761
1803
|
: (androidRequestSource as RequestPurchaseAndroidProps);
|
|
@@ -1788,6 +1830,29 @@ export const requestPurchase: MutationField<'requestPurchase'> = async (
|
|
|
1788
1830
|
|
|
1789
1831
|
if (isSubs) {
|
|
1790
1832
|
const subsRequest = androidRequest as RequestSubscriptionAndroidProps;
|
|
1833
|
+
const subscriptionOffers = subsRequest.subscriptionOffers as unknown;
|
|
1834
|
+
if (
|
|
1835
|
+
subscriptionOffers != null &&
|
|
1836
|
+
(!Array.isArray(subscriptionOffers) ||
|
|
1837
|
+
subscriptionOffers.some((offer) => {
|
|
1838
|
+
if (offer == null || typeof offer !== 'object') {
|
|
1839
|
+
return true;
|
|
1840
|
+
}
|
|
1841
|
+
const candidate = offer as Record<string, unknown>;
|
|
1842
|
+
return (
|
|
1843
|
+
typeof candidate.sku !== 'string' ||
|
|
1844
|
+
candidate.sku.trim() === '' ||
|
|
1845
|
+
typeof candidate.offerToken !== 'string' ||
|
|
1846
|
+
candidate.offerToken.trim() === ''
|
|
1847
|
+
);
|
|
1848
|
+
}))
|
|
1849
|
+
) {
|
|
1850
|
+
throw createPurchaseError({
|
|
1851
|
+
message:
|
|
1852
|
+
'Invalid request for Android. Every subscription offer must include non-empty `sku` and `offerToken` strings.',
|
|
1853
|
+
code: ErrorCode.DeveloperError,
|
|
1854
|
+
});
|
|
1855
|
+
}
|
|
1791
1856
|
if (subsRequest.purchaseToken) {
|
|
1792
1857
|
androidPayload.purchaseToken = subsRequest.purchaseToken;
|
|
1793
1858
|
}
|
|
@@ -1800,15 +1865,11 @@ export const requestPurchase: MutationField<'requestPurchase'> = async (
|
|
|
1800
1865
|
subsRequest.subscriptionProductReplacementParams;
|
|
1801
1866
|
}
|
|
1802
1867
|
androidPayload.subscriptionOffers = (
|
|
1803
|
-
|
|
1804
|
-
)
|
|
1805
|
-
.
|
|
1806
|
-
|
|
1807
|
-
|
|
1808
|
-
.map((offer) => ({
|
|
1809
|
-
sku: offer.sku,
|
|
1810
|
-
offerToken: offer.offerToken,
|
|
1811
|
-
}));
|
|
1868
|
+
(subscriptionOffers ?? []) as AndroidSubscriptionOfferInput[]
|
|
1869
|
+
).map((offer) => ({
|
|
1870
|
+
sku: offer.sku,
|
|
1871
|
+
offerToken: offer.offerToken,
|
|
1872
|
+
}));
|
|
1812
1873
|
}
|
|
1813
1874
|
|
|
1814
1875
|
unifiedRequest.google = androidPayload;
|
|
@@ -2135,11 +2196,20 @@ export const verifyPurchase: MutationField<'verifyPurchase'> = async (
|
|
|
2135
2196
|
: undefined,
|
|
2136
2197
|
};
|
|
2137
2198
|
return result;
|
|
2199
|
+
} else if (params.horizon !== null) {
|
|
2200
|
+
const horizonResult =
|
|
2201
|
+
nitroResult as NitroPurchaseVerificationResultHorizon;
|
|
2202
|
+
const result: VerifyPurchaseResultHorizon = {
|
|
2203
|
+
isValid: horizonResult.isValid,
|
|
2204
|
+
grantTime: horizonResult.grantTime,
|
|
2205
|
+
success: horizonResult.success,
|
|
2206
|
+
};
|
|
2207
|
+
return result;
|
|
2138
2208
|
} else {
|
|
2139
|
-
// Android
|
|
2140
2209
|
const androidResult =
|
|
2141
2210
|
nitroResult as NitroPurchaseVerificationResultAndroid;
|
|
2142
2211
|
const result: VerifyPurchaseResultAndroid = {
|
|
2212
|
+
isValid: androidResult.isValid,
|
|
2143
2213
|
autoRenewing: androidResult.autoRenewing,
|
|
2144
2214
|
betaProduct: androidResult.betaProduct,
|
|
2145
2215
|
cancelDate: androidResult.cancelDate,
|
package/src/kit-api.ts
CHANGED
|
@@ -31,7 +31,15 @@ export type KitSubscription = {
|
|
|
31
31
|
id: string;
|
|
32
32
|
productId: string;
|
|
33
33
|
platform: "IOS" | "Android";
|
|
34
|
-
state:
|
|
34
|
+
state:
|
|
35
|
+
| "Active"
|
|
36
|
+
| "InGracePeriod"
|
|
37
|
+
| "InBillingRetry"
|
|
38
|
+
| "Expired"
|
|
39
|
+
| "Revoked"
|
|
40
|
+
| "Refunded"
|
|
41
|
+
| "Paused"
|
|
42
|
+
| "Unknown";
|
|
35
43
|
expiresAt?: number;
|
|
36
44
|
renewsAt?: number;
|
|
37
45
|
willRenew?: boolean;
|
|
@@ -41,6 +49,7 @@ export type KitSubscription = {
|
|
|
41
49
|
startedAt: number;
|
|
42
50
|
updatedAt: number;
|
|
43
51
|
purchaseToken: string;
|
|
52
|
+
originalTransactionId?: string;
|
|
44
53
|
userId?: string;
|
|
45
54
|
};
|
|
46
55
|
|
|
@@ -58,7 +67,8 @@ export type StatusResponse = {
|
|
|
58
67
|
export type KitProductPlatform = "IOS" | "Android";
|
|
59
68
|
|
|
60
69
|
export type KitProductClientPayload = {
|
|
61
|
-
|
|
70
|
+
/** Current values are toml, json, and text; preserve unknown values. */
|
|
71
|
+
format: string;
|
|
62
72
|
body: string;
|
|
63
73
|
version: number;
|
|
64
74
|
updatedAt: number;
|
|
@@ -84,6 +94,13 @@ export type KitProduct = {
|
|
|
84
94
|
type: "Subscription" | "NonConsumable" | "Consumable";
|
|
85
95
|
title: string;
|
|
86
96
|
description?: string;
|
|
97
|
+
baseLocale?: string;
|
|
98
|
+
localizations?: Array<{
|
|
99
|
+
locale: string;
|
|
100
|
+
title: string;
|
|
101
|
+
description?: string;
|
|
102
|
+
}>;
|
|
103
|
+
regions?: "all" | string[];
|
|
87
104
|
priceAmountMicros?: number;
|
|
88
105
|
currency?: string;
|
|
89
106
|
state: "Draft" | "Ready" | "Active" | "Removed";
|
|
@@ -113,6 +130,108 @@ export type KitProductsResponse = {
|
|
|
113
130
|
nextCursor?: string;
|
|
114
131
|
};
|
|
115
132
|
|
|
133
|
+
export type KitSubscriptionsResponse = {
|
|
134
|
+
items: KitSubscription[];
|
|
135
|
+
total: number;
|
|
136
|
+
};
|
|
137
|
+
|
|
138
|
+
export type KitMrrCurrencyEntry = {
|
|
139
|
+
currency: string;
|
|
140
|
+
mrrMicros: number;
|
|
141
|
+
};
|
|
142
|
+
|
|
143
|
+
export type KitMetricsResponse = {
|
|
144
|
+
activeSubs: number;
|
|
145
|
+
inGracePeriod: number;
|
|
146
|
+
inBillingRetry: number;
|
|
147
|
+
refunded30d: number;
|
|
148
|
+
canceled30d: number;
|
|
149
|
+
mrrMicros: number;
|
|
150
|
+
currency: string;
|
|
151
|
+
reportingCurrency: string;
|
|
152
|
+
mrrByCurrency: KitMrrCurrencyEntry[];
|
|
153
|
+
excludedMrrByCurrency: KitMrrCurrencyEntry[];
|
|
154
|
+
};
|
|
155
|
+
|
|
156
|
+
export type KitRevenueMetricsResponse = {
|
|
157
|
+
days: Array<{
|
|
158
|
+
day: string;
|
|
159
|
+
currency: string;
|
|
160
|
+
productId: string;
|
|
161
|
+
platform: KitProductPlatform;
|
|
162
|
+
activeSubs: number;
|
|
163
|
+
newSubs: number;
|
|
164
|
+
renewals: number;
|
|
165
|
+
cancellations: number;
|
|
166
|
+
refunds: number;
|
|
167
|
+
revenueMicros: number;
|
|
168
|
+
}>;
|
|
169
|
+
currencies: string[];
|
|
170
|
+
productIds: string[];
|
|
171
|
+
platforms: KitProductPlatform[];
|
|
172
|
+
truncated: boolean;
|
|
173
|
+
};
|
|
174
|
+
|
|
175
|
+
export type KitProductUpsertResponse = { id: string; created: boolean };
|
|
176
|
+
export type KitProductStateResponse = {
|
|
177
|
+
id: string;
|
|
178
|
+
state: KitProduct["state"];
|
|
179
|
+
};
|
|
180
|
+
export type KitClientPayloadStateResponse = {
|
|
181
|
+
expectedVersion: number;
|
|
182
|
+
clientPayload?: KitProductClientPayload;
|
|
183
|
+
};
|
|
184
|
+
export type KitSetClientPayloadResponse = {
|
|
185
|
+
id: string;
|
|
186
|
+
created: boolean;
|
|
187
|
+
changed: boolean;
|
|
188
|
+
version: number;
|
|
189
|
+
updatedAt: number;
|
|
190
|
+
};
|
|
191
|
+
export type KitRemoveClientPayloadResponse = { ok: boolean };
|
|
192
|
+
export type KitProductSyncResponse = { jobId: string; deduped: boolean };
|
|
193
|
+
export type KitProductSyncJobResponse = {
|
|
194
|
+
_id: string;
|
|
195
|
+
_creationTime: number;
|
|
196
|
+
projectId: string;
|
|
197
|
+
platform: KitProductPlatform;
|
|
198
|
+
direction: "pull" | "push" | "both" | "purge-local";
|
|
199
|
+
dryRun: boolean;
|
|
200
|
+
status: "queued" | "running" | "succeeded" | "failed";
|
|
201
|
+
progress: {
|
|
202
|
+
phase: string;
|
|
203
|
+
current?: number;
|
|
204
|
+
total?: number;
|
|
205
|
+
failuresCount?: number;
|
|
206
|
+
};
|
|
207
|
+
result?: {
|
|
208
|
+
pulled: number;
|
|
209
|
+
pushed: number;
|
|
210
|
+
deleted?: number;
|
|
211
|
+
failures: Array<{ productId: string; reason: string }>;
|
|
212
|
+
failuresTruncated?: boolean;
|
|
213
|
+
plannedWrites?: Array<{
|
|
214
|
+
productId: string;
|
|
215
|
+
step: string;
|
|
216
|
+
detail?: string;
|
|
217
|
+
}>;
|
|
218
|
+
plannedWritesTruncated?: boolean;
|
|
219
|
+
manualActions?: Array<{
|
|
220
|
+
productId: string;
|
|
221
|
+
code: string;
|
|
222
|
+
message: string;
|
|
223
|
+
}>;
|
|
224
|
+
manualActionsTruncated?: boolean;
|
|
225
|
+
};
|
|
226
|
+
error?: string;
|
|
227
|
+
cancelRequested?: boolean;
|
|
228
|
+
expectedDeadline?: number;
|
|
229
|
+
createdBy?: string;
|
|
230
|
+
startedAt?: number;
|
|
231
|
+
completedAt?: number;
|
|
232
|
+
createdAt: number;
|
|
233
|
+
};
|
|
234
|
+
|
|
116
235
|
export type KitClientPayloadResponse = {
|
|
117
236
|
clientPayload: KitProductClientPayload;
|
|
118
237
|
};
|
|
@@ -135,7 +254,7 @@ const DEFAULT_BASE_URL = "https://kit.openiap.dev";
|
|
|
135
254
|
function mergeHeaders(
|
|
136
255
|
callerHeaders: Record<string, string> | undefined,
|
|
137
256
|
hasBody: boolean,
|
|
138
|
-
):
|
|
257
|
+
): RequestInit["headers"] {
|
|
139
258
|
if (typeof Headers === "function") {
|
|
140
259
|
const merged = new Headers(callerHeaders);
|
|
141
260
|
if (!merged.has("accept")) merged.set("accept", "application/json");
|
|
@@ -283,9 +402,11 @@ export function kitApi(options: KitApiOptions) {
|
|
|
283
402
|
if (!raw) return null;
|
|
284
403
|
const candidate = JSON.parse(raw) as Partial<CachedClientPayload>;
|
|
285
404
|
const payload = candidate.clientPayload;
|
|
405
|
+
// Only the invariants the cache depends on. `format` is opaque: evicting
|
|
406
|
+
// on an unknown one would kill ETag revalidation and offline reads.
|
|
286
407
|
if (
|
|
287
408
|
!payload ||
|
|
288
|
-
|
|
409
|
+
typeof payload.format !== "string" ||
|
|
289
410
|
typeof payload.body !== "string" ||
|
|
290
411
|
!Number.isSafeInteger(payload.version) ||
|
|
291
412
|
payload.version < 1 ||
|
package/src/specs/RnIap.nitro.ts
CHANGED
|
@@ -55,6 +55,7 @@ import type {
|
|
|
55
55
|
VerifyPurchaseGoogleOptions,
|
|
56
56
|
VerifyPurchaseHorizonOptions,
|
|
57
57
|
VerifyPurchaseResultAndroid,
|
|
58
|
+
VerifyPurchaseResultHorizon,
|
|
58
59
|
RequestPurchaseIosProps,
|
|
59
60
|
RequestPurchaseResult,
|
|
60
61
|
RequestSubscriptionAndroidProps,
|
|
@@ -408,6 +409,7 @@ export interface NitroPurchaseVerificationResultIOS {
|
|
|
408
409
|
}
|
|
409
410
|
|
|
410
411
|
export interface NitroPurchaseVerificationResultAndroid {
|
|
412
|
+
isValid: VerifyPurchaseResultAndroid['isValid'];
|
|
411
413
|
autoRenewing: VerifyPurchaseResultAndroid['autoRenewing'];
|
|
412
414
|
betaProduct: VerifyPurchaseResultAndroid['betaProduct'];
|
|
413
415
|
cancelDate: VerifyPurchaseResultAndroid['cancelDate'];
|
|
@@ -428,6 +430,12 @@ export interface NitroPurchaseVerificationResultAndroid {
|
|
|
428
430
|
testTransaction: VerifyPurchaseResultAndroid['testTransaction'];
|
|
429
431
|
}
|
|
430
432
|
|
|
433
|
+
export interface NitroPurchaseVerificationResultHorizon {
|
|
434
|
+
isValid: VerifyPurchaseResultHorizon['isValid'];
|
|
435
|
+
grantTime?: VerifyPurchaseResultHorizon['grantTime'];
|
|
436
|
+
success: VerifyPurchaseResultHorizon['success'];
|
|
437
|
+
}
|
|
438
|
+
|
|
431
439
|
// VerifyPurchaseWithProvider types
|
|
432
440
|
|
|
433
441
|
export interface NitroVerifyPurchaseWithIapkitAppleProps {
|
|
@@ -994,12 +1002,14 @@ export interface RnIap extends HybridObject<{ios: 'swift'; android: 'kotlin'}> {
|
|
|
994
1002
|
/**
|
|
995
1003
|
* Verify a purchase on the appropriate platform.
|
|
996
1004
|
* @param params - Purchase verification parameters including platform-specific options
|
|
997
|
-
* @returns Promise
|
|
1005
|
+
* @returns Promise with the platform-specific verification result
|
|
998
1006
|
*/
|
|
999
1007
|
verifyPurchase(
|
|
1000
1008
|
params: NitroPurchaseVerificationParams,
|
|
1001
1009
|
): Promise<
|
|
1002
|
-
|
|
1010
|
+
| NitroPurchaseVerificationResultIOS
|
|
1011
|
+
| NitroPurchaseVerificationResultAndroid
|
|
1012
|
+
| NitroPurchaseVerificationResultHorizon
|
|
1003
1013
|
>;
|
|
1004
1014
|
|
|
1005
1015
|
/**
|