react-native-iap 15.3.5 → 15.4.0-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/README.md +1 -1
- package/android/build.gradle +13 -5
- package/android/src/main/java/com/margelo/nitro/iap/HybridRnIap.kt +16 -3
- package/ios/HybridRnIap.swift +12 -0
- package/lib/module/index.js +93 -75
- package/lib/module/index.js.map +1 -1
- package/lib/module/index.kepler.js +170 -0
- package/lib/module/index.kepler.js.map +1 -0
- package/lib/module/types/amazon-devices-kepler/index.d.js +2 -0
- package/lib/module/types/amazon-devices-kepler/index.d.js.map +1 -0
- package/lib/module/types.js +5 -2
- package/lib/module/types.js.map +1 -1
- package/lib/module/utils/error.js +98 -15
- package/lib/module/utils/error.js.map +1 -1
- package/lib/module/utils/type-bridge.js +4 -1
- package/lib/module/utils/type-bridge.js.map +1 -1
- package/lib/module/vega-adapter.js +981 -0
- package/lib/module/vega-adapter.js.map +1 -0
- package/lib/module/vega.js +10 -0
- package/lib/module/vega.js.map +1 -0
- package/lib/module/vega.kepler.js +18 -0
- package/lib/module/vega.kepler.js.map +1 -0
- package/lib/typescript/plugin/src/withIAP.d.ts +33 -0
- package/lib/typescript/plugin/src/withIAP.d.ts.map +1 -1
- package/lib/typescript/src/index.d.ts +9 -2
- package/lib/typescript/src/index.d.ts.map +1 -1
- package/lib/typescript/src/index.kepler.d.ts +55 -0
- package/lib/typescript/src/index.kepler.d.ts.map +1 -0
- package/lib/typescript/src/specs/RnIap.nitro.d.ts +10 -1
- package/lib/typescript/src/specs/RnIap.nitro.d.ts.map +1 -1
- package/lib/typescript/src/types.d.ts +16 -3
- package/lib/typescript/src/types.d.ts.map +1 -1
- package/lib/typescript/src/utils/error.d.ts +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/lib/typescript/src/vega-adapter.d.ts +76 -0
- package/lib/typescript/src/vega-adapter.d.ts.map +1 -0
- package/lib/typescript/src/vega.d.ts +4 -0
- package/lib/typescript/src/vega.d.ts.map +1 -0
- package/lib/typescript/src/vega.kepler.d.ts +4 -0
- package/lib/typescript/src/vega.kepler.d.ts.map +1 -0
- package/nitrogen/generated/android/NitroIap+autolinking.cmake +1 -0
- package/nitrogen/generated/android/c++/JHybridRnIapSpec.cpp +5 -0
- package/nitrogen/generated/android/c++/JIapStore.hpp +3 -0
- package/nitrogen/generated/android/c++/JNitroVerifyPurchaseWithIapkitAmazonProps.hpp +71 -0
- package/nitrogen/generated/android/c++/JNitroVerifyPurchaseWithIapkitProps.hpp +9 -1
- package/nitrogen/generated/android/c++/JNitroVerifyPurchaseWithProviderProps.hpp +4 -0
- package/nitrogen/generated/android/c++/JVariant_NullType_NitroVerifyPurchaseWithIapkitAmazonProps.cpp +26 -0
- package/nitrogen/generated/android/c++/JVariant_NullType_NitroVerifyPurchaseWithIapkitAmazonProps.hpp +75 -0
- package/nitrogen/generated/android/c++/JVariant_NullType_NitroVerifyPurchaseWithIapkitProps.hpp +4 -0
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/iap/IapStore.kt +2 -1
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/iap/NitroVerifyPurchaseWithIapkitAmazonProps.kt +44 -0
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/iap/NitroVerifyPurchaseWithIapkitProps.kt +5 -2
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/iap/Variant_NullType_NitroVerifyPurchaseWithIapkitAmazonProps.kt +53 -0
- package/nitrogen/generated/ios/NitroIap-Swift-Cxx-Bridge.hpp +47 -0
- package/nitrogen/generated/ios/NitroIap-Swift-Cxx-Umbrella.hpp +3 -0
- package/nitrogen/generated/ios/c++/HybridRnIapSpecSwift.hpp +3 -0
- package/nitrogen/generated/ios/swift/IapStore.swift +4 -0
- package/nitrogen/generated/ios/swift/NitroVerifyPurchaseWithIapkitAmazonProps.swift +103 -0
- package/nitrogen/generated/ios/swift/NitroVerifyPurchaseWithIapkitProps.swift +38 -1
- package/nitrogen/generated/ios/swift/Variant_NullType_NitroVerifyPurchaseWithIapkitAmazonProps.swift +18 -0
- package/nitrogen/generated/shared/c++/IapStore.hpp +4 -0
- package/nitrogen/generated/shared/c++/NitroVerifyPurchaseWithIapkitAmazonProps.hpp +94 -0
- package/nitrogen/generated/shared/c++/NitroVerifyPurchaseWithIapkitProps.hpp +8 -1
- package/openiap-versions.json +2 -2
- package/package.json +17 -4
- package/plugin/build/withIAP.d.ts +33 -0
- package/plugin/build/withIAP.js +109 -42
- package/plugin/src/withIAP.ts +185 -55
- package/src/index.kepler.ts +311 -0
- package/src/index.ts +187 -78
- package/src/specs/RnIap.nitro.ts +13 -2
- package/src/types/amazon-devices-kepler/index.d.ts +14 -0
- package/src/types.ts +17 -3
- package/src/utils/error.ts +127 -14
- package/src/utils/type-bridge.ts +4 -1
- package/src/vega-adapter.ts +1503 -0
- package/src/vega.kepler.ts +21 -0
- package/src/vega.ts +10 -0
- package/android/src/test/java/com/margelo/nitro/iap/ListenerThreadSafetyTest.kt +0 -154
- package/android/src/test/java/com/margelo/nitro/iap/OpenIapExceptionTest.kt +0 -93
- package/android/src/test/java/com/margelo/nitro/iap/ProductQueryHelpersTest.kt +0 -140
- package/plugin/tsconfig.tsbuildinfo +0 -1
package/README.md
CHANGED
|
@@ -105,7 +105,7 @@ Before installing React Native IAP, make sure you have:
|
|
|
105
105
|
|
|
106
106
|
#### Android Configuration
|
|
107
107
|
|
|
108
|
-
**Kotlin Version Requirement:** This library requires Kotlin 2.
|
|
108
|
+
**Kotlin Version Requirement:** This library requires Kotlin 2.2+. Configure your project's Kotlin version:
|
|
109
109
|
|
|
110
110
|
In your root `android/build.gradle`:
|
|
111
111
|
|
package/android/build.gradle
CHANGED
|
@@ -107,8 +107,13 @@ def getExtOrIntegerDefault(name) {
|
|
|
107
107
|
return getExtOrDefault(name).toString().toInteger()
|
|
108
108
|
}
|
|
109
109
|
|
|
110
|
-
// Read
|
|
110
|
+
// Read store flags from gradle.properties, default to play
|
|
111
111
|
def horizonEnabled = project.findProperty('horizonEnabled')?.toBoolean() ?: false
|
|
112
|
+
def fireOsEnabled = project.findProperty('fireOsEnabled')?.toBoolean() ?: false
|
|
113
|
+
if (horizonEnabled && fireOsEnabled) {
|
|
114
|
+
throw new GradleException("react-native-iap: horizonEnabled and fireOsEnabled cannot both be true")
|
|
115
|
+
}
|
|
116
|
+
def openiapFlavor = fireOsEnabled ? 'amazon' : (horizonEnabled ? 'horizon' : 'play')
|
|
112
117
|
|
|
113
118
|
def resolveOpenIapGoogleBuildFile() {
|
|
114
119
|
def candidates = [
|
|
@@ -155,9 +160,8 @@ android {
|
|
|
155
160
|
// Ship consumer keep rules so Nitro HybridObjects aren't stripped in app release builds
|
|
156
161
|
consumerProguardFiles 'consumer-rules.pro'
|
|
157
162
|
|
|
158
|
-
// Use
|
|
159
|
-
|
|
160
|
-
missingDimensionStrategy "platform", flavor
|
|
163
|
+
// Use explicit store flags to determine platform flavor
|
|
164
|
+
missingDimensionStrategy "platform", openiapFlavor
|
|
161
165
|
|
|
162
166
|
externalNativeBuild {
|
|
163
167
|
cmake {
|
|
@@ -251,7 +255,9 @@ dependencies {
|
|
|
251
255
|
}
|
|
252
256
|
|
|
253
257
|
// Google Play Services
|
|
254
|
-
|
|
258
|
+
if (!fireOsEnabled && !horizonEnabled) {
|
|
259
|
+
implementation "com.google.android.gms:play-services-base:$playServicesBaseVersion"
|
|
260
|
+
}
|
|
255
261
|
|
|
256
262
|
// Kotlin coroutines
|
|
257
263
|
implementation "org.jetbrains.kotlinx:kotlinx-coroutines-android:$coroutinesVersion"
|
|
@@ -261,6 +267,8 @@ dependencies {
|
|
|
261
267
|
def localGoogleProject = findProject(':openiap')
|
|
262
268
|
if (localGoogleProject != null) {
|
|
263
269
|
implementation project(':openiap')
|
|
270
|
+
} else if (fireOsEnabled) {
|
|
271
|
+
implementation "io.github.hyochan.openiap:openiap-google-amazon:${googleVersionString}"
|
|
264
272
|
} else if (horizonEnabled) {
|
|
265
273
|
implementation "io.github.hyochan.openiap:openiap-google-horizon:${googleVersionString}"
|
|
266
274
|
} else {
|
|
@@ -43,13 +43,13 @@ import dev.hyo.openiap.ExternalLinkLaunchModeAndroid as OpenIapExternalLinkLaunc
|
|
|
43
43
|
import dev.hyo.openiap.ExternalLinkTypeAndroid as OpenIapExternalLinkType
|
|
44
44
|
import dev.hyo.openiap.listener.OpenIapDeveloperProvidedBillingListener
|
|
45
45
|
import dev.hyo.openiap.store.OpenIapStore
|
|
46
|
+
import java.util.Locale
|
|
46
47
|
import kotlin.coroutines.cancellation.CancellationException
|
|
47
48
|
import kotlinx.coroutines.Dispatchers
|
|
48
49
|
import kotlinx.coroutines.withContext
|
|
49
50
|
import kotlinx.coroutines.CompletableDeferred
|
|
50
51
|
import org.json.JSONArray
|
|
51
52
|
import org.json.JSONObject
|
|
52
|
-
import java.util.Locale
|
|
53
53
|
|
|
54
54
|
/**
|
|
55
55
|
* Custom exception for OpenIAP errors that only includes the error JSON without stack traces.
|
|
@@ -575,7 +575,7 @@ class HybridRnIap : HybridRnIapSpec() {
|
|
|
575
575
|
mapOf("type" to androidOptions?.type?.name, "includeSuspended" to includeSuspended)
|
|
576
576
|
)
|
|
577
577
|
|
|
578
|
-
val typeName = androidOptions?.type?.name?.lowercase()
|
|
578
|
+
val typeName = androidOptions?.type?.name?.lowercase(java.util.Locale.ROOT)
|
|
579
579
|
val normalizedType = when (typeName) {
|
|
580
580
|
"inapp" -> {
|
|
581
581
|
RnIapLog.warn("getAvailablePurchases received legacy type 'inapp'; forwarding as 'in-app'")
|
|
@@ -1279,6 +1279,7 @@ class HybridRnIap : HybridRnIapSpec() {
|
|
|
1279
1279
|
dev.hyo.openiap.IapStore.Apple -> IapStore.APPLE
|
|
1280
1280
|
dev.hyo.openiap.IapStore.Google -> IapStore.GOOGLE
|
|
1281
1281
|
dev.hyo.openiap.IapStore.Horizon -> IapStore.HORIZON
|
|
1282
|
+
dev.hyo.openiap.IapStore.Amazon -> IapStore.AMAZON
|
|
1282
1283
|
dev.hyo.openiap.IapStore.Unknown -> IapStore.UNKNOWN
|
|
1283
1284
|
}
|
|
1284
1285
|
}
|
|
@@ -1469,7 +1470,7 @@ class HybridRnIap : HybridRnIapSpec() {
|
|
|
1469
1470
|
return Promise.async {
|
|
1470
1471
|
try {
|
|
1471
1472
|
// Convert Nitro enum to string (e.g., IAPKIT -> "iapkit")
|
|
1472
|
-
val providerString = params.provider.name.lowercase()
|
|
1473
|
+
val providerString = params.provider.name.lowercase(java.util.Locale.ROOT)
|
|
1473
1474
|
RnIapLog.payload("verifyPurchaseWithProvider", mapOf("provider" to providerString))
|
|
1474
1475
|
|
|
1475
1476
|
// Build the props map for OpenIAP - use string value for provider
|
|
@@ -1482,6 +1483,14 @@ class HybridRnIap : HybridRnIapSpec() {
|
|
|
1482
1483
|
(iapkit.google as? Variant_NullType_NitroVerifyPurchaseWithIapkitGoogleProps.Second)?.value?.let { google ->
|
|
1483
1484
|
iapkitMap["google"] = mapOf("purchaseToken" to google.purchaseToken)
|
|
1484
1485
|
}
|
|
1486
|
+
(iapkit.amazon as? Variant_NullType_NitroVerifyPurchaseWithIapkitAmazonProps.Second)?.value?.let { amazon ->
|
|
1487
|
+
val amazonMap = mutableMapOf<String, Any?>(
|
|
1488
|
+
"receiptId" to amazon.receiptId
|
|
1489
|
+
)
|
|
1490
|
+
amazon.userId.unwrapString()?.let { amazonMap["userId"] = it }
|
|
1491
|
+
amazon.sandbox.unwrapBool()?.let { amazonMap["sandbox"] = it }
|
|
1492
|
+
iapkitMap["amazon"] = amazonMap
|
|
1493
|
+
}
|
|
1485
1494
|
(iapkit.apple as? Variant_NullType_NitroVerifyPurchaseWithIapkitAppleProps.Second)?.value?.let { apple ->
|
|
1486
1495
|
iapkitMap["apple"] = mapOf("jws" to apple.jws)
|
|
1487
1496
|
}
|
|
@@ -1609,6 +1618,7 @@ class HybridRnIap : HybridRnIapSpec() {
|
|
|
1609
1618
|
// Alternative Billing (Android)
|
|
1610
1619
|
// -------------------------------------------------------------------------
|
|
1611
1620
|
|
|
1621
|
+
@Suppress("DEPRECATION")
|
|
1612
1622
|
override fun checkAlternativeBillingAvailabilityAndroid(): Promise<Boolean> {
|
|
1613
1623
|
return Promise.async {
|
|
1614
1624
|
RnIapLog.payload("checkAlternativeBillingAvailabilityAndroid", null)
|
|
@@ -1626,6 +1636,7 @@ class HybridRnIap : HybridRnIapSpec() {
|
|
|
1626
1636
|
}
|
|
1627
1637
|
}
|
|
1628
1638
|
|
|
1639
|
+
@Suppress("DEPRECATION")
|
|
1629
1640
|
override fun showAlternativeBillingDialogAndroid(): Promise<Boolean> {
|
|
1630
1641
|
return Promise.async {
|
|
1631
1642
|
RnIapLog.payload("showAlternativeBillingDialogAndroid", null)
|
|
@@ -1647,6 +1658,7 @@ class HybridRnIap : HybridRnIapSpec() {
|
|
|
1647
1658
|
}
|
|
1648
1659
|
}
|
|
1649
1660
|
|
|
1661
|
+
@Suppress("DEPRECATION")
|
|
1650
1662
|
override fun createAlternativeBillingTokenAndroid(sku: Variant_NullType_String?): Promise<Variant_NullType_String> {
|
|
1651
1663
|
return Promise.async {
|
|
1652
1664
|
val skuValue = sku.unwrapString()
|
|
@@ -2000,6 +2012,7 @@ class HybridRnIap : HybridRnIapSpec() {
|
|
|
2000
2012
|
"APPLE" -> IapStore.APPLE
|
|
2001
2013
|
"GOOGLE" -> IapStore.GOOGLE
|
|
2002
2014
|
"HORIZON" -> IapStore.HORIZON
|
|
2015
|
+
"AMAZON" -> IapStore.AMAZON
|
|
2003
2016
|
else -> IapStore.UNKNOWN
|
|
2004
2017
|
}
|
|
2005
2018
|
}
|
package/ios/HybridRnIap.swift
CHANGED
|
@@ -446,6 +446,18 @@ class HybridRnIap: HybridRnIapSpec {
|
|
|
446
446
|
if case .second(let google) = iapkit.google {
|
|
447
447
|
iapkitDict["google"] = ["purchaseToken": google.purchaseToken]
|
|
448
448
|
}
|
|
449
|
+
if case .second(let amazon) = iapkit.amazon {
|
|
450
|
+
var amazonDict: [String: Any] = [
|
|
451
|
+
"receiptId": amazon.receiptId
|
|
452
|
+
]
|
|
453
|
+
if case .second(let sandbox) = amazon.sandbox {
|
|
454
|
+
amazonDict["sandbox"] = sandbox
|
|
455
|
+
}
|
|
456
|
+
if case .second(let userId) = amazon.userId {
|
|
457
|
+
amazonDict["userId"] = userId
|
|
458
|
+
}
|
|
459
|
+
iapkitDict["amazon"] = amazonDict
|
|
460
|
+
}
|
|
449
461
|
propsDict["iapkit"] = iapkitDict
|
|
450
462
|
}
|
|
451
463
|
// Use JSONSerialization + JSONDecoder like expo-iap does
|
package/lib/module/index.js
CHANGED
|
@@ -10,11 +10,12 @@ import { NitroModules } from 'react-native-nitro-modules';
|
|
|
10
10
|
|
|
11
11
|
import { ErrorCode } from "./types.js";
|
|
12
12
|
import { convertNitroProductToProduct, convertNitroPurchaseToPurchase, convertProductToProductSubscription, validateNitroProduct, validateNitroPurchase, convertNitroSubscriptionStatusToSubscriptionStatusIOS } from "./utils/type-bridge.js";
|
|
13
|
-
import { parseErrorStringToJsonObj } from "./utils/error.js";
|
|
13
|
+
import { isUserCancelledError, parseErrorStringToJsonObj } from "./utils/error.js";
|
|
14
14
|
import { normalizeErrorCodeFromNative, createPurchaseError, DUPLICATE_PURCHASE_CODE } from "./utils/errorMapping.js";
|
|
15
15
|
import { RnIapConsole } from "./utils/debug.js";
|
|
16
16
|
import { getSuccessFromPurchaseVariant } from "./utils/purchase.js";
|
|
17
17
|
import { parseAppTransactionPayload } from "./utils.js";
|
|
18
|
+
import { getVegaIapModule, isVegaOS } from "./vega.js";
|
|
18
19
|
|
|
19
20
|
// ------------------------------
|
|
20
21
|
// Billing Programs API (Android 8.2.0+)
|
|
@@ -28,6 +29,7 @@ import { parseAppTransactionPayload } from "./utils.js";
|
|
|
28
29
|
|
|
29
30
|
export * from "./types.js";
|
|
30
31
|
export * from "./utils/error.js";
|
|
32
|
+
export * from "./vega.js";
|
|
31
33
|
const LEGACY_INAPP_WARNING = "[react-native-iap] `type: 'inapp'` is deprecated and will be removed in a future major version. Use 'in-app' instead.";
|
|
32
34
|
const toErrorMessage = error => {
|
|
33
35
|
if (typeof error === 'object' && error !== null && 'message' in error && error.message != null) {
|
|
@@ -35,6 +37,13 @@ const toErrorMessage = error => {
|
|
|
35
37
|
}
|
|
36
38
|
return String(error ?? '');
|
|
37
39
|
};
|
|
40
|
+
const parseErrorAndLogIfNeeded = (message, error) => {
|
|
41
|
+
const parsedError = parseErrorStringToJsonObj(error);
|
|
42
|
+
if (!isUserCancelledError(parsedError)) {
|
|
43
|
+
RnIapConsole.error(message, error);
|
|
44
|
+
}
|
|
45
|
+
return parsedError;
|
|
46
|
+
};
|
|
38
47
|
const unsupportedPlatformError = () => new Error(`Unsupported platform: ${Platform.OS}`);
|
|
39
48
|
// ActiveSubscription and PurchaseError types are already exported via 'export * from ./types'
|
|
40
49
|
|
|
@@ -56,6 +65,10 @@ let iapRef = null;
|
|
|
56
65
|
*/
|
|
57
66
|
export const isNitroReady = () => {
|
|
58
67
|
if (iapRef) return true;
|
|
68
|
+
if (isVegaOS()) {
|
|
69
|
+
iapRef = getVegaIapModule();
|
|
70
|
+
return Boolean(iapRef);
|
|
71
|
+
}
|
|
59
72
|
try {
|
|
60
73
|
iapRef = NitroModules.createHybridObject('RnIap');
|
|
61
74
|
return true;
|
|
@@ -86,9 +99,20 @@ export const isMacOS = () => {
|
|
|
86
99
|
export const isStandardIOS = () => {
|
|
87
100
|
return Platform.OS === 'ios' && !isTVOS() && !isMacOS();
|
|
88
101
|
};
|
|
102
|
+
const isAndroidStoreRuntime = () => {
|
|
103
|
+
return Platform.OS === 'android' || isVegaOS();
|
|
104
|
+
};
|
|
89
105
|
const IAP = {
|
|
90
106
|
get instance() {
|
|
91
107
|
if (iapRef) return iapRef;
|
|
108
|
+
if (isVegaOS()) {
|
|
109
|
+
const vegaModule = getVegaIapModule();
|
|
110
|
+
if (!vegaModule) {
|
|
111
|
+
throw new Error('Amazon Vega IAP module is unavailable. Install @amazon-devices/keplerscript-appstore-iap-lib in the Vega app target and build with the React Native for Vega kepler platform.');
|
|
112
|
+
}
|
|
113
|
+
iapRef = vegaModule;
|
|
114
|
+
return iapRef;
|
|
115
|
+
}
|
|
92
116
|
|
|
93
117
|
// Attempt to create the HybridObject and map common Nitro/JSI readiness errors
|
|
94
118
|
try {
|
|
@@ -500,7 +524,7 @@ function tryAttachSubscriptionBillingIssueNative() {
|
|
|
500
524
|
} catch (e) {
|
|
501
525
|
const msg = toErrorMessage(e);
|
|
502
526
|
if (msg.includes('Nitro runtime not installed')) {
|
|
503
|
-
RnIapConsole.warn('[subscriptionBillingIssueListener] Nitro not ready yet; will retry
|
|
527
|
+
RnIapConsole.warn('[subscriptionBillingIssueListener] Nitro not ready yet; will retry after initConnection()');
|
|
504
528
|
} else {
|
|
505
529
|
throw e;
|
|
506
530
|
}
|
|
@@ -590,7 +614,7 @@ export const fetchProducts = async request => {
|
|
|
590
614
|
|
|
591
615
|
// item.type === 'subs' case
|
|
592
616
|
// For Android, check if subscription items have actual offers
|
|
593
|
-
if (
|
|
617
|
+
if (isAndroidStoreRuntime() && item.platform === 'android' && item.type === 'subs') {
|
|
594
618
|
// TypeScript now knows this is ProductSubscriptionAndroid
|
|
595
619
|
const hasSubscriptionOffers = item.subscriptionOfferDetailsAndroid && Array.isArray(item.subscriptionOfferDetailsAndroid) && item.subscriptionOfferDetailsAndroid.length > 0;
|
|
596
620
|
RnIapConsole.debug(`[fetchProducts] ${item.id}: type=${item.type}, hasOffers=${hasSubscriptionOffers}`);
|
|
@@ -622,8 +646,7 @@ export const fetchProducts = async request => {
|
|
|
622
646
|
}
|
|
623
647
|
return convertedProducts;
|
|
624
648
|
} catch (error) {
|
|
625
|
-
|
|
626
|
-
const parsedError = parseErrorStringToJsonObj(error);
|
|
649
|
+
const parsedError = parseErrorAndLogIfNeeded('[fetchProducts] Failed:', error);
|
|
627
650
|
throw createPurchaseError({
|
|
628
651
|
code: parsedError.code,
|
|
629
652
|
message: parsedError.message,
|
|
@@ -677,9 +700,22 @@ export const getAvailablePurchases = async options => {
|
|
|
677
700
|
RnIapConsole.warn(`[getAvailablePurchases] Some purchases failed validation: ${nitroPurchases.length - validPurchases.length} invalid`);
|
|
678
701
|
}
|
|
679
702
|
return validPurchases.map(convertNitroPurchaseToPurchase);
|
|
680
|
-
} else if (
|
|
681
|
-
// For Android, we need to call twice for inapp and subs
|
|
703
|
+
} else if (isAndroidStoreRuntime()) {
|
|
682
704
|
const includeSuspended = Boolean(options?.includeSuspendedAndroid ?? false);
|
|
705
|
+
if (isVegaOS()) {
|
|
706
|
+
const nitroPurchases = await IAP.instance.getAvailablePurchases({
|
|
707
|
+
android: {
|
|
708
|
+
includeSuspended
|
|
709
|
+
}
|
|
710
|
+
});
|
|
711
|
+
const validPurchases = nitroPurchases.filter(validateNitroPurchase);
|
|
712
|
+
if (validPurchases.length !== nitroPurchases.length) {
|
|
713
|
+
RnIapConsole.warn(`[getAvailablePurchases] Some Vega purchases failed validation: ${nitroPurchases.length - validPurchases.length} invalid`);
|
|
714
|
+
}
|
|
715
|
+
return validPurchases.map(convertNitroPurchaseToPurchase);
|
|
716
|
+
}
|
|
717
|
+
|
|
718
|
+
// For Android Play/Horizon/Fire OS, query in-app items and subscriptions separately.
|
|
683
719
|
const inappNitroPurchases = await IAP.instance.getAvailablePurchases({
|
|
684
720
|
android: {
|
|
685
721
|
type: 'inapp',
|
|
@@ -728,8 +764,7 @@ export const getPromotedProductIOS = async () => {
|
|
|
728
764
|
const converted = convertNitroProductToProduct(nitroProduct);
|
|
729
765
|
return converted.platform === 'ios' ? converted : null;
|
|
730
766
|
} catch (error) {
|
|
731
|
-
|
|
732
|
-
const parsedError = parseErrorStringToJsonObj(error);
|
|
767
|
+
const parsedError = parseErrorAndLogIfNeeded('[getPromotedProductIOS] Failed:', error);
|
|
733
768
|
throw createPurchaseError({
|
|
734
769
|
code: parsedError.code,
|
|
735
770
|
message: parsedError.message,
|
|
@@ -772,8 +807,8 @@ export const getStorefrontIOS = async () => {
|
|
|
772
807
|
* @see {@link https://openiap.dev/docs/apis/get-storefront}
|
|
773
808
|
*/
|
|
774
809
|
export const getStorefront = async () => {
|
|
775
|
-
if (Platform.OS !== 'ios' &&
|
|
776
|
-
RnIapConsole.warn('[getStorefront] Storefront lookup is only supported on iOS and
|
|
810
|
+
if (Platform.OS !== 'ios' && !isAndroidStoreRuntime()) {
|
|
811
|
+
RnIapConsole.warn('[getStorefront] Storefront lookup is only supported on iOS, Android, and Vega OS.');
|
|
777
812
|
return '';
|
|
778
813
|
}
|
|
779
814
|
const hasUnifiedMethod = typeof IAP.instance.getStorefront === 'function';
|
|
@@ -858,8 +893,7 @@ export const subscriptionStatusIOS = async sku => {
|
|
|
858
893
|
if (!Array.isArray(statuses)) return [];
|
|
859
894
|
return statuses.filter(status => status != null).map(convertNitroSubscriptionStatusToSubscriptionStatusIOS);
|
|
860
895
|
} catch (error) {
|
|
861
|
-
|
|
862
|
-
const parsedError = parseErrorStringToJsonObj(error);
|
|
896
|
+
const parsedError = parseErrorAndLogIfNeeded('[subscriptionStatusIOS] Failed:', error);
|
|
863
897
|
throw createPurchaseError({
|
|
864
898
|
code: parsedError.code,
|
|
865
899
|
message: parsedError.message,
|
|
@@ -889,8 +923,7 @@ export const currentEntitlementIOS = async sku => {
|
|
|
889
923
|
}
|
|
890
924
|
return null;
|
|
891
925
|
} catch (error) {
|
|
892
|
-
|
|
893
|
-
const parsedError = parseErrorStringToJsonObj(error);
|
|
926
|
+
const parsedError = parseErrorAndLogIfNeeded('[currentEntitlementIOS] Failed:', error);
|
|
894
927
|
throw createPurchaseError({
|
|
895
928
|
code: parsedError.code,
|
|
896
929
|
message: parsedError.message,
|
|
@@ -920,8 +953,7 @@ export const latestTransactionIOS = async sku => {
|
|
|
920
953
|
}
|
|
921
954
|
return null;
|
|
922
955
|
} catch (error) {
|
|
923
|
-
|
|
924
|
-
const parsedError = parseErrorStringToJsonObj(error);
|
|
956
|
+
const parsedError = parseErrorAndLogIfNeeded('[latestTransactionIOS] Failed:', error);
|
|
925
957
|
throw createPurchaseError({
|
|
926
958
|
code: parsedError.code,
|
|
927
959
|
message: parsedError.message,
|
|
@@ -946,8 +978,7 @@ export const getPendingTransactionsIOS = async () => {
|
|
|
946
978
|
const nitroPurchases = await IAP.instance.getPendingTransactionsIOS();
|
|
947
979
|
return nitroPurchases.map(convertNitroPurchaseToPurchase).filter(purchase => purchase.platform === 'ios');
|
|
948
980
|
} catch (error) {
|
|
949
|
-
|
|
950
|
-
const parsedError = parseErrorStringToJsonObj(error);
|
|
981
|
+
const parsedError = parseErrorAndLogIfNeeded('[getPendingTransactionsIOS] Failed:', error);
|
|
951
982
|
throw createPurchaseError({
|
|
952
983
|
code: parsedError.code,
|
|
953
984
|
message: parsedError.message,
|
|
@@ -970,8 +1001,7 @@ export const getAllTransactionsIOS = async () => {
|
|
|
970
1001
|
const nitroPurchases = await IAP.instance.getAllTransactionsIOS();
|
|
971
1002
|
return nitroPurchases.map(convertNitroPurchaseToPurchase).filter(purchase => purchase.platform === 'ios');
|
|
972
1003
|
} catch (error) {
|
|
973
|
-
|
|
974
|
-
const parsedError = parseErrorStringToJsonObj(error);
|
|
1004
|
+
const parsedError = parseErrorAndLogIfNeeded('[getAllTransactionsIOS] Failed:', error);
|
|
975
1005
|
throw createPurchaseError({
|
|
976
1006
|
code: parsedError.code,
|
|
977
1007
|
message: parsedError.message,
|
|
@@ -996,8 +1026,7 @@ export const showManageSubscriptionsIOS = async () => {
|
|
|
996
1026
|
const nitroPurchases = await IAP.instance.showManageSubscriptionsIOS();
|
|
997
1027
|
return nitroPurchases.map(convertNitroPurchaseToPurchase).filter(purchase => purchase.platform === 'ios');
|
|
998
1028
|
} catch (error) {
|
|
999
|
-
|
|
1000
|
-
const parsedError = parseErrorStringToJsonObj(error);
|
|
1029
|
+
const parsedError = parseErrorAndLogIfNeeded('[showManageSubscriptionsIOS] Failed:', error);
|
|
1001
1030
|
throw createPurchaseError({
|
|
1002
1031
|
code: parsedError.code,
|
|
1003
1032
|
message: parsedError.message,
|
|
@@ -1022,8 +1051,7 @@ export const isEligibleForIntroOfferIOS = async groupID => {
|
|
|
1022
1051
|
try {
|
|
1023
1052
|
return await IAP.instance.isEligibleForIntroOfferIOS(groupID);
|
|
1024
1053
|
} catch (error) {
|
|
1025
|
-
|
|
1026
|
-
const parsedError = parseErrorStringToJsonObj(error);
|
|
1054
|
+
const parsedError = parseErrorAndLogIfNeeded('[isEligibleForIntroOfferIOS] Failed:', error);
|
|
1027
1055
|
throw createPurchaseError({
|
|
1028
1056
|
code: parsedError.code,
|
|
1029
1057
|
message: parsedError.message,
|
|
@@ -1048,8 +1076,7 @@ export const getReceiptDataIOS = async () => {
|
|
|
1048
1076
|
try {
|
|
1049
1077
|
return await IAP.instance.getReceiptDataIOS();
|
|
1050
1078
|
} catch (error) {
|
|
1051
|
-
|
|
1052
|
-
const parsedError = parseErrorStringToJsonObj(error);
|
|
1079
|
+
const parsedError = parseErrorAndLogIfNeeded('[getReceiptDataIOS] Failed:', error);
|
|
1053
1080
|
throw createPurchaseError({
|
|
1054
1081
|
code: parsedError.code,
|
|
1055
1082
|
message: parsedError.message,
|
|
@@ -1069,8 +1096,7 @@ export const getReceiptIOS = async () => {
|
|
|
1069
1096
|
}
|
|
1070
1097
|
return await IAP.instance.getReceiptDataIOS();
|
|
1071
1098
|
} catch (error) {
|
|
1072
|
-
|
|
1073
|
-
const parsedError = parseErrorStringToJsonObj(error);
|
|
1099
|
+
const parsedError = parseErrorAndLogIfNeeded('[getReceiptIOS] Failed:', error);
|
|
1074
1100
|
throw createPurchaseError({
|
|
1075
1101
|
code: parsedError.code,
|
|
1076
1102
|
message: parsedError.message,
|
|
@@ -1090,8 +1116,7 @@ export const requestReceiptRefreshIOS = async () => {
|
|
|
1090
1116
|
}
|
|
1091
1117
|
return await IAP.instance.getReceiptDataIOS();
|
|
1092
1118
|
} catch (error) {
|
|
1093
|
-
|
|
1094
|
-
const parsedError = parseErrorStringToJsonObj(error);
|
|
1119
|
+
const parsedError = parseErrorAndLogIfNeeded('[requestReceiptRefreshIOS] Failed:', error);
|
|
1095
1120
|
throw createPurchaseError({
|
|
1096
1121
|
code: parsedError.code,
|
|
1097
1122
|
message: parsedError.message,
|
|
@@ -1116,8 +1141,7 @@ export const isTransactionVerifiedIOS = async sku => {
|
|
|
1116
1141
|
try {
|
|
1117
1142
|
return await IAP.instance.isTransactionVerifiedIOS(sku);
|
|
1118
1143
|
} catch (error) {
|
|
1119
|
-
|
|
1120
|
-
const parsedError = parseErrorStringToJsonObj(error);
|
|
1144
|
+
const parsedError = parseErrorAndLogIfNeeded('[isTransactionVerifiedIOS] Failed:', error);
|
|
1121
1145
|
throw createPurchaseError({
|
|
1122
1146
|
code: parsedError.code,
|
|
1123
1147
|
message: parsedError.message,
|
|
@@ -1142,8 +1166,7 @@ export const getTransactionJwsIOS = async sku => {
|
|
|
1142
1166
|
try {
|
|
1143
1167
|
return await IAP.instance.getTransactionJwsIOS(sku);
|
|
1144
1168
|
} catch (error) {
|
|
1145
|
-
|
|
1146
|
-
const parsedError = parseErrorStringToJsonObj(error);
|
|
1169
|
+
const parsedError = parseErrorAndLogIfNeeded('[getTransactionJwsIOS] Failed:', error);
|
|
1147
1170
|
throw createPurchaseError({
|
|
1148
1171
|
code: parsedError.code,
|
|
1149
1172
|
message: parsedError.message,
|
|
@@ -1178,10 +1201,13 @@ export const getTransactionJwsIOS = async sku => {
|
|
|
1178
1201
|
*/
|
|
1179
1202
|
export const initConnection = async config => {
|
|
1180
1203
|
try {
|
|
1181
|
-
|
|
1204
|
+
const result = await IAP.instance.initConnection(config);
|
|
1205
|
+
if (subscriptionBillingIssueJsListeners.size > 0) {
|
|
1206
|
+
tryAttachSubscriptionBillingIssueNative();
|
|
1207
|
+
}
|
|
1208
|
+
return result;
|
|
1182
1209
|
} catch (error) {
|
|
1183
|
-
|
|
1184
|
-
const parsedError = parseErrorStringToJsonObj(error);
|
|
1210
|
+
const parsedError = parseErrorAndLogIfNeeded('Failed to initialize IAP connection:', error);
|
|
1185
1211
|
throw createPurchaseError({
|
|
1186
1212
|
code: parsedError.code,
|
|
1187
1213
|
message: parsedError.message,
|
|
@@ -1203,8 +1229,7 @@ export const endConnection = async () => {
|
|
|
1203
1229
|
resetListenerState();
|
|
1204
1230
|
return result;
|
|
1205
1231
|
} catch (error) {
|
|
1206
|
-
|
|
1207
|
-
const parsedError = parseErrorStringToJsonObj(error);
|
|
1232
|
+
const parsedError = parseErrorAndLogIfNeeded('Failed to end IAP connection:', error);
|
|
1208
1233
|
throw createPurchaseError({
|
|
1209
1234
|
code: parsedError.code,
|
|
1210
1235
|
message: parsedError.message,
|
|
@@ -1229,8 +1254,7 @@ export const restorePurchases = async () => {
|
|
|
1229
1254
|
onlyIncludeActiveItemsIOS: true
|
|
1230
1255
|
});
|
|
1231
1256
|
} catch (error) {
|
|
1232
|
-
|
|
1233
|
-
const parsedError = parseErrorStringToJsonObj(error);
|
|
1257
|
+
const parsedError = parseErrorAndLogIfNeeded('Failed to restore purchases:', error);
|
|
1234
1258
|
throw createPurchaseError({
|
|
1235
1259
|
code: parsedError.code,
|
|
1236
1260
|
message: parsedError.message,
|
|
@@ -1284,7 +1308,7 @@ export const requestPurchase = async request => {
|
|
|
1284
1308
|
if (!iosRequest?.sku) {
|
|
1285
1309
|
throw new Error('Invalid request for iOS. The `sku` property is required.');
|
|
1286
1310
|
}
|
|
1287
|
-
} else if (
|
|
1311
|
+
} else if (isAndroidStoreRuntime()) {
|
|
1288
1312
|
// Support both 'google' (recommended) and 'android' (deprecated) fields
|
|
1289
1313
|
const androidRequest = perPlatformRequest.google ?? perPlatformRequest.android;
|
|
1290
1314
|
if (!androidRequest?.skus?.length) {
|
|
@@ -1338,7 +1362,7 @@ export const requestPurchase = async request => {
|
|
|
1338
1362
|
|
|
1339
1363
|
// Support both 'google' (recommended) and 'android' (deprecated) fields
|
|
1340
1364
|
const androidRequestSource = perPlatformRequest.google ?? perPlatformRequest.android;
|
|
1341
|
-
if (
|
|
1365
|
+
if (isAndroidStoreRuntime() && androidRequestSource) {
|
|
1342
1366
|
const androidRequest = isSubs ? androidRequestSource : androidRequestSource;
|
|
1343
1367
|
const androidPayload = {
|
|
1344
1368
|
skus: androidRequest.skus
|
|
@@ -1380,8 +1404,7 @@ export const requestPurchase = async request => {
|
|
|
1380
1404
|
}
|
|
1381
1405
|
return await IAP.instance.requestPurchase(unifiedRequest);
|
|
1382
1406
|
} catch (error) {
|
|
1383
|
-
|
|
1384
|
-
const parsedError = parseErrorStringToJsonObj(error);
|
|
1407
|
+
const parsedError = parseErrorAndLogIfNeeded('Failed to request purchase:', error);
|
|
1385
1408
|
throw createPurchaseError({
|
|
1386
1409
|
code: parsedError.code,
|
|
1387
1410
|
message: parsedError.message,
|
|
@@ -1432,7 +1455,7 @@ export const finishTransaction = async args => {
|
|
|
1432
1455
|
transactionId: purchase.id
|
|
1433
1456
|
}
|
|
1434
1457
|
};
|
|
1435
|
-
} else if (
|
|
1458
|
+
} else if (isAndroidStoreRuntime()) {
|
|
1436
1459
|
const token = purchase.purchaseToken ?? undefined;
|
|
1437
1460
|
if (!token) {
|
|
1438
1461
|
throw new Error('purchaseToken required to finish Android transaction');
|
|
@@ -1482,8 +1505,8 @@ export const finishTransaction = async args => {
|
|
|
1482
1505
|
*/
|
|
1483
1506
|
export const acknowledgePurchaseAndroid = async purchaseToken => {
|
|
1484
1507
|
try {
|
|
1485
|
-
if (
|
|
1486
|
-
throw new Error('acknowledgePurchaseAndroid is only available on Android');
|
|
1508
|
+
if (!isAndroidStoreRuntime()) {
|
|
1509
|
+
throw new Error('acknowledgePurchaseAndroid is only available on Android and Vega OS');
|
|
1487
1510
|
}
|
|
1488
1511
|
const result = await IAP.instance.finishTransaction({
|
|
1489
1512
|
android: {
|
|
@@ -1493,8 +1516,7 @@ export const acknowledgePurchaseAndroid = async purchaseToken => {
|
|
|
1493
1516
|
});
|
|
1494
1517
|
return getSuccessFromPurchaseVariant(result, 'acknowledgePurchaseAndroid');
|
|
1495
1518
|
} catch (error) {
|
|
1496
|
-
|
|
1497
|
-
const parsedError = parseErrorStringToJsonObj(error);
|
|
1519
|
+
const parsedError = parseErrorAndLogIfNeeded('Failed to acknowledge purchase Android:', error);
|
|
1498
1520
|
throw createPurchaseError({
|
|
1499
1521
|
code: parsedError.code,
|
|
1500
1522
|
message: parsedError.message,
|
|
@@ -1518,8 +1540,8 @@ export const acknowledgePurchaseAndroid = async purchaseToken => {
|
|
|
1518
1540
|
*/
|
|
1519
1541
|
export const consumePurchaseAndroid = async purchaseToken => {
|
|
1520
1542
|
try {
|
|
1521
|
-
if (
|
|
1522
|
-
throw new Error('consumePurchaseAndroid is only available on Android');
|
|
1543
|
+
if (!isAndroidStoreRuntime()) {
|
|
1544
|
+
throw new Error('consumePurchaseAndroid is only available on Android and Vega OS');
|
|
1523
1545
|
}
|
|
1524
1546
|
const result = await IAP.instance.finishTransaction({
|
|
1525
1547
|
android: {
|
|
@@ -1529,8 +1551,7 @@ export const consumePurchaseAndroid = async purchaseToken => {
|
|
|
1529
1551
|
});
|
|
1530
1552
|
return getSuccessFromPurchaseVariant(result, 'consumePurchaseAndroid');
|
|
1531
1553
|
} catch (error) {
|
|
1532
|
-
|
|
1533
|
-
const parsedError = parseErrorStringToJsonObj(error);
|
|
1554
|
+
const parsedError = parseErrorAndLogIfNeeded('Failed to consume purchase Android:', error);
|
|
1534
1555
|
throw createPurchaseError({
|
|
1535
1556
|
code: parsedError.code,
|
|
1536
1557
|
message: parsedError.message,
|
|
@@ -1656,8 +1677,7 @@ export const validateReceipt = async options => {
|
|
|
1656
1677
|
return result;
|
|
1657
1678
|
}
|
|
1658
1679
|
} catch (error) {
|
|
1659
|
-
|
|
1660
|
-
const parsedError = parseErrorStringToJsonObj(error);
|
|
1680
|
+
const parsedError = parseErrorAndLogIfNeeded('[validateReceipt] Failed:', error);
|
|
1661
1681
|
throw createPurchaseError({
|
|
1662
1682
|
code: parsedError.code,
|
|
1663
1683
|
message: parsedError.message,
|
|
@@ -1713,8 +1733,14 @@ export const validateReceiptIOS = async options => {
|
|
|
1713
1733
|
* provider: 'iapkit',
|
|
1714
1734
|
* iapkit: {
|
|
1715
1735
|
* apiKey: 'your-api-key',
|
|
1716
|
-
*
|
|
1717
|
-
*
|
|
1736
|
+
* // Choose exactly one store payload.
|
|
1737
|
+
* // apple: { jws: purchase.purchaseToken },
|
|
1738
|
+
* // google: { purchaseToken: purchase.purchaseToken },
|
|
1739
|
+
* amazon: {
|
|
1740
|
+
* userId: amazonUserId,
|
|
1741
|
+
* receiptId: purchase.purchaseToken,
|
|
1742
|
+
* sandbox: __DEV__,
|
|
1743
|
+
* },
|
|
1718
1744
|
* },
|
|
1719
1745
|
* });
|
|
1720
1746
|
* ```
|
|
@@ -1744,8 +1770,7 @@ export const verifyPurchaseWithProvider = async options => {
|
|
|
1744
1770
|
errors: result.errors ?? null
|
|
1745
1771
|
};
|
|
1746
1772
|
} catch (error) {
|
|
1747
|
-
|
|
1748
|
-
const parsedError = parseErrorStringToJsonObj(error);
|
|
1773
|
+
const parsedError = parseErrorAndLogIfNeeded('[verifyPurchaseWithProvider] Failed:', error);
|
|
1749
1774
|
throw createPurchaseError({
|
|
1750
1775
|
code: parsedError.code,
|
|
1751
1776
|
message: parsedError.message,
|
|
@@ -1770,8 +1795,7 @@ export const syncIOS = async () => {
|
|
|
1770
1795
|
const result = await IAP.instance.syncIOS();
|
|
1771
1796
|
return Boolean(result);
|
|
1772
1797
|
} catch (error) {
|
|
1773
|
-
|
|
1774
|
-
const parsedError = parseErrorStringToJsonObj(error);
|
|
1798
|
+
const parsedError = parseErrorAndLogIfNeeded('[syncIOS] Failed:', error);
|
|
1775
1799
|
throw createPurchaseError({
|
|
1776
1800
|
code: parsedError.code,
|
|
1777
1801
|
message: parsedError.message,
|
|
@@ -1796,8 +1820,7 @@ export const presentCodeRedemptionSheetIOS = async () => {
|
|
|
1796
1820
|
const result = await IAP.instance.presentCodeRedemptionSheetIOS();
|
|
1797
1821
|
return Boolean(result);
|
|
1798
1822
|
} catch (error) {
|
|
1799
|
-
|
|
1800
|
-
const parsedError = parseErrorStringToJsonObj(error);
|
|
1823
|
+
const parsedError = parseErrorAndLogIfNeeded('[presentCodeRedemptionSheetIOS] Failed:', error);
|
|
1801
1824
|
throw createPurchaseError({
|
|
1802
1825
|
code: parsedError.code,
|
|
1803
1826
|
message: parsedError.message,
|
|
@@ -1846,8 +1869,7 @@ export const requestPurchaseOnPromotedProductIOS = async () => {
|
|
|
1846
1869
|
}
|
|
1847
1870
|
return true;
|
|
1848
1871
|
} catch (error) {
|
|
1849
|
-
|
|
1850
|
-
const parsedError = parseErrorStringToJsonObj(error);
|
|
1872
|
+
const parsedError = parseErrorAndLogIfNeeded('[requestPurchaseOnPromotedProductIOS] Failed:', error);
|
|
1851
1873
|
throw createPurchaseError({
|
|
1852
1874
|
code: parsedError.code,
|
|
1853
1875
|
message: parsedError.message,
|
|
@@ -1872,8 +1894,7 @@ export const clearTransactionIOS = async () => {
|
|
|
1872
1894
|
await IAP.instance.clearTransactionIOS();
|
|
1873
1895
|
return true;
|
|
1874
1896
|
} catch (error) {
|
|
1875
|
-
|
|
1876
|
-
const parsedError = parseErrorStringToJsonObj(error);
|
|
1897
|
+
const parsedError = parseErrorAndLogIfNeeded('[clearTransactionIOS] Failed:', error);
|
|
1877
1898
|
throw createPurchaseError({
|
|
1878
1899
|
code: parsedError.code,
|
|
1879
1900
|
message: parsedError.message,
|
|
@@ -1899,8 +1920,7 @@ export const beginRefundRequestIOS = async sku => {
|
|
|
1899
1920
|
const status = await IAP.instance.beginRefundRequestIOS(sku);
|
|
1900
1921
|
return status ?? null;
|
|
1901
1922
|
} catch (error) {
|
|
1902
|
-
|
|
1903
|
-
const parsedError = parseErrorStringToJsonObj(error);
|
|
1923
|
+
const parsedError = parseErrorAndLogIfNeeded('[beginRefundRequestIOS] Failed:', error);
|
|
1904
1924
|
throw createPurchaseError({
|
|
1905
1925
|
code: parsedError.code,
|
|
1906
1926
|
message: parsedError.message,
|
|
@@ -1946,8 +1966,7 @@ export const deepLinkToSubscriptionsIOS = async () => {
|
|
|
1946
1966
|
await IAP.instance.showManageSubscriptionsIOS();
|
|
1947
1967
|
return true;
|
|
1948
1968
|
} catch (error) {
|
|
1949
|
-
|
|
1950
|
-
const parsedError = parseErrorStringToJsonObj(error);
|
|
1969
|
+
const parsedError = parseErrorAndLogIfNeeded('[deepLinkToSubscriptionsIOS] Failed:', error);
|
|
1951
1970
|
throw createPurchaseError({
|
|
1952
1971
|
code: parsedError.code,
|
|
1953
1972
|
message: parsedError.message,
|
|
@@ -2015,8 +2034,7 @@ export const getActiveSubscriptions = async subscriptionIds => {
|
|
|
2015
2034
|
RnIapConsole.error('IAP connection not initialized:', error);
|
|
2016
2035
|
throw error;
|
|
2017
2036
|
}
|
|
2018
|
-
|
|
2019
|
-
const parsedError = parseErrorStringToJsonObj(error);
|
|
2037
|
+
const parsedError = parseErrorAndLogIfNeeded('Failed to get active subscriptions:', error);
|
|
2020
2038
|
throw createPurchaseError({
|
|
2021
2039
|
code: parsedError.code,
|
|
2022
2040
|
message: parsedError.message,
|