react-native-iap 14.2.3 → 14.3.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +2 -6
- package/android/build.gradle +4 -5
- package/android/src/main/java/com/margelo/nitro/iap/HybridRnIap.kt +327 -547
- package/ios/HybridRnIap.swift +41 -19
- package/lib/module/helpers/subscription.js +2 -2
- package/lib/module/helpers/subscription.js.map +1 -1
- package/lib/module/index.js +44 -1
- package/lib/module/index.js.map +1 -1
- package/lib/module/types.js.map +1 -1
- package/lib/module/utils/type-bridge.js +1 -2
- package/lib/module/utils/type-bridge.js.map +1 -1
- package/lib/typescript/plugin/src/withIAP.d.ts.map +1 -1
- package/lib/typescript/src/helpers/subscription.d.ts.map +1 -1
- package/lib/typescript/src/index.d.ts +15 -0
- package/lib/typescript/src/index.d.ts.map +1 -1
- package/lib/typescript/src/specs/RnIap.nitro.d.ts +17 -0
- package/lib/typescript/src/specs/RnIap.nitro.d.ts.map +1 -1
- package/lib/typescript/src/types.d.ts +0 -2
- package/lib/typescript/src/types.d.ts.map +1 -1
- package/nitrogen/generated/android/c++/JHybridRnIapSpec.cpp +35 -0
- package/nitrogen/generated/android/c++/JHybridRnIapSpec.hpp +2 -0
- package/nitrogen/generated/android/c++/JNitroDeepLinkOptionsAndroid.hpp +58 -0
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/iap/HybridRnIapSpec.kt +8 -0
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/iap/NitroDeepLinkOptionsAndroid.kt +32 -0
- package/nitrogen/generated/ios/NitroIap-Swift-Cxx-Umbrella.hpp +3 -0
- package/nitrogen/generated/ios/c++/HybridRnIapSpecSwift.hpp +19 -0
- package/nitrogen/generated/ios/swift/HybridRnIapSpec.swift +2 -0
- package/nitrogen/generated/ios/swift/HybridRnIapSpec_cxx.swift +38 -0
- package/nitrogen/generated/ios/swift/NitroDeepLinkOptionsAndroid.swift +84 -0
- package/nitrogen/generated/shared/c++/HybridRnIapSpec.cpp +2 -0
- package/nitrogen/generated/shared/c++/HybridRnIapSpec.hpp +5 -0
- package/nitrogen/generated/shared/c++/NitroDeepLinkOptionsAndroid.hpp +72 -0
- package/package.json +1 -1
- package/plugin/build/withIAP.js +21 -18
- package/plugin/src/withIAP.ts +31 -23
- package/src/helpers/subscription.ts +2 -5
- package/src/index.ts +49 -2
- package/src/specs/RnIap.nitro.ts +22 -0
- package/src/types.ts +0 -2
- package/src/utils/type-bridge.ts +1 -1
|
@@ -45,6 +45,8 @@ namespace margelo::nitro::iap { struct NitroFinishTransactionAndroidParams; }
|
|
|
45
45
|
namespace margelo::nitro::iap { struct NitroReceiptValidationParams; }
|
|
46
46
|
// Forward declaration of `NitroAndroidReceiptValidationOptions` to properly resolve imports.
|
|
47
47
|
namespace margelo::nitro::iap { struct NitroAndroidReceiptValidationOptions; }
|
|
48
|
+
// Forward declaration of `NitroDeepLinkOptionsAndroid` to properly resolve imports.
|
|
49
|
+
namespace margelo::nitro::iap { struct NitroDeepLinkOptionsAndroid; }
|
|
48
50
|
|
|
49
51
|
#include <NitroModules/Promise.hpp>
|
|
50
52
|
#include <NitroModules/JPromise.hpp>
|
|
@@ -97,6 +99,8 @@ namespace margelo::nitro::iap { struct NitroAndroidReceiptValidationOptions; }
|
|
|
97
99
|
#include "JNitroReceiptValidationParams.hpp"
|
|
98
100
|
#include "NitroAndroidReceiptValidationOptions.hpp"
|
|
99
101
|
#include "JNitroAndroidReceiptValidationOptions.hpp"
|
|
102
|
+
#include "NitroDeepLinkOptionsAndroid.hpp"
|
|
103
|
+
#include "JNitroDeepLinkOptionsAndroid.hpp"
|
|
100
104
|
|
|
101
105
|
namespace margelo::nitro::iap {
|
|
102
106
|
|
|
@@ -582,5 +586,36 @@ namespace margelo::nitro::iap {
|
|
|
582
586
|
return __promise;
|
|
583
587
|
}();
|
|
584
588
|
}
|
|
589
|
+
std::shared_ptr<Promise<std::string>> JHybridRnIapSpec::getStorefrontAndroid() {
|
|
590
|
+
static const auto method = javaClassStatic()->getMethod<jni::local_ref<JPromise::javaobject>()>("getStorefrontAndroid");
|
|
591
|
+
auto __result = method(_javaPart);
|
|
592
|
+
return [&]() {
|
|
593
|
+
auto __promise = Promise<std::string>::create();
|
|
594
|
+
__result->cthis()->addOnResolvedListener([=](const jni::alias_ref<jni::JObject>& __boxedResult) {
|
|
595
|
+
auto __result = jni::static_ref_cast<jni::JString>(__boxedResult);
|
|
596
|
+
__promise->resolve(__result->toStdString());
|
|
597
|
+
});
|
|
598
|
+
__result->cthis()->addOnRejectedListener([=](const jni::alias_ref<jni::JThrowable>& __throwable) {
|
|
599
|
+
jni::JniException __jniError(__throwable);
|
|
600
|
+
__promise->reject(std::make_exception_ptr(__jniError));
|
|
601
|
+
});
|
|
602
|
+
return __promise;
|
|
603
|
+
}();
|
|
604
|
+
}
|
|
605
|
+
std::shared_ptr<Promise<void>> JHybridRnIapSpec::deepLinkToSubscriptionsAndroid(const NitroDeepLinkOptionsAndroid& options) {
|
|
606
|
+
static const auto method = javaClassStatic()->getMethod<jni::local_ref<JPromise::javaobject>(jni::alias_ref<JNitroDeepLinkOptionsAndroid> /* options */)>("deepLinkToSubscriptionsAndroid");
|
|
607
|
+
auto __result = method(_javaPart, JNitroDeepLinkOptionsAndroid::fromCpp(options));
|
|
608
|
+
return [&]() {
|
|
609
|
+
auto __promise = Promise<void>::create();
|
|
610
|
+
__result->cthis()->addOnResolvedListener([=](const jni::alias_ref<jni::JObject>& /* unit */) {
|
|
611
|
+
__promise->resolve();
|
|
612
|
+
});
|
|
613
|
+
__result->cthis()->addOnRejectedListener([=](const jni::alias_ref<jni::JThrowable>& __throwable) {
|
|
614
|
+
jni::JniException __jniError(__throwable);
|
|
615
|
+
__promise->reject(std::make_exception_ptr(__jniError));
|
|
616
|
+
});
|
|
617
|
+
return __promise;
|
|
618
|
+
}();
|
|
619
|
+
}
|
|
585
620
|
|
|
586
621
|
} // namespace margelo::nitro::iap
|
|
@@ -83,6 +83,8 @@ namespace margelo::nitro::iap {
|
|
|
83
83
|
std::shared_ptr<Promise<bool>> isTransactionVerifiedIOS(const std::string& sku) override;
|
|
84
84
|
std::shared_ptr<Promise<std::optional<std::string>>> getTransactionJwsIOS(const std::string& sku) override;
|
|
85
85
|
std::shared_ptr<Promise<std::variant<NitroReceiptValidationResultIOS, NitroReceiptValidationResultAndroid>>> validateReceipt(const NitroReceiptValidationParams& params) override;
|
|
86
|
+
std::shared_ptr<Promise<std::string>> getStorefrontAndroid() override;
|
|
87
|
+
std::shared_ptr<Promise<void>> deepLinkToSubscriptionsAndroid(const NitroDeepLinkOptionsAndroid& options) override;
|
|
86
88
|
|
|
87
89
|
private:
|
|
88
90
|
friend HybridBase;
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
///
|
|
2
|
+
/// JNitroDeepLinkOptionsAndroid.hpp
|
|
3
|
+
/// This file was generated by nitrogen. DO NOT MODIFY THIS FILE.
|
|
4
|
+
/// https://github.com/mrousavy/nitro
|
|
5
|
+
/// Copyright © 2025 Marc Rousavy @ Margelo
|
|
6
|
+
///
|
|
7
|
+
|
|
8
|
+
#pragma once
|
|
9
|
+
|
|
10
|
+
#include <fbjni/fbjni.h>
|
|
11
|
+
#include "NitroDeepLinkOptionsAndroid.hpp"
|
|
12
|
+
|
|
13
|
+
#include <optional>
|
|
14
|
+
#include <string>
|
|
15
|
+
|
|
16
|
+
namespace margelo::nitro::iap {
|
|
17
|
+
|
|
18
|
+
using namespace facebook;
|
|
19
|
+
|
|
20
|
+
/**
|
|
21
|
+
* The C++ JNI bridge between the C++ struct "NitroDeepLinkOptionsAndroid" and the the Kotlin data class "NitroDeepLinkOptionsAndroid".
|
|
22
|
+
*/
|
|
23
|
+
struct JNitroDeepLinkOptionsAndroid final: public jni::JavaClass<JNitroDeepLinkOptionsAndroid> {
|
|
24
|
+
public:
|
|
25
|
+
static auto constexpr kJavaDescriptor = "Lcom/margelo/nitro/iap/NitroDeepLinkOptionsAndroid;";
|
|
26
|
+
|
|
27
|
+
public:
|
|
28
|
+
/**
|
|
29
|
+
* Convert this Java/Kotlin-based struct to the C++ struct NitroDeepLinkOptionsAndroid by copying all values to C++.
|
|
30
|
+
*/
|
|
31
|
+
[[maybe_unused]]
|
|
32
|
+
[[nodiscard]]
|
|
33
|
+
NitroDeepLinkOptionsAndroid toCpp() const {
|
|
34
|
+
static const auto clazz = javaClassStatic();
|
|
35
|
+
static const auto fieldSkuAndroid = clazz->getField<jni::JString>("skuAndroid");
|
|
36
|
+
jni::local_ref<jni::JString> skuAndroid = this->getFieldValue(fieldSkuAndroid);
|
|
37
|
+
static const auto fieldPackageNameAndroid = clazz->getField<jni::JString>("packageNameAndroid");
|
|
38
|
+
jni::local_ref<jni::JString> packageNameAndroid = this->getFieldValue(fieldPackageNameAndroid);
|
|
39
|
+
return NitroDeepLinkOptionsAndroid(
|
|
40
|
+
skuAndroid != nullptr ? std::make_optional(skuAndroid->toStdString()) : std::nullopt,
|
|
41
|
+
packageNameAndroid != nullptr ? std::make_optional(packageNameAndroid->toStdString()) : std::nullopt
|
|
42
|
+
);
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
public:
|
|
46
|
+
/**
|
|
47
|
+
* Create a Java/Kotlin-based struct by copying all values from the given C++ struct to Java.
|
|
48
|
+
*/
|
|
49
|
+
[[maybe_unused]]
|
|
50
|
+
static jni::local_ref<JNitroDeepLinkOptionsAndroid::javaobject> fromCpp(const NitroDeepLinkOptionsAndroid& value) {
|
|
51
|
+
return newInstance(
|
|
52
|
+
value.skuAndroid.has_value() ? jni::make_jstring(value.skuAndroid.value()) : nullptr,
|
|
53
|
+
value.packageNameAndroid.has_value() ? jni::make_jstring(value.packageNameAndroid.value()) : nullptr
|
|
54
|
+
);
|
|
55
|
+
}
|
|
56
|
+
};
|
|
57
|
+
|
|
58
|
+
} // namespace margelo::nitro::iap
|
|
@@ -189,6 +189,14 @@ abstract class HybridRnIapSpec: HybridObject() {
|
|
|
189
189
|
@DoNotStrip
|
|
190
190
|
@Keep
|
|
191
191
|
abstract fun validateReceipt(params: NitroReceiptValidationParams): Promise<Variant_NitroReceiptValidationResultIOS_NitroReceiptValidationResultAndroid>
|
|
192
|
+
|
|
193
|
+
@DoNotStrip
|
|
194
|
+
@Keep
|
|
195
|
+
abstract fun getStorefrontAndroid(): Promise<String>
|
|
196
|
+
|
|
197
|
+
@DoNotStrip
|
|
198
|
+
@Keep
|
|
199
|
+
abstract fun deepLinkToSubscriptionsAndroid(options: NitroDeepLinkOptionsAndroid): Promise<Unit>
|
|
192
200
|
|
|
193
201
|
private external fun initHybrid(): HybridData
|
|
194
202
|
|
package/nitrogen/generated/android/kotlin/com/margelo/nitro/iap/NitroDeepLinkOptionsAndroid.kt
ADDED
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
///
|
|
2
|
+
/// NitroDeepLinkOptionsAndroid.kt
|
|
3
|
+
/// This file was generated by nitrogen. DO NOT MODIFY THIS FILE.
|
|
4
|
+
/// https://github.com/mrousavy/nitro
|
|
5
|
+
/// Copyright © 2025 Marc Rousavy @ Margelo
|
|
6
|
+
///
|
|
7
|
+
|
|
8
|
+
package com.margelo.nitro.iap
|
|
9
|
+
|
|
10
|
+
import androidx.annotation.Keep
|
|
11
|
+
import com.facebook.proguard.annotations.DoNotStrip
|
|
12
|
+
import com.margelo.nitro.core.*
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
/**
|
|
16
|
+
* Represents the JavaScript object/struct "NitroDeepLinkOptionsAndroid".
|
|
17
|
+
*/
|
|
18
|
+
@DoNotStrip
|
|
19
|
+
@Keep
|
|
20
|
+
data class NitroDeepLinkOptionsAndroid
|
|
21
|
+
@DoNotStrip
|
|
22
|
+
@Keep
|
|
23
|
+
constructor(
|
|
24
|
+
@DoNotStrip
|
|
25
|
+
@Keep
|
|
26
|
+
val skuAndroid: String?,
|
|
27
|
+
@DoNotStrip
|
|
28
|
+
@Keep
|
|
29
|
+
val packageNameAndroid: String?
|
|
30
|
+
) {
|
|
31
|
+
/* main constructor */
|
|
32
|
+
}
|
|
@@ -18,6 +18,8 @@ namespace margelo::nitro::iap { struct NitroAvailablePurchasesAndroidOptions; }
|
|
|
18
18
|
namespace margelo::nitro::iap { struct NitroAvailablePurchasesIosOptions; }
|
|
19
19
|
// Forward declaration of `NitroAvailablePurchasesOptions` to properly resolve imports.
|
|
20
20
|
namespace margelo::nitro::iap { struct NitroAvailablePurchasesOptions; }
|
|
21
|
+
// Forward declaration of `NitroDeepLinkOptionsAndroid` to properly resolve imports.
|
|
22
|
+
namespace margelo::nitro::iap { struct NitroDeepLinkOptionsAndroid; }
|
|
21
23
|
// Forward declaration of `NitroFinishTransactionAndroidParams` to properly resolve imports.
|
|
22
24
|
namespace margelo::nitro::iap { struct NitroFinishTransactionAndroidParams; }
|
|
23
25
|
// Forward declaration of `NitroFinishTransactionIosParams` to properly resolve imports.
|
|
@@ -55,6 +57,7 @@ namespace margelo::nitro::iap { struct NitroSubscriptionStatus; }
|
|
|
55
57
|
#include "NitroAvailablePurchasesAndroidOptions.hpp"
|
|
56
58
|
#include "NitroAvailablePurchasesIosOptions.hpp"
|
|
57
59
|
#include "NitroAvailablePurchasesOptions.hpp"
|
|
60
|
+
#include "NitroDeepLinkOptionsAndroid.hpp"
|
|
58
61
|
#include "NitroFinishTransactionAndroidParams.hpp"
|
|
59
62
|
#include "NitroFinishTransactionIosParams.hpp"
|
|
60
63
|
#include "NitroFinishTransactionParams.hpp"
|
|
@@ -50,6 +50,8 @@ namespace margelo::nitro::iap { struct NitroReceiptValidationResultAndroid; }
|
|
|
50
50
|
namespace margelo::nitro::iap { struct NitroReceiptValidationParams; }
|
|
51
51
|
// Forward declaration of `NitroAndroidReceiptValidationOptions` to properly resolve imports.
|
|
52
52
|
namespace margelo::nitro::iap { struct NitroAndroidReceiptValidationOptions; }
|
|
53
|
+
// Forward declaration of `NitroDeepLinkOptionsAndroid` to properly resolve imports.
|
|
54
|
+
namespace margelo::nitro::iap { struct NitroDeepLinkOptionsAndroid; }
|
|
53
55
|
|
|
54
56
|
#include <NitroModules/Promise.hpp>
|
|
55
57
|
#include "NitroProduct.hpp"
|
|
@@ -77,6 +79,7 @@ namespace margelo::nitro::iap { struct NitroAndroidReceiptValidationOptions; }
|
|
|
77
79
|
#include "NitroReceiptValidationResultAndroid.hpp"
|
|
78
80
|
#include "NitroReceiptValidationParams.hpp"
|
|
79
81
|
#include "NitroAndroidReceiptValidationOptions.hpp"
|
|
82
|
+
#include "NitroDeepLinkOptionsAndroid.hpp"
|
|
80
83
|
|
|
81
84
|
#include "NitroIap-Swift-Cxx-Umbrella.hpp"
|
|
82
85
|
|
|
@@ -347,6 +350,22 @@ namespace margelo::nitro::iap {
|
|
|
347
350
|
auto __value = std::move(__result.value());
|
|
348
351
|
return __value;
|
|
349
352
|
}
|
|
353
|
+
inline std::shared_ptr<Promise<std::string>> getStorefrontAndroid() override {
|
|
354
|
+
auto __result = _swiftPart.getStorefrontAndroid();
|
|
355
|
+
if (__result.hasError()) [[unlikely]] {
|
|
356
|
+
std::rethrow_exception(__result.error());
|
|
357
|
+
}
|
|
358
|
+
auto __value = std::move(__result.value());
|
|
359
|
+
return __value;
|
|
360
|
+
}
|
|
361
|
+
inline std::shared_ptr<Promise<void>> deepLinkToSubscriptionsAndroid(const NitroDeepLinkOptionsAndroid& options) override {
|
|
362
|
+
auto __result = _swiftPart.deepLinkToSubscriptionsAndroid(options);
|
|
363
|
+
if (__result.hasError()) [[unlikely]] {
|
|
364
|
+
std::rethrow_exception(__result.error());
|
|
365
|
+
}
|
|
366
|
+
auto __value = std::move(__result.value());
|
|
367
|
+
return __value;
|
|
368
|
+
}
|
|
350
369
|
|
|
351
370
|
private:
|
|
352
371
|
NitroIap::HybridRnIapSpec_cxx _swiftPart;
|
|
@@ -44,6 +44,8 @@ public protocol HybridRnIapSpec_protocol: HybridObject {
|
|
|
44
44
|
func isTransactionVerifiedIOS(sku: String) throws -> Promise<Bool>
|
|
45
45
|
func getTransactionJwsIOS(sku: String) throws -> Promise<String?>
|
|
46
46
|
func validateReceipt(params: NitroReceiptValidationParams) throws -> Promise<Variant_NitroReceiptValidationResultIOS_NitroReceiptValidationResultAndroid>
|
|
47
|
+
func getStorefrontAndroid() throws -> Promise<String>
|
|
48
|
+
func deepLinkToSubscriptionsAndroid(options: NitroDeepLinkOptionsAndroid) throws -> Promise<Void>
|
|
47
49
|
}
|
|
48
50
|
|
|
49
51
|
/// See ``HybridRnIapSpec``
|
|
@@ -753,4 +753,42 @@ open class HybridRnIapSpec_cxx {
|
|
|
753
753
|
return bridge.create_Result_std__shared_ptr_Promise_std__variant_NitroReceiptValidationResultIOS__NitroReceiptValidationResultAndroid____(__exceptionPtr)
|
|
754
754
|
}
|
|
755
755
|
}
|
|
756
|
+
|
|
757
|
+
@inline(__always)
|
|
758
|
+
public final func getStorefrontAndroid() -> bridge.Result_std__shared_ptr_Promise_std__string___ {
|
|
759
|
+
do {
|
|
760
|
+
let __result = try self.__implementation.getStorefrontAndroid()
|
|
761
|
+
let __resultCpp = { () -> bridge.std__shared_ptr_Promise_std__string__ in
|
|
762
|
+
let __promise = bridge.create_std__shared_ptr_Promise_std__string__()
|
|
763
|
+
let __promiseHolder = bridge.wrap_std__shared_ptr_Promise_std__string__(__promise)
|
|
764
|
+
__result
|
|
765
|
+
.then({ __result in __promiseHolder.resolve(std.string(__result)) })
|
|
766
|
+
.catch({ __error in __promiseHolder.reject(__error.toCpp()) })
|
|
767
|
+
return __promise
|
|
768
|
+
}()
|
|
769
|
+
return bridge.create_Result_std__shared_ptr_Promise_std__string___(__resultCpp)
|
|
770
|
+
} catch (let __error) {
|
|
771
|
+
let __exceptionPtr = __error.toCpp()
|
|
772
|
+
return bridge.create_Result_std__shared_ptr_Promise_std__string___(__exceptionPtr)
|
|
773
|
+
}
|
|
774
|
+
}
|
|
775
|
+
|
|
776
|
+
@inline(__always)
|
|
777
|
+
public final func deepLinkToSubscriptionsAndroid(options: NitroDeepLinkOptionsAndroid) -> bridge.Result_std__shared_ptr_Promise_void___ {
|
|
778
|
+
do {
|
|
779
|
+
let __result = try self.__implementation.deepLinkToSubscriptionsAndroid(options: options)
|
|
780
|
+
let __resultCpp = { () -> bridge.std__shared_ptr_Promise_void__ in
|
|
781
|
+
let __promise = bridge.create_std__shared_ptr_Promise_void__()
|
|
782
|
+
let __promiseHolder = bridge.wrap_std__shared_ptr_Promise_void__(__promise)
|
|
783
|
+
__result
|
|
784
|
+
.then({ __result in __promiseHolder.resolve() })
|
|
785
|
+
.catch({ __error in __promiseHolder.reject(__error.toCpp()) })
|
|
786
|
+
return __promise
|
|
787
|
+
}()
|
|
788
|
+
return bridge.create_Result_std__shared_ptr_Promise_void___(__resultCpp)
|
|
789
|
+
} catch (let __error) {
|
|
790
|
+
let __exceptionPtr = __error.toCpp()
|
|
791
|
+
return bridge.create_Result_std__shared_ptr_Promise_void___(__exceptionPtr)
|
|
792
|
+
}
|
|
793
|
+
}
|
|
756
794
|
}
|
|
@@ -0,0 +1,84 @@
|
|
|
1
|
+
///
|
|
2
|
+
/// NitroDeepLinkOptionsAndroid.swift
|
|
3
|
+
/// This file was generated by nitrogen. DO NOT MODIFY THIS FILE.
|
|
4
|
+
/// https://github.com/mrousavy/nitro
|
|
5
|
+
/// Copyright © 2025 Marc Rousavy @ Margelo
|
|
6
|
+
///
|
|
7
|
+
|
|
8
|
+
import NitroModules
|
|
9
|
+
|
|
10
|
+
/**
|
|
11
|
+
* Represents an instance of `NitroDeepLinkOptionsAndroid`, backed by a C++ struct.
|
|
12
|
+
*/
|
|
13
|
+
public typealias NitroDeepLinkOptionsAndroid = margelo.nitro.iap.NitroDeepLinkOptionsAndroid
|
|
14
|
+
|
|
15
|
+
public extension NitroDeepLinkOptionsAndroid {
|
|
16
|
+
private typealias bridge = margelo.nitro.iap.bridge.swift
|
|
17
|
+
|
|
18
|
+
/**
|
|
19
|
+
* Create a new instance of `NitroDeepLinkOptionsAndroid`.
|
|
20
|
+
*/
|
|
21
|
+
init(skuAndroid: String?, packageNameAndroid: String?) {
|
|
22
|
+
self.init({ () -> bridge.std__optional_std__string_ in
|
|
23
|
+
if let __unwrappedValue = skuAndroid {
|
|
24
|
+
return bridge.create_std__optional_std__string_(std.string(__unwrappedValue))
|
|
25
|
+
} else {
|
|
26
|
+
return .init()
|
|
27
|
+
}
|
|
28
|
+
}(), { () -> bridge.std__optional_std__string_ in
|
|
29
|
+
if let __unwrappedValue = packageNameAndroid {
|
|
30
|
+
return bridge.create_std__optional_std__string_(std.string(__unwrappedValue))
|
|
31
|
+
} else {
|
|
32
|
+
return .init()
|
|
33
|
+
}
|
|
34
|
+
}())
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
var skuAndroid: String? {
|
|
38
|
+
@inline(__always)
|
|
39
|
+
get {
|
|
40
|
+
return { () -> String? in
|
|
41
|
+
if bridge.has_value_std__optional_std__string_(self.__skuAndroid) {
|
|
42
|
+
let __unwrapped = bridge.get_std__optional_std__string_(self.__skuAndroid)
|
|
43
|
+
return String(__unwrapped)
|
|
44
|
+
} else {
|
|
45
|
+
return nil
|
|
46
|
+
}
|
|
47
|
+
}()
|
|
48
|
+
}
|
|
49
|
+
@inline(__always)
|
|
50
|
+
set {
|
|
51
|
+
self.__skuAndroid = { () -> bridge.std__optional_std__string_ in
|
|
52
|
+
if let __unwrappedValue = newValue {
|
|
53
|
+
return bridge.create_std__optional_std__string_(std.string(__unwrappedValue))
|
|
54
|
+
} else {
|
|
55
|
+
return .init()
|
|
56
|
+
}
|
|
57
|
+
}()
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
var packageNameAndroid: String? {
|
|
62
|
+
@inline(__always)
|
|
63
|
+
get {
|
|
64
|
+
return { () -> String? in
|
|
65
|
+
if bridge.has_value_std__optional_std__string_(self.__packageNameAndroid) {
|
|
66
|
+
let __unwrapped = bridge.get_std__optional_std__string_(self.__packageNameAndroid)
|
|
67
|
+
return String(__unwrapped)
|
|
68
|
+
} else {
|
|
69
|
+
return nil
|
|
70
|
+
}
|
|
71
|
+
}()
|
|
72
|
+
}
|
|
73
|
+
@inline(__always)
|
|
74
|
+
set {
|
|
75
|
+
self.__packageNameAndroid = { () -> bridge.std__optional_std__string_ in
|
|
76
|
+
if let __unwrappedValue = newValue {
|
|
77
|
+
return bridge.create_std__optional_std__string_(std.string(__unwrappedValue))
|
|
78
|
+
} else {
|
|
79
|
+
return .init()
|
|
80
|
+
}
|
|
81
|
+
}()
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
}
|
|
@@ -44,6 +44,8 @@ namespace margelo::nitro::iap {
|
|
|
44
44
|
prototype.registerHybridMethod("isTransactionVerifiedIOS", &HybridRnIapSpec::isTransactionVerifiedIOS);
|
|
45
45
|
prototype.registerHybridMethod("getTransactionJwsIOS", &HybridRnIapSpec::getTransactionJwsIOS);
|
|
46
46
|
prototype.registerHybridMethod("validateReceipt", &HybridRnIapSpec::validateReceipt);
|
|
47
|
+
prototype.registerHybridMethod("getStorefrontAndroid", &HybridRnIapSpec::getStorefrontAndroid);
|
|
48
|
+
prototype.registerHybridMethod("deepLinkToSubscriptionsAndroid", &HybridRnIapSpec::deepLinkToSubscriptionsAndroid);
|
|
47
49
|
});
|
|
48
50
|
}
|
|
49
51
|
|
|
@@ -33,6 +33,8 @@ namespace margelo::nitro::iap { struct NitroReceiptValidationResultIOS; }
|
|
|
33
33
|
namespace margelo::nitro::iap { struct NitroReceiptValidationResultAndroid; }
|
|
34
34
|
// Forward declaration of `NitroReceiptValidationParams` to properly resolve imports.
|
|
35
35
|
namespace margelo::nitro::iap { struct NitroReceiptValidationParams; }
|
|
36
|
+
// Forward declaration of `NitroDeepLinkOptionsAndroid` to properly resolve imports.
|
|
37
|
+
namespace margelo::nitro::iap { struct NitroDeepLinkOptionsAndroid; }
|
|
36
38
|
|
|
37
39
|
#include <NitroModules/Promise.hpp>
|
|
38
40
|
#include "NitroProduct.hpp"
|
|
@@ -50,6 +52,7 @@ namespace margelo::nitro::iap { struct NitroReceiptValidationParams; }
|
|
|
50
52
|
#include "NitroReceiptValidationResultIOS.hpp"
|
|
51
53
|
#include "NitroReceiptValidationResultAndroid.hpp"
|
|
52
54
|
#include "NitroReceiptValidationParams.hpp"
|
|
55
|
+
#include "NitroDeepLinkOptionsAndroid.hpp"
|
|
53
56
|
|
|
54
57
|
namespace margelo::nitro::iap {
|
|
55
58
|
|
|
@@ -112,6 +115,8 @@ namespace margelo::nitro::iap {
|
|
|
112
115
|
virtual std::shared_ptr<Promise<bool>> isTransactionVerifiedIOS(const std::string& sku) = 0;
|
|
113
116
|
virtual std::shared_ptr<Promise<std::optional<std::string>>> getTransactionJwsIOS(const std::string& sku) = 0;
|
|
114
117
|
virtual std::shared_ptr<Promise<std::variant<NitroReceiptValidationResultIOS, NitroReceiptValidationResultAndroid>>> validateReceipt(const NitroReceiptValidationParams& params) = 0;
|
|
118
|
+
virtual std::shared_ptr<Promise<std::string>> getStorefrontAndroid() = 0;
|
|
119
|
+
virtual std::shared_ptr<Promise<void>> deepLinkToSubscriptionsAndroid(const NitroDeepLinkOptionsAndroid& options) = 0;
|
|
115
120
|
|
|
116
121
|
protected:
|
|
117
122
|
// Hybrid Setup
|
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
///
|
|
2
|
+
/// NitroDeepLinkOptionsAndroid.hpp
|
|
3
|
+
/// This file was generated by nitrogen. DO NOT MODIFY THIS FILE.
|
|
4
|
+
/// https://github.com/mrousavy/nitro
|
|
5
|
+
/// Copyright © 2025 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
|
+
|
|
21
|
+
|
|
22
|
+
|
|
23
|
+
#include <string>
|
|
24
|
+
#include <optional>
|
|
25
|
+
|
|
26
|
+
namespace margelo::nitro::iap {
|
|
27
|
+
|
|
28
|
+
/**
|
|
29
|
+
* A struct which can be represented as a JavaScript object (NitroDeepLinkOptionsAndroid).
|
|
30
|
+
*/
|
|
31
|
+
struct NitroDeepLinkOptionsAndroid {
|
|
32
|
+
public:
|
|
33
|
+
std::optional<std::string> skuAndroid SWIFT_PRIVATE;
|
|
34
|
+
std::optional<std::string> packageNameAndroid SWIFT_PRIVATE;
|
|
35
|
+
|
|
36
|
+
public:
|
|
37
|
+
NitroDeepLinkOptionsAndroid() = default;
|
|
38
|
+
explicit NitroDeepLinkOptionsAndroid(std::optional<std::string> skuAndroid, std::optional<std::string> packageNameAndroid): skuAndroid(skuAndroid), packageNameAndroid(packageNameAndroid) {}
|
|
39
|
+
};
|
|
40
|
+
|
|
41
|
+
} // namespace margelo::nitro::iap
|
|
42
|
+
|
|
43
|
+
namespace margelo::nitro {
|
|
44
|
+
|
|
45
|
+
// C++ NitroDeepLinkOptionsAndroid <> JS NitroDeepLinkOptionsAndroid (object)
|
|
46
|
+
template <>
|
|
47
|
+
struct JSIConverter<margelo::nitro::iap::NitroDeepLinkOptionsAndroid> final {
|
|
48
|
+
static inline margelo::nitro::iap::NitroDeepLinkOptionsAndroid fromJSI(jsi::Runtime& runtime, const jsi::Value& arg) {
|
|
49
|
+
jsi::Object obj = arg.asObject(runtime);
|
|
50
|
+
return margelo::nitro::iap::NitroDeepLinkOptionsAndroid(
|
|
51
|
+
JSIConverter<std::optional<std::string>>::fromJSI(runtime, obj.getProperty(runtime, "skuAndroid")),
|
|
52
|
+
JSIConverter<std::optional<std::string>>::fromJSI(runtime, obj.getProperty(runtime, "packageNameAndroid"))
|
|
53
|
+
);
|
|
54
|
+
}
|
|
55
|
+
static inline jsi::Value toJSI(jsi::Runtime& runtime, const margelo::nitro::iap::NitroDeepLinkOptionsAndroid& arg) {
|
|
56
|
+
jsi::Object obj(runtime);
|
|
57
|
+
obj.setProperty(runtime, "skuAndroid", JSIConverter<std::optional<std::string>>::toJSI(runtime, arg.skuAndroid));
|
|
58
|
+
obj.setProperty(runtime, "packageNameAndroid", JSIConverter<std::optional<std::string>>::toJSI(runtime, arg.packageNameAndroid));
|
|
59
|
+
return obj;
|
|
60
|
+
}
|
|
61
|
+
static inline bool canConvert(jsi::Runtime& runtime, const jsi::Value& value) {
|
|
62
|
+
if (!value.isObject()) {
|
|
63
|
+
return false;
|
|
64
|
+
}
|
|
65
|
+
jsi::Object obj = value.getObject(runtime);
|
|
66
|
+
if (!JSIConverter<std::optional<std::string>>::canConvert(runtime, obj.getProperty(runtime, "skuAndroid"))) return false;
|
|
67
|
+
if (!JSIConverter<std::optional<std::string>>::canConvert(runtime, obj.getProperty(runtime, "packageNameAndroid"))) return false;
|
|
68
|
+
return true;
|
|
69
|
+
}
|
|
70
|
+
};
|
|
71
|
+
|
|
72
|
+
} // namespace margelo::nitro
|
package/package.json
CHANGED
package/plugin/build/withIAP.js
CHANGED
|
@@ -18,12 +18,11 @@ const addLineToGradle = (content, anchor, lineToAdd, offset = 1) => {
|
|
|
18
18
|
return lines.join('\n');
|
|
19
19
|
};
|
|
20
20
|
const modifyProjectBuildGradle = (gradle) => {
|
|
21
|
-
//
|
|
21
|
+
// Keep backward-compatible behavior: add supportLibVersion inside ext { } if missing
|
|
22
22
|
if (!gradle.includes('supportLibVersion')) {
|
|
23
23
|
const lines = gradle.split('\n');
|
|
24
24
|
const extIndex = lines.findIndex((line) => line.trim() === 'ext {');
|
|
25
25
|
if (extIndex !== -1) {
|
|
26
|
-
// Insert supportLibVersion right after 'ext {' with proper indentation
|
|
27
26
|
lines.splice(extIndex + 1, 0, 'supportLibVersion = "28.0.0"');
|
|
28
27
|
return lines.join('\n');
|
|
29
28
|
}
|
|
@@ -31,28 +30,32 @@ const modifyProjectBuildGradle = (gradle) => {
|
|
|
31
30
|
return gradle;
|
|
32
31
|
};
|
|
33
32
|
exports.modifyProjectBuildGradle = modifyProjectBuildGradle;
|
|
33
|
+
const OPENIAP_COORD = 'io.github.hyochan.openiap:openiap-google';
|
|
34
|
+
const OPENIAP_VERSION = '1.1.0';
|
|
34
35
|
const modifyAppBuildGradle = (gradle) => {
|
|
35
36
|
let modified = gradle;
|
|
36
|
-
//
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
37
|
+
// Replace legacy Billing/GMS instructions with OpenIAP Google library
|
|
38
|
+
// Remove any old billingclient or play-services-base lines we may have added previously
|
|
39
|
+
modified = modified
|
|
40
|
+
.replace(/^[ \t]*(implementation|api)[ \t]+["']com\.android\.billingclient:billing-ktx:[^"']+["'][ \t]*$/gim, '')
|
|
41
|
+
.replace(/^[ \t]*(implementation|api)[ \t]+["']com\.google\.android\.gms:play-services-base:[^"']+["'][ \t]*$/gim, '')
|
|
42
|
+
.replace(/\n{3,}/g, '\n\n');
|
|
43
|
+
const openiapDep = ` implementation "${OPENIAP_COORD}:${OPENIAP_VERSION}"`;
|
|
44
|
+
if (!modified.includes(OPENIAP_COORD)) {
|
|
45
|
+
if (!/dependencies\s*{/.test(modified)) {
|
|
46
|
+
modified += `\n\ndependencies {\n${openiapDep}\n}\n`;
|
|
47
|
+
}
|
|
48
|
+
else {
|
|
49
|
+
modified = addLineToGradle(modified, /dependencies\s*{/, openiapDep);
|
|
50
|
+
}
|
|
51
|
+
if (!hasLoggedPluginExecution) {
|
|
52
|
+
console.log(`🛠️ react-native-iap: Added OpenIAP (${OPENIAP_VERSION}) to build.gradle`);
|
|
53
|
+
}
|
|
51
54
|
}
|
|
52
55
|
return modified;
|
|
53
56
|
};
|
|
54
57
|
const withIapAndroid = (config) => {
|
|
55
|
-
// Add
|
|
58
|
+
// Add OpenIAP dependency to app build.gradle
|
|
56
59
|
config = (0, config_plugins_1.withAppBuildGradle)(config, (config) => {
|
|
57
60
|
config.modResults.contents = modifyAppBuildGradle(config.modResults.contents);
|
|
58
61
|
return config;
|
package/plugin/src/withIAP.ts
CHANGED
|
@@ -31,12 +31,11 @@ const addLineToGradle = (
|
|
|
31
31
|
};
|
|
32
32
|
|
|
33
33
|
export const modifyProjectBuildGradle = (gradle: string): string => {
|
|
34
|
-
//
|
|
34
|
+
// Keep backward-compatible behavior: add supportLibVersion inside ext { } if missing
|
|
35
35
|
if (!gradle.includes('supportLibVersion')) {
|
|
36
36
|
const lines = gradle.split('\n');
|
|
37
37
|
const extIndex = lines.findIndex((line) => line.trim() === 'ext {');
|
|
38
38
|
if (extIndex !== -1) {
|
|
39
|
-
// Insert supportLibVersion right after 'ext {' with proper indentation
|
|
40
39
|
lines.splice(extIndex + 1, 0, 'supportLibVersion = "28.0.0"');
|
|
41
40
|
return lines.join('\n');
|
|
42
41
|
}
|
|
@@ -44,36 +43,45 @@ export const modifyProjectBuildGradle = (gradle: string): string => {
|
|
|
44
43
|
return gradle;
|
|
45
44
|
};
|
|
46
45
|
|
|
46
|
+
const OPENIAP_COORD = 'io.github.hyochan.openiap:openiap-google';
|
|
47
|
+
const OPENIAP_VERSION = '1.1.0';
|
|
48
|
+
|
|
47
49
|
const modifyAppBuildGradle = (gradle: string): string => {
|
|
48
50
|
let modified = gradle;
|
|
49
51
|
|
|
50
|
-
//
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
}
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
52
|
+
// Replace legacy Billing/GMS instructions with OpenIAP Google library
|
|
53
|
+
// Remove any old billingclient or play-services-base lines we may have added previously
|
|
54
|
+
modified = modified
|
|
55
|
+
.replace(
|
|
56
|
+
/^[ \t]*(implementation|api)[ \t]+["']com\.android\.billingclient:billing-ktx:[^"']+["'][ \t]*$/gim,
|
|
57
|
+
'',
|
|
58
|
+
)
|
|
59
|
+
.replace(
|
|
60
|
+
/^[ \t]*(implementation|api)[ \t]+["']com\.google\.android\.gms:play-services-base:[^"']+["'][ \t]*$/gim,
|
|
61
|
+
'',
|
|
62
|
+
)
|
|
63
|
+
.replace(/\n{3,}/g, '\n\n');
|
|
64
|
+
|
|
65
|
+
const openiapDep = ` implementation "${OPENIAP_COORD}:${OPENIAP_VERSION}"`;
|
|
66
|
+
|
|
67
|
+
if (!modified.includes(OPENIAP_COORD)) {
|
|
68
|
+
if (!/dependencies\s*{/.test(modified)) {
|
|
69
|
+
modified += `\n\ndependencies {\n${openiapDep}\n}\n`;
|
|
70
|
+
} else {
|
|
71
|
+
modified = addLineToGradle(modified, /dependencies\s*{/, openiapDep);
|
|
72
|
+
}
|
|
73
|
+
if (!hasLoggedPluginExecution) {
|
|
74
|
+
console.log(
|
|
75
|
+
`🛠️ react-native-iap: Added OpenIAP (${OPENIAP_VERSION}) to build.gradle`,
|
|
76
|
+
);
|
|
77
|
+
}
|
|
70
78
|
}
|
|
71
79
|
|
|
72
80
|
return modified;
|
|
73
81
|
};
|
|
74
82
|
|
|
75
83
|
const withIapAndroid: ConfigPlugin = (config) => {
|
|
76
|
-
// Add
|
|
84
|
+
// Add OpenIAP dependency to app build.gradle
|
|
77
85
|
config = withAppBuildGradle(config, (config) => {
|
|
78
86
|
config.modResults.contents = modifyAppBuildGradle(
|
|
79
87
|
config.modResults.contents,
|
|
@@ -29,11 +29,8 @@ export const getActiveSubscriptions = async (
|
|
|
29
29
|
productId: purchase.productId,
|
|
30
30
|
isActive: true, // If it's in availablePurchases, it's active
|
|
31
31
|
// Backend validation fields
|
|
32
|
-
transactionId: purchase.
|
|
33
|
-
purchaseToken:
|
|
34
|
-
androidPurchase.purchaseToken ||
|
|
35
|
-
androidPurchase.purchaseTokenAndroid ||
|
|
36
|
-
iosPurchase.purchaseToken,
|
|
32
|
+
transactionId: purchase.id,
|
|
33
|
+
purchaseToken: purchase.purchaseToken,
|
|
37
34
|
transactionDate: purchase.transactionDate,
|
|
38
35
|
// Platform-specific fields
|
|
39
36
|
expirationDateIOS: iosPurchase.expirationDateIOS
|