react-native-iap 8.3.0 → 9.0.0-beta2
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/.yarn/install-state.gz +0 -0
- package/android/build.gradle +3 -3
- package/android/src/amazon/java/com/dooboolab/RNIap/RNIapAmazonListener.kt +16 -4
- package/android/src/play/java/com/dooboolab/RNIap/RNIapModule.kt +143 -98
- package/android/src/play/java/com/dooboolab/RNIap/RNIapModuleInterface.kt +44 -0
- package/android/src/play/java/com/dooboolab/RNIap/RNIapModuleV4.kt +656 -0
- package/android/src/play/java/com/dooboolab/RNIap/RNIapPackage.kt +1 -0
- package/android/src/testPlay/java/com/dooboolab/RNIap/{RNIapModuleTest.kt → RNIapModuleTestV4.kt} +5 -5
- package/ios/RNIapIos.m +2 -0
- package/ios/RNIapIos.swift +7 -7
- package/package.json +1 -1
- package/src/hooks/useIAP.d.ts +1 -0
- package/src/hooks/useIAP.js +2 -1
- package/src/hooks/withIAPContext.d.ts +1 -0
- package/src/hooks/withIAPContext.js +9 -1
- package/src/iap.d.ts +6 -3
- package/src/iap.js +40 -33
- package/src/types/index.d.ts +40 -2
- package/ios/RNIapQueue.swift +0 -36
package/android/src/testPlay/java/com/dooboolab/RNIap/{RNIapModuleTest.kt → RNIapModuleTestV4.kt}
RENAMED
|
@@ -30,7 +30,7 @@ import org.junit.Assert.assertTrue
|
|
|
30
30
|
import org.junit.Before
|
|
31
31
|
import org.junit.Test
|
|
32
32
|
|
|
33
|
-
class
|
|
33
|
+
class RNIapModuleTestV4 {
|
|
34
34
|
|
|
35
35
|
@MockK
|
|
36
36
|
lateinit var context: ReactApplicationContext
|
|
@@ -44,14 +44,14 @@ class RNIapModuleTest {
|
|
|
44
44
|
@MockK
|
|
45
45
|
lateinit var availability: GoogleApiAvailability
|
|
46
46
|
|
|
47
|
-
private lateinit var module:
|
|
47
|
+
private lateinit var module: RNIapModuleV4
|
|
48
48
|
|
|
49
49
|
@Before
|
|
50
50
|
fun setUp() {
|
|
51
51
|
MockKAnnotations.init(this, relaxUnitFun = true)
|
|
52
52
|
every { builder.setListener(any()) } returns builder
|
|
53
53
|
every { builder.build() } returns billingClient
|
|
54
|
-
module =
|
|
54
|
+
module = RNIapModuleV4(context, builder, availability)
|
|
55
55
|
}
|
|
56
56
|
|
|
57
57
|
@Test
|
|
@@ -134,7 +134,7 @@ class RNIapModuleTest {
|
|
|
134
134
|
every { billingClient.isReady } returns true
|
|
135
135
|
val promise = mockk<Promise>(relaxed = true)
|
|
136
136
|
val listener = slot<PurchasesResponseListener>()
|
|
137
|
-
every { billingClient.queryPurchasesAsync(any(), capture(listener)) } answers {
|
|
137
|
+
every { billingClient.queryPurchasesAsync(any<String>(), capture(listener)) } answers {
|
|
138
138
|
listener.captured.onQueryPurchasesResponse(BillingResult.newBuilder().build(), listOf())
|
|
139
139
|
}
|
|
140
140
|
module.initConnection(mockk())
|
|
@@ -150,7 +150,7 @@ class RNIapModuleTest {
|
|
|
150
150
|
every { billingClient.isReady } returns true
|
|
151
151
|
val promise = mockk<Promise>(relaxed = true)
|
|
152
152
|
val listener = slot<PurchasesResponseListener>()
|
|
153
|
-
every { billingClient.queryPurchasesAsync(any(), capture(listener)) } answers {
|
|
153
|
+
every { billingClient.queryPurchasesAsync(any<String>(), capture(listener)) } answers {
|
|
154
154
|
listener.captured.onQueryPurchasesResponse(
|
|
155
155
|
BillingResult.newBuilder().build(),
|
|
156
156
|
listOf(
|
package/ios/RNIapIos.m
CHANGED
|
@@ -18,7 +18,9 @@ RCT_EXTERN_METHOD(getAvailableItems:
|
|
|
18
18
|
reject:(RCTPromiseRejectBlock)reject)
|
|
19
19
|
RCT_EXTERN_METHOD(buyProduct:
|
|
20
20
|
(NSString*)sku
|
|
21
|
+
appAccountToken:(NSString*)appAccountToken
|
|
21
22
|
andDangerouslyFinishTransactionAutomatically:(BOOL)andDangerouslyFinishTransactionAutomatically
|
|
23
|
+
applicationUsername:(NSString)applicationUsername
|
|
22
24
|
resolve:(RCTPromiseResolveBlock)resolve
|
|
23
25
|
reject:(RCTPromiseRejectBlock)reject)
|
|
24
26
|
RCT_EXTERN_METHOD(buyProductWithOffer:
|
package/ios/RNIapIos.swift
CHANGED
|
@@ -47,6 +47,7 @@ class RNIapIos: RCTEventEmitter, SKRequestDelegate, SKPaymentTransactionObserver
|
|
|
47
47
|
myQueue = DispatchQueue(label: "reject")
|
|
48
48
|
validProducts = [SKProduct]()
|
|
49
49
|
super.init()
|
|
50
|
+
SKPaymentQueue.default().add(self)
|
|
50
51
|
}
|
|
51
52
|
|
|
52
53
|
deinit {
|
|
@@ -132,12 +133,6 @@ class RNIapIos: RCTEventEmitter, SKRequestDelegate, SKPaymentTransactionObserver
|
|
|
132
133
|
_ resolve: @escaping RCTPromiseResolveBlock = { _ in },
|
|
133
134
|
reject: @escaping RCTPromiseRejectBlock = { _, _, _ in }
|
|
134
135
|
) {
|
|
135
|
-
SKPaymentQueue.default().remove(RNIapQueue.shared)
|
|
136
|
-
if let queue = RNIapQueue.shared.queue, let payment = RNIapQueue.shared.payment, let product = RNIapQueue.shared.product {
|
|
137
|
-
let val = paymentQueue(queue, shouldAddStorePayment: payment,for: product)
|
|
138
|
-
print("Promoted product response \(val)")
|
|
139
|
-
}
|
|
140
|
-
SKPaymentQueue.default().add(self)
|
|
141
136
|
let canMakePayments = SKPaymentQueue.canMakePayments()
|
|
142
137
|
resolve(NSNumber(value: canMakePayments))
|
|
143
138
|
}
|
|
@@ -179,6 +174,7 @@ class RNIapIos: RCTEventEmitter, SKRequestDelegate, SKPaymentTransactionObserver
|
|
|
179
174
|
@objc public func buyProduct(
|
|
180
175
|
_ sku:String,
|
|
181
176
|
andDangerouslyFinishTransactionAutomatically: Bool,
|
|
177
|
+
applicationUsername:String?,
|
|
182
178
|
resolve: @escaping RCTPromiseResolveBlock = { _ in },
|
|
183
179
|
reject: @escaping RCTPromiseRejectBlock = { _, _, _ in }
|
|
184
180
|
) {
|
|
@@ -197,6 +193,10 @@ class RNIapIos: RCTEventEmitter, SKRequestDelegate, SKPaymentTransactionObserver
|
|
|
197
193
|
addPromise(forKey: prod.productIdentifier, resolve: resolve, reject: reject)
|
|
198
194
|
|
|
199
195
|
let payment = SKMutablePayment(product: prod)
|
|
196
|
+
|
|
197
|
+
if (applicationUsername != nil) {
|
|
198
|
+
payment.applicationUsername = applicationUsername
|
|
199
|
+
}
|
|
200
200
|
SKPaymentQueue.default().add(payment)
|
|
201
201
|
} else{
|
|
202
202
|
if hasListeners {
|
|
@@ -341,7 +341,7 @@ class RNIapIos: RCTEventEmitter, SKRequestDelegate, SKPaymentTransactionObserver
|
|
|
341
341
|
reject: @escaping RCTPromiseRejectBlock = { _, _, _ in }
|
|
342
342
|
) {
|
|
343
343
|
print("\n\n\n *** get promoted product. \n\n.")
|
|
344
|
-
resolve(promotedProduct )
|
|
344
|
+
resolve((promotedProduct != nil) ? getProductObject(promotedProduct!) : nil)
|
|
345
345
|
}
|
|
346
346
|
|
|
347
347
|
@objc public func buyPromotedProduct(
|
package/package.json
CHANGED
package/src/hooks/useIAP.d.ts
CHANGED
|
@@ -9,6 +9,7 @@ declare type IAP_STATUS = {
|
|
|
9
9
|
availablePurchases: Purchase[];
|
|
10
10
|
currentPurchase?: Purchase;
|
|
11
11
|
currentPurchaseError?: PurchaseError;
|
|
12
|
+
initConnectionError?: Error;
|
|
12
13
|
finishTransaction: (purchase: Purchase, isConsumable?: boolean, developerPayloadAndroid?: string) => Promise<string | void>;
|
|
13
14
|
getAvailablePurchases: () => Promise<void>;
|
|
14
15
|
getPurchaseHistories: () => Promise<void>;
|
package/src/hooks/useIAP.js
CHANGED
|
@@ -39,7 +39,7 @@ import { useCallback } from 'react';
|
|
|
39
39
|
import { useIAPContext } from './withIAPContext';
|
|
40
40
|
export function useIAP() {
|
|
41
41
|
var _this = this;
|
|
42
|
-
var _a = useIAPContext(), connected = _a.connected, products = _a.products, promotedProductsIOS = _a.promotedProductsIOS, subscriptions = _a.subscriptions, purchaseHistories = _a.purchaseHistories, availablePurchases = _a.availablePurchases, currentPurchase = _a.currentPurchase, currentPurchaseError = _a.currentPurchaseError, setProducts = _a.setProducts, setSubscriptions = _a.setSubscriptions, setAvailablePurchases = _a.setAvailablePurchases, setPurchaseHistories = _a.setPurchaseHistories, setCurrentPurchase = _a.setCurrentPurchase, setCurrentPurchaseError = _a.setCurrentPurchaseError;
|
|
42
|
+
var _a = useIAPContext(), connected = _a.connected, products = _a.products, promotedProductsIOS = _a.promotedProductsIOS, subscriptions = _a.subscriptions, purchaseHistories = _a.purchaseHistories, availablePurchases = _a.availablePurchases, currentPurchase = _a.currentPurchase, currentPurchaseError = _a.currentPurchaseError, initConnectionError = _a.initConnectionError, setProducts = _a.setProducts, setSubscriptions = _a.setSubscriptions, setAvailablePurchases = _a.setAvailablePurchases, setPurchaseHistories = _a.setPurchaseHistories, setCurrentPurchase = _a.setCurrentPurchase, setCurrentPurchaseError = _a.setCurrentPurchaseError;
|
|
43
43
|
var getProducts = useCallback(function (skus) { return __awaiter(_this, void 0, void 0, function () {
|
|
44
44
|
var _a;
|
|
45
45
|
return __generator(this, function (_b) {
|
|
@@ -129,6 +129,7 @@ export function useIAP() {
|
|
|
129
129
|
availablePurchases: availablePurchases,
|
|
130
130
|
currentPurchase: currentPurchase,
|
|
131
131
|
currentPurchaseError: currentPurchaseError,
|
|
132
|
+
initConnectionError: initConnectionError,
|
|
132
133
|
finishTransaction: finishTransaction,
|
|
133
134
|
getProducts: getProducts,
|
|
134
135
|
getSubscriptions: getSubscriptions,
|
|
@@ -9,6 +9,7 @@ declare type IAPContextType = {
|
|
|
9
9
|
availablePurchases: Purchase[];
|
|
10
10
|
currentPurchase?: Purchase;
|
|
11
11
|
currentPurchaseError?: PurchaseError;
|
|
12
|
+
initConnectionError?: Error;
|
|
12
13
|
setProducts: (products: Product[]) => void;
|
|
13
14
|
setSubscriptions: (subscriptions: Subscription[]) => void;
|
|
14
15
|
setPurchaseHistories: (purchaseHistories: Purchase[]) => void;
|
|
@@ -68,6 +68,7 @@ export function withIAPContext(Component) {
|
|
|
68
68
|
var _f = useState([]), availablePurchases = _f[0], setAvailablePurchases = _f[1];
|
|
69
69
|
var _g = useState(), currentPurchase = _g[0], setCurrentPurchase = _g[1];
|
|
70
70
|
var _h = useState(), currentPurchaseError = _h[0], setCurrentPurchaseError = _h[1];
|
|
71
|
+
var _j = useState(), initConnectionError = _j[0], setInitConnectionError = _j[1];
|
|
71
72
|
var context = useMemo(function () { return ({
|
|
72
73
|
connected: connected,
|
|
73
74
|
products: products,
|
|
@@ -77,6 +78,7 @@ export function withIAPContext(Component) {
|
|
|
77
78
|
availablePurchases: availablePurchases,
|
|
78
79
|
currentPurchase: currentPurchase,
|
|
79
80
|
currentPurchaseError: currentPurchaseError,
|
|
81
|
+
initConnectionError: initConnectionError,
|
|
80
82
|
setProducts: setProducts,
|
|
81
83
|
setSubscriptions: setSubscriptions,
|
|
82
84
|
setPurchaseHistories: setPurchaseHistories,
|
|
@@ -92,6 +94,7 @@ export function withIAPContext(Component) {
|
|
|
92
94
|
availablePurchases,
|
|
93
95
|
currentPurchase,
|
|
94
96
|
currentPurchaseError,
|
|
97
|
+
initConnectionError,
|
|
95
98
|
setProducts,
|
|
96
99
|
setSubscriptions,
|
|
97
100
|
setPurchaseHistories,
|
|
@@ -100,7 +103,12 @@ export function withIAPContext(Component) {
|
|
|
100
103
|
setCurrentPurchaseError,
|
|
101
104
|
]);
|
|
102
105
|
useEffect(function () {
|
|
103
|
-
initConnection()
|
|
106
|
+
initConnection()
|
|
107
|
+
.then(function (value) {
|
|
108
|
+
setInitConnectionError(undefined);
|
|
109
|
+
setConnected(value);
|
|
110
|
+
})
|
|
111
|
+
.catch(setInitConnectionError);
|
|
104
112
|
}, []);
|
|
105
113
|
useEffect(function () {
|
|
106
114
|
if (!connected) {
|
package/src/iap.d.ts
CHANGED
|
@@ -2,8 +2,9 @@ import * as Amazon from './types/amazon';
|
|
|
2
2
|
import * as Android from './types/android';
|
|
3
3
|
import * as Apple from './types/apple';
|
|
4
4
|
import { EmitterSubscription } from 'react-native';
|
|
5
|
-
import { InAppPurchase, InstallSourceAndroid, Product, ProductPurchase,
|
|
5
|
+
import { InAppPurchase, InstallSourceAndroid, Product, ProductPurchase, PurchaseError, PurchaseResult, RequestPurchase, RequestSubscription, Subscription, SubscriptionPurchase } from './types';
|
|
6
6
|
export declare const getInstallSourceAndroid: () => InstallSourceAndroid;
|
|
7
|
+
export declare const setAndroidNativeModule: (nativeModule: any) => void;
|
|
7
8
|
/**
|
|
8
9
|
* Init module for purchase flow. Required on Android. In ios it will check whether user canMakePayment.
|
|
9
10
|
* @returns {Promise<boolean>}
|
|
@@ -44,12 +45,13 @@ export declare const getAvailablePurchases: () => Promise<(InAppPurchase | Subsc
|
|
|
44
45
|
/**
|
|
45
46
|
* Request a purchase for product. This will be received in `PurchaseUpdatedListener`.
|
|
46
47
|
* @param {string} sku The product's sku/ID
|
|
48
|
+
* @param {string} [applicationUsername] The purchaser's user ID
|
|
47
49
|
* @param {boolean} [andDangerouslyFinishTransactionAutomaticallyIOS] You should set this to false and call finishTransaction manually when you have delivered the purchased goods to the user. It defaults to true to provide backwards compatibility. Will default to false in version 4.0.0.
|
|
48
50
|
* @param {string} [obfuscatedAccountIdAndroid] Specifies an optional obfuscated string that is uniquely associated with the user's account in your app.
|
|
49
51
|
* @param {string} [obfuscatedProfileIdAndroid] Specifies an optional obfuscated string that is uniquely associated with the user's profile in your app.
|
|
50
52
|
* @returns {Promise<InAppPurchase>}
|
|
51
53
|
*/
|
|
52
|
-
export declare const requestPurchase: (sku
|
|
54
|
+
export declare const requestPurchase: ({ sku, andDangerouslyFinishTransactionAutomaticallyIOS, applicationUsername, obfuscatedAccountIdAndroid, obfuscatedProfileIdAndroid, }: RequestPurchase) => Promise<InAppPurchase>;
|
|
53
55
|
/**
|
|
54
56
|
* Request a purchase for product. This will be received in `PurchaseUpdatedListener`.
|
|
55
57
|
* @param {string} [sku] The product's sku/ID
|
|
@@ -58,9 +60,10 @@ export declare const requestPurchase: (sku: string, andDangerouslyFinishTransact
|
|
|
58
60
|
* @param {ProrationModesAndroid} [prorationModeAndroid] UNKNOWN_SUBSCRIPTION_UPGRADE_DOWNGRADE_POLICY, IMMEDIATE_WITH_TIME_PRORATION, IMMEDIATE_AND_CHARGE_PRORATED_PRICE, IMMEDIATE_WITHOUT_PRORATION, DEFERRED
|
|
59
61
|
* @param {string} [obfuscatedAccountIdAndroid] Specifies an optional obfuscated string that is uniquely associated with the user's account in your app.
|
|
60
62
|
* @param {string} [obfuscatedProfileIdAndroid] Specifies an optional obfuscated string that is uniquely associated with the user's profile in your app.
|
|
63
|
+
* @param {string} [selectedOfferIndex] Selected Offer index from the list returned by get products
|
|
61
64
|
* @returns {Promise<SubscriptionPurchase | null>} Promise resolves to null when using proratioModesAndroid=DEFERRED, and to a SubscriptionPurchase otherwise
|
|
62
65
|
*/
|
|
63
|
-
export declare const requestSubscription: (sku
|
|
66
|
+
export declare const requestSubscription: ({ sku, andDangerouslyFinishTransactionAutomaticallyIOS, purchaseTokenAndroid, prorationModeAndroid, obfuscatedAccountIdAndroid, obfuscatedProfileIdAndroid, selectedOfferIndex, }: RequestSubscription) => Promise<SubscriptionPurchase | null>;
|
|
64
67
|
/**
|
|
65
68
|
* Request a purchase for product. This will be received in `PurchaseUpdatedListener`.
|
|
66
69
|
* @param {string} sku The product's sku/ID
|
package/src/iap.js
CHANGED
|
@@ -37,7 +37,7 @@ var __generator = (this && this.__generator) || function (thisArg, body) {
|
|
|
37
37
|
import * as Apple from './types/apple';
|
|
38
38
|
import { Linking, NativeEventEmitter, NativeModules, Platform, } from 'react-native';
|
|
39
39
|
import { IAPErrorCode, InstallSourceAndroid, PurchaseStateAndroid, } from './types';
|
|
40
|
-
var RNIapIos = NativeModules.RNIapIos, RNIapModule = NativeModules.RNIapModule, RNIapAmazonModule = NativeModules.RNIapAmazonModule;
|
|
40
|
+
var RNIapIos = NativeModules.RNIapIos, RNIapModule = NativeModules.RNIapModule, RNIapModuleV4 = NativeModules.RNIapModuleV4, RNIapAmazonModule = NativeModules.RNIapAmazonModule;
|
|
41
41
|
var ANDROID_ITEM_TYPE_SUBSCRIPTION = 'subs';
|
|
42
42
|
var ANDROID_ITEM_TYPE_IAP = 'inapp';
|
|
43
43
|
export var getInstallSourceAndroid = function () {
|
|
@@ -45,14 +45,25 @@ export var getInstallSourceAndroid = function () {
|
|
|
45
45
|
? InstallSourceAndroid.GOOGLE_PLAY
|
|
46
46
|
: InstallSourceAndroid.AMAZON;
|
|
47
47
|
};
|
|
48
|
+
/**
|
|
49
|
+
* Defaulting to V4 to minimize migration, it'll eventually be changed to default to V5
|
|
50
|
+
*/
|
|
51
|
+
var androidNativeModule = RNIapModuleV4;
|
|
52
|
+
export var setAndroidNativeModule = function (nativeModule) {
|
|
53
|
+
androidNativeModule = nativeModule;
|
|
54
|
+
};
|
|
48
55
|
var checkNativeAndroidAvailable = function () {
|
|
49
|
-
if (!RNIapModule && !RNIapAmazonModule) {
|
|
56
|
+
if (!RNIapModule && !RNIapModuleV4 && !RNIapAmazonModule) {
|
|
50
57
|
throw new Error(IAPErrorCode.E_IAP_NOT_AVAILABLE);
|
|
51
58
|
}
|
|
52
59
|
};
|
|
53
60
|
var getAndroidModule = function () {
|
|
54
61
|
checkNativeAndroidAvailable();
|
|
55
|
-
return
|
|
62
|
+
return androidNativeModule
|
|
63
|
+
? androidNativeModule
|
|
64
|
+
: RNIapModule
|
|
65
|
+
? RNIapModule
|
|
66
|
+
: RNIapAmazonModule;
|
|
56
67
|
};
|
|
57
68
|
var checkNativeiOSAvailable = function () {
|
|
58
69
|
if (!RNIapIos) {
|
|
@@ -64,11 +75,13 @@ var getIosModule = function () {
|
|
|
64
75
|
return RNIapIos;
|
|
65
76
|
};
|
|
66
77
|
var getNativeModule = function () {
|
|
67
|
-
return
|
|
68
|
-
?
|
|
69
|
-
:
|
|
70
|
-
?
|
|
71
|
-
:
|
|
78
|
+
return androidNativeModule
|
|
79
|
+
? androidNativeModule
|
|
80
|
+
: RNIapModule
|
|
81
|
+
? RNIapModule
|
|
82
|
+
: RNIapAmazonModule
|
|
83
|
+
? RNIapAmazonModule
|
|
84
|
+
: RNIapIos;
|
|
72
85
|
};
|
|
73
86
|
/**
|
|
74
87
|
* Init module for purchase flow. Required on Android. In ios it will check whether user canMakePayment.
|
|
@@ -135,13 +148,13 @@ var fillProductsAdditionalData = function (products) { return __awaiter(void 0,
|
|
|
135
148
|
export var getProducts = function (skus) {
|
|
136
149
|
return (Platform.select({
|
|
137
150
|
ios: function () { return __awaiter(void 0, void 0, void 0, function () {
|
|
138
|
-
var items;
|
|
139
151
|
return __generator(this, function (_a) {
|
|
140
152
|
switch (_a.label) {
|
|
141
|
-
case 0: return [4 /*yield*/, getIosModule()
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
153
|
+
case 0: return [4 /*yield*/, getIosModule()
|
|
154
|
+
.getItems(skus)
|
|
155
|
+
.filter(function (item) { return skus.includes(item.productId); })
|
|
156
|
+
.filter(function (item) { return item.type === 'iap'; })];
|
|
157
|
+
case 1: return [2 /*return*/, _a.sent()];
|
|
145
158
|
}
|
|
146
159
|
});
|
|
147
160
|
}); },
|
|
@@ -166,15 +179,13 @@ export var getProducts = function (skus) {
|
|
|
166
179
|
export var getSubscriptions = function (skus) {
|
|
167
180
|
return (Platform.select({
|
|
168
181
|
ios: function () { return __awaiter(void 0, void 0, void 0, function () {
|
|
169
|
-
var items;
|
|
170
182
|
return __generator(this, function (_a) {
|
|
171
183
|
switch (_a.label) {
|
|
172
|
-
case 0: return [4 /*yield*/, getIosModule()
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
})];
|
|
184
|
+
case 0: return [4 /*yield*/, getIosModule()
|
|
185
|
+
.getItems(skus)
|
|
186
|
+
.filter(function (item) { return skus.includes(item.productId); })
|
|
187
|
+
.filter(function (item) { return item.type === 'subs'; })];
|
|
188
|
+
case 1: return [2 /*return*/, _a.sent()];
|
|
178
189
|
}
|
|
179
190
|
});
|
|
180
191
|
}); },
|
|
@@ -256,15 +267,14 @@ export var getAvailablePurchases = function () {
|
|
|
256
267
|
/**
|
|
257
268
|
* Request a purchase for product. This will be received in `PurchaseUpdatedListener`.
|
|
258
269
|
* @param {string} sku The product's sku/ID
|
|
270
|
+
* @param {string} [applicationUsername] The purchaser's user ID
|
|
259
271
|
* @param {boolean} [andDangerouslyFinishTransactionAutomaticallyIOS] You should set this to false and call finishTransaction manually when you have delivered the purchased goods to the user. It defaults to true to provide backwards compatibility. Will default to false in version 4.0.0.
|
|
260
272
|
* @param {string} [obfuscatedAccountIdAndroid] Specifies an optional obfuscated string that is uniquely associated with the user's account in your app.
|
|
261
273
|
* @param {string} [obfuscatedProfileIdAndroid] Specifies an optional obfuscated string that is uniquely associated with the user's profile in your app.
|
|
262
274
|
* @returns {Promise<InAppPurchase>}
|
|
263
275
|
*/
|
|
264
|
-
export var requestPurchase = function (
|
|
265
|
-
|
|
266
|
-
if (obfuscatedAccountIdAndroid === void 0) { obfuscatedAccountIdAndroid = undefined; }
|
|
267
|
-
if (obfuscatedProfileIdAndroid === void 0) { obfuscatedProfileIdAndroid = undefined; }
|
|
276
|
+
export var requestPurchase = function (_a) {
|
|
277
|
+
var sku = _a.sku, _b = _a.andDangerouslyFinishTransactionAutomaticallyIOS, andDangerouslyFinishTransactionAutomaticallyIOS = _b === void 0 ? false : _b, applicationUsername = _a.applicationUsername, _c = _a.obfuscatedAccountIdAndroid, obfuscatedAccountIdAndroid = _c === void 0 ? undefined : _c, _d = _a.obfuscatedProfileIdAndroid, obfuscatedProfileIdAndroid = _d === void 0 ? undefined : _d;
|
|
268
278
|
return (Platform.select({
|
|
269
279
|
ios: function () { return __awaiter(void 0, void 0, void 0, function () {
|
|
270
280
|
return __generator(this, function (_a) {
|
|
@@ -274,12 +284,12 @@ export var requestPurchase = function (sku, andDangerouslyFinishTransactionAutom
|
|
|
274
284
|
// eslint-disable-next-line max-len
|
|
275
285
|
'You are dangerously allowing react-native-iap to finish your transaction automatically. You should set andDangerouslyFinishTransactionAutomatically to false when calling requestPurchase and call finishTransaction manually when you have delivered the purchased goods to the user. It defaults to true to provide backwards compatibility. Will default to false in version 4.0.0.');
|
|
276
286
|
}
|
|
277
|
-
return [2 /*return*/, getIosModule().buyProduct(sku, andDangerouslyFinishTransactionAutomaticallyIOS)];
|
|
287
|
+
return [2 /*return*/, getIosModule().buyProduct(sku, andDangerouslyFinishTransactionAutomaticallyIOS, applicationUsername)];
|
|
278
288
|
});
|
|
279
289
|
}); },
|
|
280
290
|
android: function () { return __awaiter(void 0, void 0, void 0, function () {
|
|
281
291
|
return __generator(this, function (_a) {
|
|
282
|
-
return [2 /*return*/, getAndroidModule().buyItemByType(ANDROID_ITEM_TYPE_IAP, sku, null, 0, obfuscatedAccountIdAndroid, obfuscatedProfileIdAndroid)];
|
|
292
|
+
return [2 /*return*/, getAndroidModule().buyItemByType(ANDROID_ITEM_TYPE_IAP, sku, null, 0, obfuscatedAccountIdAndroid, obfuscatedProfileIdAndroid, undefined)];
|
|
283
293
|
});
|
|
284
294
|
}); },
|
|
285
295
|
}) || Promise.resolve)();
|
|
@@ -292,14 +302,11 @@ export var requestPurchase = function (sku, andDangerouslyFinishTransactionAutom
|
|
|
292
302
|
* @param {ProrationModesAndroid} [prorationModeAndroid] UNKNOWN_SUBSCRIPTION_UPGRADE_DOWNGRADE_POLICY, IMMEDIATE_WITH_TIME_PRORATION, IMMEDIATE_AND_CHARGE_PRORATED_PRICE, IMMEDIATE_WITHOUT_PRORATION, DEFERRED
|
|
293
303
|
* @param {string} [obfuscatedAccountIdAndroid] Specifies an optional obfuscated string that is uniquely associated with the user's account in your app.
|
|
294
304
|
* @param {string} [obfuscatedProfileIdAndroid] Specifies an optional obfuscated string that is uniquely associated with the user's profile in your app.
|
|
305
|
+
* @param {string} [selectedOfferIndex] Selected Offer index from the list returned by get products
|
|
295
306
|
* @returns {Promise<SubscriptionPurchase | null>} Promise resolves to null when using proratioModesAndroid=DEFERRED, and to a SubscriptionPurchase otherwise
|
|
296
307
|
*/
|
|
297
|
-
export var requestSubscription = function (
|
|
298
|
-
|
|
299
|
-
if (purchaseTokenAndroid === void 0) { purchaseTokenAndroid = undefined; }
|
|
300
|
-
if (prorationModeAndroid === void 0) { prorationModeAndroid = -1; }
|
|
301
|
-
if (obfuscatedAccountIdAndroid === void 0) { obfuscatedAccountIdAndroid = undefined; }
|
|
302
|
-
if (obfuscatedProfileIdAndroid === void 0) { obfuscatedProfileIdAndroid = undefined; }
|
|
308
|
+
export var requestSubscription = function (_a) {
|
|
309
|
+
var sku = _a.sku, _b = _a.andDangerouslyFinishTransactionAutomaticallyIOS, andDangerouslyFinishTransactionAutomaticallyIOS = _b === void 0 ? false : _b, _c = _a.purchaseTokenAndroid, purchaseTokenAndroid = _c === void 0 ? undefined : _c, _d = _a.prorationModeAndroid, prorationModeAndroid = _d === void 0 ? -1 : _d, _e = _a.obfuscatedAccountIdAndroid, obfuscatedAccountIdAndroid = _e === void 0 ? undefined : _e, _f = _a.obfuscatedProfileIdAndroid, obfuscatedProfileIdAndroid = _f === void 0 ? undefined : _f, _g = _a.selectedOfferIndex, selectedOfferIndex = _g === void 0 ? undefined : _g;
|
|
303
310
|
return (Platform.select({
|
|
304
311
|
ios: function () { return __awaiter(void 0, void 0, void 0, function () {
|
|
305
312
|
return __generator(this, function (_a) {
|
|
@@ -314,7 +321,7 @@ export var requestSubscription = function (sku, andDangerouslyFinishTransactionA
|
|
|
314
321
|
}); },
|
|
315
322
|
android: function () { return __awaiter(void 0, void 0, void 0, function () {
|
|
316
323
|
return __generator(this, function (_a) {
|
|
317
|
-
return [2 /*return*/, getAndroidModule().buyItemByType(ANDROID_ITEM_TYPE_SUBSCRIPTION, sku, purchaseTokenAndroid, prorationModeAndroid, obfuscatedAccountIdAndroid, obfuscatedProfileIdAndroid)];
|
|
324
|
+
return [2 /*return*/, getAndroidModule().buyItemByType(ANDROID_ITEM_TYPE_SUBSCRIPTION, sku, purchaseTokenAndroid, prorationModeAndroid, obfuscatedAccountIdAndroid, obfuscatedProfileIdAndroid, selectedOfferIndex)];
|
|
318
325
|
});
|
|
319
326
|
}); },
|
|
320
327
|
}) || Promise.resolve)();
|
package/src/types/index.d.ts
CHANGED
|
@@ -35,6 +35,8 @@ export declare enum InstallSourceAndroid {
|
|
|
35
35
|
AMAZON = 2
|
|
36
36
|
}
|
|
37
37
|
export interface ProductCommon {
|
|
38
|
+
type: 'subs' | 'sub' | 'inapp' | 'iap';
|
|
39
|
+
productId: string;
|
|
38
40
|
title: string;
|
|
39
41
|
description: string;
|
|
40
42
|
price: string;
|
|
@@ -60,6 +62,28 @@ export interface ProductPurchase {
|
|
|
60
62
|
developerPayloadAndroid?: string;
|
|
61
63
|
obfuscatedAccountIdAndroid?: string;
|
|
62
64
|
obfuscatedProfileIdAndroid?: string;
|
|
65
|
+
title?: string;
|
|
66
|
+
description?: string;
|
|
67
|
+
productType?: string;
|
|
68
|
+
name?: string;
|
|
69
|
+
oneTimePurchaseOfferDetails?: {
|
|
70
|
+
priceCurrencyCode?: string;
|
|
71
|
+
formattedPrice?: string;
|
|
72
|
+
priceAmountMicros?: string;
|
|
73
|
+
}[];
|
|
74
|
+
subscriptionOfferDetails?: {
|
|
75
|
+
offerToken?: string[];
|
|
76
|
+
pricingPhases: {
|
|
77
|
+
pricingPhaseList: {
|
|
78
|
+
formattedPrice?: string;
|
|
79
|
+
priceCurrencyCode?: string;
|
|
80
|
+
billingPeriod?: string;
|
|
81
|
+
billingCycleCount?: number;
|
|
82
|
+
priceAmountMicros?: string;
|
|
83
|
+
recurrenceMode?: number;
|
|
84
|
+
};
|
|
85
|
+
};
|
|
86
|
+
}[];
|
|
63
87
|
userIdAmazon?: string;
|
|
64
88
|
userMarketplaceAmazon?: string;
|
|
65
89
|
userJsonAmazon?: string;
|
|
@@ -96,11 +120,9 @@ export interface Discount {
|
|
|
96
120
|
}
|
|
97
121
|
export interface Product extends ProductCommon {
|
|
98
122
|
type: 'inapp' | 'iap';
|
|
99
|
-
productId: string;
|
|
100
123
|
}
|
|
101
124
|
export interface Subscription extends ProductCommon {
|
|
102
125
|
type: 'subs' | 'sub';
|
|
103
|
-
productId: string;
|
|
104
126
|
discounts?: Discount[];
|
|
105
127
|
introductoryPrice?: string;
|
|
106
128
|
introductoryPriceAsAmountIOS?: string;
|
|
@@ -115,3 +137,19 @@ export interface Subscription extends ProductCommon {
|
|
|
115
137
|
subscriptionPeriodAndroid?: string;
|
|
116
138
|
freeTrialPeriodAndroid?: string;
|
|
117
139
|
}
|
|
140
|
+
export interface RequestPurchase {
|
|
141
|
+
sku: string;
|
|
142
|
+
andDangerouslyFinishTransactionAutomaticallyIOS: boolean;
|
|
143
|
+
applicationUsername?: string;
|
|
144
|
+
obfuscatedAccountIdAndroid: string | undefined;
|
|
145
|
+
obfuscatedProfileIdAndroid: string | undefined;
|
|
146
|
+
}
|
|
147
|
+
export interface RequestSubscription {
|
|
148
|
+
sku: string;
|
|
149
|
+
andDangerouslyFinishTransactionAutomaticallyIOS: boolean;
|
|
150
|
+
purchaseTokenAndroid: string | undefined;
|
|
151
|
+
prorationModeAndroid: ProrationModesAndroid;
|
|
152
|
+
obfuscatedAccountIdAndroid: string | undefined;
|
|
153
|
+
obfuscatedProfileIdAndroid: string | undefined;
|
|
154
|
+
selectedOfferIndex?: number | undefined;
|
|
155
|
+
}
|
package/ios/RNIapQueue.swift
DELETED
|
@@ -1,36 +0,0 @@
|
|
|
1
|
-
//
|
|
2
|
-
// RNIapQueue.swift
|
|
3
|
-
//
|
|
4
|
-
//
|
|
5
|
-
// Created by Andres Aguilar on 9/8/21.
|
|
6
|
-
//
|
|
7
|
-
|
|
8
|
-
import Foundation
|
|
9
|
-
import StoreKit
|
|
10
|
-
|
|
11
|
-
// Temporarily stores payment information since it is sent by the OS before RN instantiates the RNModule
|
|
12
|
-
@objc(RNIapQueue)
|
|
13
|
-
public class RNIapQueue: NSObject, SKPaymentTransactionObserver {
|
|
14
|
-
public func paymentQueue(_ queue: SKPaymentQueue, updatedTransactions transactions: [SKPaymentTransaction]) {
|
|
15
|
-
//No-op
|
|
16
|
-
}
|
|
17
|
-
|
|
18
|
-
@objc
|
|
19
|
-
public static let shared = RNIapQueue()
|
|
20
|
-
|
|
21
|
-
var queue: SKPaymentQueue? = nil;
|
|
22
|
-
var payment: SKPayment? = nil;
|
|
23
|
-
var product: SKProduct? = nil;
|
|
24
|
-
|
|
25
|
-
private override init(){}
|
|
26
|
-
|
|
27
|
-
// Sent when a user initiates an IAP buy from the App Store
|
|
28
|
-
@available(iOS 11.0, *)
|
|
29
|
-
func paymentQueue(_ queue: SKPaymentQueue, shouldAddStorePayment payment: SKPayment, for product: SKProduct) -> Bool{
|
|
30
|
-
RNIapQueue.shared.queue = queue
|
|
31
|
-
RNIapQueue.shared.payment = payment
|
|
32
|
-
RNIapQueue.shared.product = product
|
|
33
|
-
return false
|
|
34
|
-
}
|
|
35
|
-
|
|
36
|
-
}
|