react-native-iap 11.0.0-alpha.7 → 11.0.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 +0 -1
- package/ios/IapSerializationUtils.swift +30 -0
- package/ios/RNIapIos.m +1 -10
- package/ios/RNIapIos.swift +18 -84
- package/ios/RNIapIosSk2.m +5 -0
- package/ios/RNIapIosSk2.swift +66 -52
- package/lib/commonjs/eventEmitter.js +4 -4
- package/lib/commonjs/eventEmitter.js.map +1 -1
- package/lib/commonjs/hooks/withIAPContext.js +1 -1
- package/lib/commonjs/hooks/withIAPContext.js.map +1 -1
- package/lib/commonjs/iap.js +398 -335
- package/lib/commonjs/iap.js.map +1 -1
- package/lib/commonjs/index.js +13 -0
- package/lib/commonjs/index.js.map +1 -1
- package/lib/commonjs/internal/platform.js +75 -2
- package/lib/commonjs/internal/platform.js.map +1 -1
- package/lib/commonjs/modules/amazon.js +28 -1
- package/lib/commonjs/modules/amazon.js.map +1 -1
- package/lib/commonjs/modules/android.js +73 -1
- package/lib/commonjs/modules/android.js.map +1 -1
- package/lib/commonjs/modules/ios.js +126 -0
- package/lib/commonjs/modules/ios.js.map +1 -1
- package/lib/commonjs/modules/iosSk2.js +47 -0
- package/lib/commonjs/modules/iosSk2.js.map +1 -1
- package/lib/commonjs/types/appleSk2.js +21 -1
- package/lib/commonjs/types/appleSk2.js.map +1 -1
- package/lib/module/eventEmitter.js +2 -2
- package/lib/module/eventEmitter.js.map +1 -1
- package/lib/module/hooks/withIAPContext.js +2 -2
- package/lib/module/hooks/withIAPContext.js.map +1 -1
- package/lib/module/iap.js +359 -267
- package/lib/module/iap.js.map +1 -1
- package/lib/module/index.js +1 -0
- package/lib/module/index.js.map +1 -1
- package/lib/module/internal/platform.js +48 -1
- package/lib/module/internal/platform.js.map +1 -1
- package/lib/module/modules/amazon.js +23 -0
- package/lib/module/modules/amazon.js.map +1 -1
- package/lib/module/modules/android.js +59 -1
- package/lib/module/modules/android.js.map +1 -1
- package/lib/module/modules/ios.js +102 -1
- package/lib/module/modules/ios.js.map +1 -1
- package/lib/module/modules/iosSk2.js +30 -1
- package/lib/module/modules/iosSk2.js.map +1 -1
- package/lib/module/types/appleSk2.js +17 -0
- package/lib/module/types/appleSk2.js.map +1 -1
- package/lib/typescript/iap.d.ts +347 -168
- package/lib/typescript/index.d.ts +1 -0
- package/lib/typescript/internal/platform.d.ts +9 -0
- package/lib/typescript/modules/amazon.d.ts +17 -0
- package/lib/typescript/modules/android.d.ts +38 -1
- package/lib/typescript/modules/ios.d.ts +57 -5
- package/lib/typescript/modules/iosSk2.d.ts +28 -7
- package/lib/typescript/types/appleSk2.d.ts +31 -0
- package/package.json +5 -2
- package/src/eventEmitter.ts +4 -3
- package/src/hooks/withIAPContext.tsx +2 -2
- package/src/iap.ts +402 -356
- package/src/index.ts +1 -0
- package/src/internal/platform.ts +77 -1
- package/src/modules/amazon.ts +29 -1
- package/src/modules/android.ts +83 -2
- package/src/modules/ios.ts +124 -13
- package/src/modules/iosSk2.ts +46 -15
- package/src/types/appleSk2.ts +58 -1
package/lib/commonjs/iap.js
CHANGED
|
@@ -3,16 +3,50 @@
|
|
|
3
3
|
Object.defineProperty(exports, "__esModule", {
|
|
4
4
|
value: true
|
|
5
5
|
});
|
|
6
|
-
exports.
|
|
6
|
+
exports.IapIosSk2 = exports.IapIos = exports.IapAndroid = exports.IapAmazon = void 0;
|
|
7
|
+
Object.defineProperty(exports, "enableStorekit2", {
|
|
8
|
+
enumerable: true,
|
|
9
|
+
get: function () {
|
|
10
|
+
return _internal.enableStorekit2;
|
|
11
|
+
}
|
|
12
|
+
});
|
|
13
|
+
exports.initConnection = exports.getSubscriptions = exports.getPurchaseHistory = exports.getProducts = exports.getAvailablePurchases = exports.flushFailedPurchasesCachedAsPendingAndroid = exports.finishTransaction = exports.endConnection = void 0;
|
|
14
|
+
Object.defineProperty(exports, "isIosStorekit2", {
|
|
15
|
+
enumerable: true,
|
|
16
|
+
get: function () {
|
|
17
|
+
return _internal.isIosStorekit2;
|
|
18
|
+
}
|
|
19
|
+
});
|
|
20
|
+
exports.requestSubscription = exports.requestPurchase = void 0;
|
|
7
21
|
|
|
8
22
|
var _reactNative = require("react-native");
|
|
9
23
|
|
|
24
|
+
var IapAmazon = _interopRequireWildcard(require("./modules/amazon"));
|
|
25
|
+
|
|
26
|
+
exports.IapAmazon = IapAmazon;
|
|
27
|
+
|
|
28
|
+
var IapAndroid = _interopRequireWildcard(require("./modules/android"));
|
|
29
|
+
|
|
30
|
+
exports.IapAndroid = IapAndroid;
|
|
31
|
+
|
|
32
|
+
var IapIos = _interopRequireWildcard(require("./modules/ios"));
|
|
33
|
+
|
|
34
|
+
exports.IapIos = IapIos;
|
|
35
|
+
|
|
36
|
+
var IapIosSk2 = _interopRequireWildcard(require("./modules/iosSk2"));
|
|
37
|
+
|
|
38
|
+
exports.IapIosSk2 = IapIosSk2;
|
|
39
|
+
|
|
10
40
|
var _appleSk = require("./types/appleSk2");
|
|
11
41
|
|
|
12
42
|
var _internal = require("./internal");
|
|
13
43
|
|
|
14
44
|
var _types = require("./types");
|
|
15
45
|
|
|
46
|
+
function _getRequireWildcardCache(nodeInterop) { if (typeof WeakMap !== "function") return null; var cacheBabelInterop = new WeakMap(); var cacheNodeInterop = new WeakMap(); return (_getRequireWildcardCache = function (nodeInterop) { return nodeInterop ? cacheNodeInterop : cacheBabelInterop; })(nodeInterop); }
|
|
47
|
+
|
|
48
|
+
function _interopRequireWildcard(obj, nodeInterop) { if (!nodeInterop && obj && obj.__esModule) { return obj; } if (obj === null || typeof obj !== "object" && typeof obj !== "function") { return { default: obj }; } var cache = _getRequireWildcardCache(nodeInterop); if (cache && cache.has(obj)) { return cache.get(obj); } var newObj = {}; var hasPropertyDescriptor = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var key in obj) { if (key !== "default" && Object.prototype.hasOwnProperty.call(obj, key)) { var desc = hasPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : null; if (desc && (desc.get || desc.set)) { Object.defineProperty(newObj, key, desc); } else { newObj[key] = obj[key]; } } } newObj.default = obj; if (cache) { cache.set(obj, newObj); } return newObj; }
|
|
49
|
+
|
|
16
50
|
const {
|
|
17
51
|
RNIapIos,
|
|
18
52
|
RNIapIosSk2,
|
|
@@ -21,78 +55,51 @@ const {
|
|
|
21
55
|
} = _reactNative.NativeModules;
|
|
22
56
|
const ANDROID_ITEM_TYPE_SUBSCRIPTION = _types.ProductType.subs;
|
|
23
57
|
const ANDROID_ITEM_TYPE_IAP = _types.ProductType.inapp;
|
|
58
|
+
/**
|
|
59
|
+
* Init module for purchase flow. Required on Android. In ios it will check whether user canMakePayment.
|
|
60
|
+
* ## Usage
|
|
24
61
|
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
};
|
|
28
|
-
|
|
29
|
-
exports.getInstallSourceAndroid = getInstallSourceAndroid;
|
|
30
|
-
let androidNativeModule = RNIapModule;
|
|
31
|
-
let iosNativeModule = RNIapIosSk2;
|
|
32
|
-
|
|
33
|
-
const isIosStorekit2 = () => iosNativeModule === RNIapIosSk2;
|
|
34
|
-
|
|
35
|
-
exports.isIosStorekit2 = isIosStorekit2;
|
|
36
|
-
|
|
37
|
-
const setAndroidNativeModule = nativeModule => {
|
|
38
|
-
androidNativeModule = nativeModule;
|
|
39
|
-
};
|
|
40
|
-
|
|
41
|
-
exports.setAndroidNativeModule = setAndroidNativeModule;
|
|
42
|
-
|
|
43
|
-
const setIosNativeModule = nativeModule => {
|
|
44
|
-
iosNativeModule = nativeModule;
|
|
45
|
-
};
|
|
46
|
-
|
|
47
|
-
exports.setIosNativeModule = setIosNativeModule;
|
|
48
|
-
|
|
49
|
-
const checkNativeAndroidAvailable = () => {
|
|
50
|
-
if (!RNIapModule && !RNIapAmazonModule) {
|
|
51
|
-
throw new Error('IAP_NOT_AVAILABLE');
|
|
52
|
-
}
|
|
53
|
-
};
|
|
54
|
-
|
|
55
|
-
const getAndroidModule = () => {
|
|
56
|
-
checkNativeAndroidAvailable();
|
|
57
|
-
return androidNativeModule ? androidNativeModule : RNIapModule ? RNIapModule : RNIapAmazonModule;
|
|
58
|
-
};
|
|
59
|
-
|
|
60
|
-
exports.getAndroidModule = getAndroidModule;
|
|
61
|
-
|
|
62
|
-
const checkNativeIOSAvailable = () => {
|
|
63
|
-
if (!RNIapIos && !RNIapIosSk2) {
|
|
64
|
-
throw new Error('IAP_NOT_AVAILABLE');
|
|
65
|
-
}
|
|
66
|
-
};
|
|
67
|
-
|
|
68
|
-
const getIosModule = () => {
|
|
69
|
-
checkNativeIOSAvailable();
|
|
70
|
-
return iosNativeModule ? iosNativeModule : RNIapIosSk2 ? RNIapIosSk2 : RNIapIos;
|
|
71
|
-
};
|
|
62
|
+
```tsx
|
|
63
|
+
import React, {useEffect} from 'react';
|
|
64
|
+
import {View} from 'react-native';
|
|
65
|
+
import {initConnection} from 'react-native-iap';
|
|
72
66
|
|
|
73
|
-
|
|
67
|
+
const App = () => {
|
|
68
|
+
useEffect(() => {
|
|
69
|
+
void initConnection();
|
|
70
|
+
}, []);
|
|
74
71
|
|
|
75
|
-
|
|
76
|
-
return _internal.isAndroid ? getAndroidModule() : getIosModule();
|
|
72
|
+
return <View />;
|
|
77
73
|
};
|
|
78
|
-
|
|
79
|
-
* Init module for purchase flow. Required on Android. In ios it will check whether user canMakePayment.
|
|
80
|
-
* @returns {Promise<boolean>}
|
|
74
|
+
```
|
|
81
75
|
*/
|
|
82
76
|
|
|
83
|
-
|
|
84
|
-
exports.getNativeModule = getNativeModule;
|
|
85
|
-
|
|
86
|
-
const initConnection = () => getNativeModule().initConnection();
|
|
77
|
+
const initConnection = () => (0, _internal.getNativeModule)().initConnection();
|
|
87
78
|
/**
|
|
88
|
-
*
|
|
79
|
+
* Disconnects from native SDK
|
|
80
|
+
* Usage
|
|
81
|
+
* ```tsx
|
|
82
|
+
import React, {useEffect} from 'react';
|
|
83
|
+
import {View} from 'react-native';
|
|
84
|
+
import {endConnection} from 'react-native-iap';
|
|
85
|
+
|
|
86
|
+
const App = () => {
|
|
87
|
+
useEffect(() => {
|
|
88
|
+
return () => {
|
|
89
|
+
void endConnection();
|
|
90
|
+
};
|
|
91
|
+
}, []);
|
|
92
|
+
|
|
93
|
+
return <View />;
|
|
94
|
+
};
|
|
95
|
+
```
|
|
89
96
|
* @returns {Promise<void>}
|
|
90
97
|
*/
|
|
91
98
|
|
|
92
99
|
|
|
93
100
|
exports.initConnection = initConnection;
|
|
94
101
|
|
|
95
|
-
const endConnection = () => getNativeModule().endConnection();
|
|
102
|
+
const endConnection = () => (0, _internal.getNativeModule)().endConnection();
|
|
96
103
|
/**
|
|
97
104
|
* Consume all 'ghost' purchases (that is, pending payment that already failed but is still marked as pending in Play Store cache). Android only.
|
|
98
105
|
* @returns {Promise<boolean>}
|
|
@@ -101,11 +108,50 @@ const endConnection = () => getNativeModule().endConnection();
|
|
|
101
108
|
|
|
102
109
|
exports.endConnection = endConnection;
|
|
103
110
|
|
|
104
|
-
const flushFailedPurchasesCachedAsPendingAndroid = () => getAndroidModule().flushFailedPurchasesCachedAsPending();
|
|
111
|
+
const flushFailedPurchasesCachedAsPendingAndroid = () => (0, _internal.getAndroidModule)().flushFailedPurchasesCachedAsPending();
|
|
105
112
|
/**
|
|
106
113
|
* Get a list of products (consumable and non-consumable items, but not subscriptions)
|
|
107
|
-
|
|
108
|
-
|
|
114
|
+
## Usage
|
|
115
|
+
|
|
116
|
+
```ts
|
|
117
|
+
import React, {useState} from 'react';
|
|
118
|
+
import {Platform} from 'react-native';
|
|
119
|
+
import {getProducts, Product} from 'react-native-iap';
|
|
120
|
+
|
|
121
|
+
const skus = Platform.select({
|
|
122
|
+
ios: ['com.example.consumableIos'],
|
|
123
|
+
android: ['com.example.consumableAndroid'],
|
|
124
|
+
});
|
|
125
|
+
|
|
126
|
+
const App = () => {
|
|
127
|
+
const [products, setProducts] = useState<Product[]>([]);
|
|
128
|
+
|
|
129
|
+
const handleProducts = async () => {
|
|
130
|
+
const items = await getProducts({skus});
|
|
131
|
+
|
|
132
|
+
setProducts(items);
|
|
133
|
+
};
|
|
134
|
+
|
|
135
|
+
useEffect(() => {
|
|
136
|
+
void handleProducts();
|
|
137
|
+
}, []);
|
|
138
|
+
|
|
139
|
+
return (
|
|
140
|
+
<>
|
|
141
|
+
{products.map((product) => (
|
|
142
|
+
<Text key={product.productId}>{product.productId}</Text>
|
|
143
|
+
))}
|
|
144
|
+
</>
|
|
145
|
+
);
|
|
146
|
+
};
|
|
147
|
+
```
|
|
148
|
+
|
|
149
|
+
Just a few things to keep in mind:
|
|
150
|
+
|
|
151
|
+
- You can get your products in `componentDidMount`, `useEffect` or another appropriate area of your app.
|
|
152
|
+
- Since a user may start your app with a bad or no internet connection, preparing/getting the items more than once may be a good idea.
|
|
153
|
+
- If the user has no IAPs available when the app starts first, you may want to check again when the user enters your IAP store.
|
|
154
|
+
|
|
109
155
|
*/
|
|
110
156
|
|
|
111
157
|
|
|
@@ -119,7 +165,7 @@ const getProducts = _ref => {
|
|
|
119
165
|
ios: async () => {
|
|
120
166
|
let items;
|
|
121
167
|
|
|
122
|
-
if (isIosStorekit2()) {
|
|
168
|
+
if ((0, _internal.isIosStorekit2)()) {
|
|
123
169
|
items = (await RNIapIosSk2.getItems(skus)).map(_appleSk.productSk2Map);
|
|
124
170
|
} else {
|
|
125
171
|
items = await RNIapIos.getItems(skus);
|
|
@@ -128,15 +174,31 @@ const getProducts = _ref => {
|
|
|
128
174
|
return items.filter(item => skus.includes(item.productId) && item.type === 'iap');
|
|
129
175
|
},
|
|
130
176
|
android: async () => {
|
|
131
|
-
const products = await getAndroidModule().getItemsByType(ANDROID_ITEM_TYPE_IAP, skus);
|
|
177
|
+
const products = await (0, _internal.getAndroidModule)().getItemsByType(ANDROID_ITEM_TYPE_IAP, skus);
|
|
132
178
|
return (0, _internal.fillProductsWithAdditionalData)(products);
|
|
133
179
|
}
|
|
134
180
|
}) || (() => Promise.reject(new Error('Unsupported Platform'))))();
|
|
135
181
|
};
|
|
136
182
|
/**
|
|
137
183
|
* Get a list of subscriptions
|
|
138
|
-
*
|
|
139
|
-
|
|
184
|
+
* ## Usage
|
|
185
|
+
|
|
186
|
+
```tsx
|
|
187
|
+
import React, {useCallback} from 'react';
|
|
188
|
+
import {View} from 'react-native';
|
|
189
|
+
import {getSubscriptions} from 'react-native-iap';
|
|
190
|
+
|
|
191
|
+
const App = () => {
|
|
192
|
+
const subscriptions = useCallback(
|
|
193
|
+
async () =>
|
|
194
|
+
await getSubscriptions(['com.example.product1', 'com.example.product2']),
|
|
195
|
+
[],
|
|
196
|
+
);
|
|
197
|
+
|
|
198
|
+
return <View />;
|
|
199
|
+
};
|
|
200
|
+
```
|
|
201
|
+
|
|
140
202
|
*/
|
|
141
203
|
|
|
142
204
|
|
|
@@ -150,7 +212,7 @@ const getSubscriptions = _ref2 => {
|
|
|
150
212
|
ios: async () => {
|
|
151
213
|
let items;
|
|
152
214
|
|
|
153
|
-
if (isIosStorekit2()) {
|
|
215
|
+
if ((0, _internal.isIosStorekit2)()) {
|
|
154
216
|
items = (await RNIapIosSk2.getItems(skus)).map(_appleSk.subscriptionSk2Map);
|
|
155
217
|
} else {
|
|
156
218
|
items = await RNIapIos.getItems(skus);
|
|
@@ -159,14 +221,33 @@ const getSubscriptions = _ref2 => {
|
|
|
159
221
|
return items.filter(item => skus.includes(item.productId) && item.type === 'subs');
|
|
160
222
|
},
|
|
161
223
|
android: async () => {
|
|
162
|
-
const subscriptions = await getAndroidModule().getItemsByType(ANDROID_ITEM_TYPE_SUBSCRIPTION, skus);
|
|
224
|
+
const subscriptions = await (0, _internal.getAndroidModule)().getItemsByType(ANDROID_ITEM_TYPE_SUBSCRIPTION, skus);
|
|
163
225
|
return (0, _internal.fillProductsWithAdditionalData)(subscriptions);
|
|
164
226
|
}
|
|
165
227
|
}) || (() => Promise.reject(new Error('Unsupported Platform'))))();
|
|
166
228
|
};
|
|
167
229
|
/**
|
|
168
230
|
* Gets an inventory of purchases made by the user regardless of consumption status
|
|
169
|
-
*
|
|
231
|
+
* ## Usage
|
|
232
|
+
|
|
233
|
+
```tsx
|
|
234
|
+
import React, {useCallback} from 'react';
|
|
235
|
+
import {View} from 'react-native';
|
|
236
|
+
import {getPurchaseHistory} from 'react-native-iap';
|
|
237
|
+
|
|
238
|
+
const App = () => {
|
|
239
|
+
const history = useCallback(
|
|
240
|
+
async () =>
|
|
241
|
+
await getPurchaseHistory([
|
|
242
|
+
'com.example.product1',
|
|
243
|
+
'com.example.product2',
|
|
244
|
+
]),
|
|
245
|
+
[],
|
|
246
|
+
);
|
|
247
|
+
|
|
248
|
+
return <View />;
|
|
249
|
+
};
|
|
250
|
+
```
|
|
170
251
|
*/
|
|
171
252
|
|
|
172
253
|
|
|
@@ -174,7 +255,7 @@ exports.getSubscriptions = getSubscriptions;
|
|
|
174
255
|
|
|
175
256
|
const getPurchaseHistory = () => (_reactNative.Platform.select({
|
|
176
257
|
ios: async () => {
|
|
177
|
-
return getIosModule().getAvailableItems();
|
|
258
|
+
return (0, _internal.getIosModule)().getAvailableItems();
|
|
178
259
|
},
|
|
179
260
|
android: async () => {
|
|
180
261
|
if (RNIapAmazonModule) {
|
|
@@ -188,7 +269,81 @@ const getPurchaseHistory = () => (_reactNative.Platform.select({
|
|
|
188
269
|
}) || (() => Promise.resolve([])))();
|
|
189
270
|
/**
|
|
190
271
|
* Get all purchases made by the user (either non-consumable, or haven't been consumed yet)
|
|
191
|
-
*
|
|
272
|
+
* ## Usage
|
|
273
|
+
|
|
274
|
+
```tsx
|
|
275
|
+
import React, {useCallback} from 'react';
|
|
276
|
+
import {View} from 'react-native';
|
|
277
|
+
import {getAvailablePurchases} from 'react-native-iap';
|
|
278
|
+
|
|
279
|
+
const App = () => {
|
|
280
|
+
const availablePurchases = useCallback(
|
|
281
|
+
async () => await getAvailablePurchases(),
|
|
282
|
+
[],
|
|
283
|
+
);
|
|
284
|
+
|
|
285
|
+
return <View />;
|
|
286
|
+
};
|
|
287
|
+
```
|
|
288
|
+
|
|
289
|
+
## Restoring purchases
|
|
290
|
+
|
|
291
|
+
You can use `getAvailablePurchases()` to do what's commonly understood as "restoring" purchases.
|
|
292
|
+
|
|
293
|
+
:::note
|
|
294
|
+
For debugging you may want to consume all items, you have then to iterate over the purchases returned by `getAvailablePurchases()`.
|
|
295
|
+
:::
|
|
296
|
+
|
|
297
|
+
:::warning
|
|
298
|
+
Beware that if you consume an item without having recorded the purchase in your database the user may have paid for something without getting it delivered and you will have no way to recover the receipt to validate and restore their purchase.
|
|
299
|
+
:::
|
|
300
|
+
|
|
301
|
+
```tsx
|
|
302
|
+
import React from 'react';
|
|
303
|
+
import {Button} from 'react-native';
|
|
304
|
+
import {getAvailablePurchases,finishTransaction} from 'react-native-iap';
|
|
305
|
+
|
|
306
|
+
const App = () => {
|
|
307
|
+
handleRestore = async () => {
|
|
308
|
+
try {
|
|
309
|
+
const purchases = await getAvailablePurchases();
|
|
310
|
+
const newState = {premium: false, ads: true};
|
|
311
|
+
let titles = [];
|
|
312
|
+
|
|
313
|
+
await Promise.all(purchases.map(async purchase => {
|
|
314
|
+
switch (purchase.productId) {
|
|
315
|
+
case 'com.example.premium':
|
|
316
|
+
newState.premium = true;
|
|
317
|
+
titles.push('Premium Version');
|
|
318
|
+
break;
|
|
319
|
+
|
|
320
|
+
case 'com.example.no_ads':
|
|
321
|
+
newState.ads = false;
|
|
322
|
+
titles.push('No Ads');
|
|
323
|
+
break;
|
|
324
|
+
|
|
325
|
+
case 'com.example.coins100':
|
|
326
|
+
await finishTransaction(purchase.purchaseToken);
|
|
327
|
+
CoinStore.addCoins(100);
|
|
328
|
+
}
|
|
329
|
+
})
|
|
330
|
+
|
|
331
|
+
Alert.alert(
|
|
332
|
+
'Restore Successful',
|
|
333
|
+
`You successfully restored the following purchases: ${titles.join(', ')}`,
|
|
334
|
+
);
|
|
335
|
+
} catch (error) {
|
|
336
|
+
console.warn(error);
|
|
337
|
+
Alert.alert(error.message);
|
|
338
|
+
}
|
|
339
|
+
};
|
|
340
|
+
|
|
341
|
+
return (
|
|
342
|
+
<Button title="Restore purchases" onPress={handleRestore} />
|
|
343
|
+
)
|
|
344
|
+
};
|
|
345
|
+
```
|
|
346
|
+
*
|
|
192
347
|
*/
|
|
193
348
|
|
|
194
349
|
|
|
@@ -196,7 +351,7 @@ exports.getPurchaseHistory = getPurchaseHistory;
|
|
|
196
351
|
|
|
197
352
|
const getAvailablePurchases = () => (_reactNative.Platform.select({
|
|
198
353
|
ios: async () => {
|
|
199
|
-
return getIosModule().getAvailableItems();
|
|
354
|
+
return (0, _internal.getIosModule)().getAvailableItems();
|
|
200
355
|
},
|
|
201
356
|
android: async () => {
|
|
202
357
|
if (RNIapAmazonModule) {
|
|
@@ -210,14 +365,70 @@ const getAvailablePurchases = () => (_reactNative.Platform.select({
|
|
|
210
365
|
}) || (() => Promise.resolve([])))();
|
|
211
366
|
/**
|
|
212
367
|
* Request a purchase for product. This will be received in `PurchaseUpdatedListener`.
|
|
213
|
-
*
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
368
|
+
* Request a purchase for a product (consumables or non-consumables).
|
|
369
|
+
|
|
370
|
+
The response will be received through the `PurchaseUpdatedListener`.
|
|
371
|
+
|
|
372
|
+
:::note
|
|
373
|
+
`andDangerouslyFinishTransactionAutomatically` defaults to false. We recommend
|
|
374
|
+
always keeping at false, and verifying the transaction receipts on the server-side.
|
|
375
|
+
:::
|
|
376
|
+
|
|
377
|
+
## Signature
|
|
378
|
+
|
|
379
|
+
```ts
|
|
380
|
+
requestPurchase(
|
|
381
|
+
The product's sku/ID
|
|
382
|
+
sku,
|
|
383
|
+
|
|
384
|
+
|
|
385
|
+
* You should set this to false and call finishTransaction manually when you have delivered the purchased goods to the user.
|
|
386
|
+
* @default false
|
|
387
|
+
|
|
388
|
+
andDangerouslyFinishTransactionAutomaticallyIOS = false,
|
|
389
|
+
|
|
390
|
+
/** Specifies an optional obfuscated string that is uniquely associated with the user's account in your app.
|
|
391
|
+
obfuscatedAccountIdAndroid,
|
|
392
|
+
|
|
393
|
+
Specifies an optional obfuscated string that is uniquely associated with the user's profile in your app.
|
|
394
|
+
obfuscatedProfileIdAndroid,
|
|
395
|
+
|
|
396
|
+
The purchaser's user ID
|
|
397
|
+
applicationUsername,
|
|
398
|
+
): Promise<ProductPurchase>;
|
|
399
|
+
```
|
|
400
|
+
|
|
401
|
+
## Usage
|
|
402
|
+
|
|
403
|
+
```tsx
|
|
404
|
+
import React, {useCallback} from 'react';
|
|
405
|
+
import {Button} from 'react-native';
|
|
406
|
+
import {requestPurchase, Product, Sku, getProducts} from 'react-native-iap';
|
|
407
|
+
|
|
408
|
+
const App = () => {
|
|
409
|
+
const products = useCallback(
|
|
410
|
+
async () => getProducts(['com.example.product']),
|
|
411
|
+
[],
|
|
412
|
+
);
|
|
413
|
+
|
|
414
|
+
const handlePurchase = async (sku: Sku) => {
|
|
415
|
+
await requestPurchase({sku});
|
|
416
|
+
};
|
|
417
|
+
|
|
418
|
+
return (
|
|
419
|
+
<>
|
|
420
|
+
{products.map((product) => (
|
|
421
|
+
<Button
|
|
422
|
+
key={product.productId}
|
|
423
|
+
title="Buy product"
|
|
424
|
+
onPress={() => handlePurchase(product.productId)}
|
|
425
|
+
/>
|
|
426
|
+
))}
|
|
427
|
+
</>
|
|
428
|
+
);
|
|
429
|
+
};
|
|
430
|
+
```
|
|
431
|
+
|
|
221
432
|
*/
|
|
222
433
|
|
|
223
434
|
|
|
@@ -247,7 +458,12 @@ const requestPurchase = _ref3 => {
|
|
|
247
458
|
console.warn('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.');
|
|
248
459
|
}
|
|
249
460
|
|
|
250
|
-
|
|
461
|
+
if ((0, _internal.isIosStorekit2)()) {
|
|
462
|
+
const offer = (0, _appleSk.offerSk2Map)(withOffer);
|
|
463
|
+
return RNIapIosSk2.buyProduct(sku, andDangerouslyFinishTransactionAutomaticallyIOS, appAccountToken, quantity ?? -1, offer);
|
|
464
|
+
} else {
|
|
465
|
+
return RNIapIos.buyProduct(sku, andDangerouslyFinishTransactionAutomaticallyIOS, appAccountToken, quantity ?? -1, withOffer);
|
|
466
|
+
}
|
|
251
467
|
},
|
|
252
468
|
android: async () => {
|
|
253
469
|
if (_internal.isAmazon) {
|
|
@@ -261,22 +477,87 @@ const requestPurchase = _ref3 => {
|
|
|
261
477
|
return Promise.reject(new Error('skus is required for Android purchase'));
|
|
262
478
|
}
|
|
263
479
|
|
|
264
|
-
return getAndroidModule().buyItemByType(ANDROID_ITEM_TYPE_IAP, skus !== null && skus !== void 0 && skus.length ? skus : [sku], undefined, -1, obfuscatedAccountIdAndroid, obfuscatedProfileIdAndroid, [], isOfferPersonalized ?? false);
|
|
480
|
+
return (0, _internal.getAndroidModule)().buyItemByType(ANDROID_ITEM_TYPE_IAP, skus !== null && skus !== void 0 && skus.length ? skus : [sku], undefined, -1, obfuscatedAccountIdAndroid, obfuscatedProfileIdAndroid, [], isOfferPersonalized ?? false);
|
|
265
481
|
}
|
|
266
482
|
}
|
|
267
483
|
}) || Promise.resolve)();
|
|
268
484
|
};
|
|
269
485
|
/**
|
|
270
486
|
* Request a purchase for product. This will be received in `PurchaseUpdatedListener`.
|
|
271
|
-
*
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
487
|
+
* Request a purchase for a subscription.
|
|
488
|
+
|
|
489
|
+
The response will be received through the `PurchaseUpdatedListener`.
|
|
490
|
+
|
|
491
|
+
:::note
|
|
492
|
+
`andDangerouslyFinishTransactionAutomatically` defaults to false. We recommend
|
|
493
|
+
always keeping at false, and verifying the transaction receipts on the server-side.
|
|
494
|
+
:::
|
|
495
|
+
|
|
496
|
+
## Signature
|
|
497
|
+
|
|
498
|
+
```ts
|
|
499
|
+
requestSubscription(
|
|
500
|
+
The product's sku/ID
|
|
501
|
+
sku,
|
|
502
|
+
|
|
503
|
+
|
|
504
|
+
* You should set this to false and call finishTransaction manually when you have delivered the purchased goods to the user.
|
|
505
|
+
* @default false
|
|
506
|
+
|
|
507
|
+
andDangerouslyFinishTransactionAutomaticallyIOS = false,
|
|
508
|
+
|
|
509
|
+
purchaseToken that the user is upgrading or downgrading from (Android).
|
|
510
|
+
purchaseTokenAndroid,
|
|
511
|
+
|
|
512
|
+
UNKNOWN_SUBSCRIPTION_UPGRADE_DOWNGRADE_POLICY, IMMEDIATE_WITH_TIME_PRORATION, IMMEDIATE_AND_CHARGE_PRORATED_PRICE, IMMEDIATE_WITHOUT_PRORATION, DEFERRED
|
|
513
|
+
prorationModeAndroid = -1,
|
|
514
|
+
|
|
515
|
+
/** Specifies an optional obfuscated string that is uniquely associated with the user's account in your app.
|
|
516
|
+
obfuscatedAccountIdAndroid,
|
|
517
|
+
|
|
518
|
+
Specifies an optional obfuscated string that is uniquely associated with the user's profile in your app.
|
|
519
|
+
obfuscatedProfileIdAndroid,
|
|
520
|
+
|
|
521
|
+
The purchaser's user ID
|
|
522
|
+
applicationUsername,
|
|
523
|
+
): Promise<SubscriptionPurchase>
|
|
524
|
+
```
|
|
525
|
+
|
|
526
|
+
## Usage
|
|
527
|
+
|
|
528
|
+
```tsx
|
|
529
|
+
import React, {useCallback} from 'react';
|
|
530
|
+
import {Button} from 'react-native';
|
|
531
|
+
import {
|
|
532
|
+
requestSubscription,
|
|
533
|
+
Product,
|
|
534
|
+
Sku,
|
|
535
|
+
getSubscriptions,
|
|
536
|
+
} from 'react-native-iap';
|
|
537
|
+
|
|
538
|
+
const App = () => {
|
|
539
|
+
const subscriptions = useCallback(
|
|
540
|
+
async () => getSubscriptions(['com.example.subscription']),
|
|
541
|
+
[],
|
|
542
|
+
);
|
|
543
|
+
|
|
544
|
+
const handlePurchase = async (sku: Sku) => {
|
|
545
|
+
await requestSubscription({sku});
|
|
546
|
+
};
|
|
547
|
+
|
|
548
|
+
return (
|
|
549
|
+
<>
|
|
550
|
+
{subscriptions.map((subscription) => (
|
|
551
|
+
<Button
|
|
552
|
+
key={subscription.productId}
|
|
553
|
+
title="Buy subscription"
|
|
554
|
+
onPress={() => handlePurchase(subscription.productId)}
|
|
555
|
+
/>
|
|
556
|
+
))}
|
|
557
|
+
</>
|
|
558
|
+
);
|
|
559
|
+
};
|
|
560
|
+
```
|
|
280
561
|
*/
|
|
281
562
|
|
|
282
563
|
|
|
@@ -308,7 +589,12 @@ const requestSubscription = _ref4 => {
|
|
|
308
589
|
console.warn('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.');
|
|
309
590
|
}
|
|
310
591
|
|
|
311
|
-
|
|
592
|
+
if ((0, _internal.isIosStorekit2)()) {
|
|
593
|
+
const offer = (0, _appleSk.offerSk2Map)(withOffer);
|
|
594
|
+
return RNIapIosSk2.buyProduct(sku, andDangerouslyFinishTransactionAutomaticallyIOS, appAccountToken, quantity ?? -1, offer);
|
|
595
|
+
} else {
|
|
596
|
+
return RNIapIos.buyProduct(sku, andDangerouslyFinishTransactionAutomaticallyIOS, appAccountToken, quantity ?? -1, withOffer);
|
|
597
|
+
}
|
|
312
598
|
},
|
|
313
599
|
android: async () => {
|
|
314
600
|
if (_internal.isAmazon) {
|
|
@@ -334,10 +620,22 @@ const requestSubscription = _ref4 => {
|
|
|
334
620
|
* Call this after you have persisted the purchased state to your server or local data in your app.
|
|
335
621
|
* `react-native-iap` will continue to deliver the purchase updated events with the successful purchase until you finish the transaction. **Even after the app has relaunched.**
|
|
336
622
|
* Android: it will consume purchase for consumables and acknowledge purchase for non-consumables.
|
|
337
|
-
*
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
623
|
+
*
|
|
624
|
+
```tsx
|
|
625
|
+
import React from 'react';
|
|
626
|
+
import {Button} from 'react-native';
|
|
627
|
+
import {finishTransaction} from 'react-native-iap';
|
|
628
|
+
|
|
629
|
+
const App = () => {
|
|
630
|
+
const handlePurchase = async () => {
|
|
631
|
+
// ... handle the purchase request
|
|
632
|
+
|
|
633
|
+
const result = finishTransaction(purchase);
|
|
634
|
+
};
|
|
635
|
+
|
|
636
|
+
return <Button title="Buy product" onPress={handlePurchase} />;
|
|
637
|
+
};
|
|
638
|
+
```
|
|
341
639
|
*/
|
|
342
640
|
|
|
343
641
|
|
|
@@ -357,14 +655,14 @@ const finishTransaction = _ref5 => {
|
|
|
357
655
|
return Promise.reject(new Error('transactionId required to finish iOS transaction'));
|
|
358
656
|
}
|
|
359
657
|
|
|
360
|
-
return getIosModule().finishTransaction(transactionId);
|
|
658
|
+
return (0, _internal.getIosModule)().finishTransaction(transactionId);
|
|
361
659
|
},
|
|
362
660
|
android: async () => {
|
|
363
661
|
if (purchase !== null && purchase !== void 0 && purchase.purchaseToken) {
|
|
364
662
|
if (isConsumable) {
|
|
365
|
-
return getAndroidModule().consumeProduct(purchase.purchaseToken, developerPayloadAndroid);
|
|
663
|
+
return (0, _internal.getAndroidModule)().consumeProduct(purchase.purchaseToken, developerPayloadAndroid);
|
|
366
664
|
} else if (purchase.userIdAmazon || !purchase.isAcknowledgedAndroid && purchase.purchaseStateAndroid === _types.PurchaseStateAndroid.PURCHASED) {
|
|
367
|
-
return getAndroidModule().acknowledgePurchase(purchase.purchaseToken, developerPayloadAndroid);
|
|
665
|
+
return (0, _internal.getAndroidModule)().acknowledgePurchase(purchase.purchaseToken, developerPayloadAndroid);
|
|
368
666
|
} else {
|
|
369
667
|
return Promise.reject(new Error('purchase is not suitable to be purchased'));
|
|
370
668
|
}
|
|
@@ -374,241 +672,6 @@ const finishTransaction = _ref5 => {
|
|
|
374
672
|
}
|
|
375
673
|
}) || (() => Promise.reject(new Error('Unsupported Platform'))))();
|
|
376
674
|
};
|
|
377
|
-
/**
|
|
378
|
-
* Clear Transaction (iOS only)
|
|
379
|
-
* Finish remaining transactions. Related to issue #257 and #801
|
|
380
|
-
* link : https://github.com/dooboolab/react-native-iap/issues/257
|
|
381
|
-
* https://github.com/dooboolab/react-native-iap/issues/801
|
|
382
|
-
* @returns {Promise<void>}
|
|
383
|
-
*/
|
|
384
|
-
|
|
385
675
|
|
|
386
676
|
exports.finishTransaction = finishTransaction;
|
|
387
|
-
|
|
388
|
-
const clearTransactionIOS = () => getIosModule().clearTransaction();
|
|
389
|
-
/**
|
|
390
|
-
* Clear valid Products (iOS only)
|
|
391
|
-
* Remove all products which are validated by Apple server.
|
|
392
|
-
* @returns {void}
|
|
393
|
-
*/
|
|
394
|
-
|
|
395
|
-
|
|
396
|
-
exports.clearTransactionIOS = clearTransactionIOS;
|
|
397
|
-
|
|
398
|
-
const clearProductsIOS = () => getIosModule().clearProducts();
|
|
399
|
-
/**
|
|
400
|
-
* Acknowledge a product (on Android.) No-op on iOS.
|
|
401
|
-
* @param {string} token The product's token (on Android)
|
|
402
|
-
* @returns {Promise<PurchaseResult | void>}
|
|
403
|
-
*/
|
|
404
|
-
|
|
405
|
-
|
|
406
|
-
exports.clearProductsIOS = clearProductsIOS;
|
|
407
|
-
|
|
408
|
-
const acknowledgePurchaseAndroid = _ref6 => {
|
|
409
|
-
let {
|
|
410
|
-
token,
|
|
411
|
-
developerPayload
|
|
412
|
-
} = _ref6;
|
|
413
|
-
return getAndroidModule().acknowledgePurchase(token, developerPayload);
|
|
414
|
-
};
|
|
415
|
-
/**
|
|
416
|
-
* Deep link to subscriptions screen on Android. No-op on iOS.
|
|
417
|
-
* @param {string} sku The product's SKU (on Android)
|
|
418
|
-
* @returns {Promise<void>}
|
|
419
|
-
*/
|
|
420
|
-
|
|
421
|
-
|
|
422
|
-
exports.acknowledgePurchaseAndroid = acknowledgePurchaseAndroid;
|
|
423
|
-
|
|
424
|
-
const deepLinkToSubscriptionsAndroid = async _ref7 => {
|
|
425
|
-
let {
|
|
426
|
-
sku
|
|
427
|
-
} = _ref7;
|
|
428
|
-
checkNativeAndroidAvailable();
|
|
429
|
-
return _reactNative.Linking.openURL(`https://play.google.com/store/account/subscriptions?package=${await RNIapModule.getPackageName()}&sku=${sku}`);
|
|
430
|
-
};
|
|
431
|
-
/**
|
|
432
|
-
* Should Add Store Payment (iOS only)
|
|
433
|
-
* Indicates the the App Store purchase should continue from the app instead of the App Store.
|
|
434
|
-
* @returns {Promise<Product | null>} promoted product
|
|
435
|
-
*/
|
|
436
|
-
|
|
437
|
-
|
|
438
|
-
exports.deepLinkToSubscriptionsAndroid = deepLinkToSubscriptionsAndroid;
|
|
439
|
-
|
|
440
|
-
const getPromotedProductIOS = () => {
|
|
441
|
-
if (!isIosStorekit2) {
|
|
442
|
-
return getIosModule().promotedProduct();
|
|
443
|
-
} else {
|
|
444
|
-
return Promise.reject('Only available on SK1');
|
|
445
|
-
}
|
|
446
|
-
};
|
|
447
|
-
/**
|
|
448
|
-
* Buy the currently selected promoted product (iOS only)
|
|
449
|
-
* Initiates the payment process for a promoted product. Should only be called in response to the `iap-promoted-product` event.
|
|
450
|
-
* @returns {Promise<void>}
|
|
451
|
-
*/
|
|
452
|
-
|
|
453
|
-
|
|
454
|
-
exports.getPromotedProductIOS = getPromotedProductIOS;
|
|
455
|
-
|
|
456
|
-
const buyPromotedProductIOS = () => getIosModule().buyPromotedProduct();
|
|
457
|
-
|
|
458
|
-
exports.buyPromotedProductIOS = buyPromotedProductIOS;
|
|
459
|
-
const TEST_RECEIPT = 21007;
|
|
460
|
-
|
|
461
|
-
const requestAgnosticReceiptValidationIos = async receiptBody => {
|
|
462
|
-
const response = await (0, _internal.enhancedFetch)('https://buy.itunes.apple.com/verifyReceipt', {
|
|
463
|
-
method: 'POST',
|
|
464
|
-
body: receiptBody
|
|
465
|
-
}); // Best practice is to check for test receipt and check sandbox instead
|
|
466
|
-
// https://developer.apple.com/documentation/appstorereceipts/verifyreceipt
|
|
467
|
-
|
|
468
|
-
if (response && response.status === TEST_RECEIPT) {
|
|
469
|
-
const testResponse = await (0, _internal.enhancedFetch)('https://sandbox.itunes.apple.com/verifyReceipt', {
|
|
470
|
-
method: 'POST',
|
|
471
|
-
body: receiptBody
|
|
472
|
-
});
|
|
473
|
-
return testResponse;
|
|
474
|
-
}
|
|
475
|
-
|
|
476
|
-
return response;
|
|
477
|
-
};
|
|
478
|
-
/**
|
|
479
|
-
* Buy products or subscriptions with offers (iOS only)
|
|
480
|
-
*
|
|
481
|
-
* Runs the payment process with some info you must fetch
|
|
482
|
-
* from your server.
|
|
483
|
-
* @param {string} sku The product identifier
|
|
484
|
-
* @param {string} forUser An user identifier on you system
|
|
485
|
-
* @param {Apple.PaymentDiscount} withOffer The offer information
|
|
486
|
-
* @param {string} withOffer.identifier The offer identifier
|
|
487
|
-
* @param {string} withOffer.keyIdentifier Key identifier that it uses to generate the signature
|
|
488
|
-
* @param {string} withOffer.nonce An UUID returned from the server
|
|
489
|
-
* @param {string} withOffer.signature The actual signature returned from the server
|
|
490
|
-
* @param {number} withOffer.timestamp The timestamp of the signature
|
|
491
|
-
* @returns {Promise<void>}
|
|
492
|
-
*/
|
|
493
|
-
|
|
494
|
-
|
|
495
|
-
const requestPurchaseWithOfferIOS = _ref8 => {
|
|
496
|
-
let {
|
|
497
|
-
sku,
|
|
498
|
-
forUser,
|
|
499
|
-
withOffer
|
|
500
|
-
} = _ref8;
|
|
501
|
-
return getIosModule().buyProductWithOffer(sku, forUser, withOffer);
|
|
502
|
-
};
|
|
503
|
-
/**
|
|
504
|
-
* Validate receipt for iOS.
|
|
505
|
-
* @param {object} receiptBody the receipt body to send to apple server.
|
|
506
|
-
* @param {boolean} isTest whether this is in test environment which is sandbox.
|
|
507
|
-
* @returns {Promise<Apple.ReceiptValidationResponse | false>}
|
|
508
|
-
*/
|
|
509
|
-
|
|
510
|
-
|
|
511
|
-
exports.requestPurchaseWithOfferIOS = requestPurchaseWithOfferIOS;
|
|
512
|
-
|
|
513
|
-
const validateReceiptIos = async _ref9 => {
|
|
514
|
-
let {
|
|
515
|
-
receiptBody,
|
|
516
|
-
isTest
|
|
517
|
-
} = _ref9;
|
|
518
|
-
|
|
519
|
-
if (isTest == null) {
|
|
520
|
-
return await requestAgnosticReceiptValidationIos(receiptBody);
|
|
521
|
-
}
|
|
522
|
-
|
|
523
|
-
const url = isTest ? 'https://sandbox.itunes.apple.com/verifyReceipt' : 'https://buy.itunes.apple.com/verifyReceipt';
|
|
524
|
-
return await (0, _internal.enhancedFetch)(url);
|
|
525
|
-
};
|
|
526
|
-
/**
|
|
527
|
-
* Validate receipt for Android. NOTE: This method is here for debugging purposes only. Including
|
|
528
|
-
* your access token in the binary you ship to users is potentially dangerous.
|
|
529
|
-
* Use server side validation instead for your production builds
|
|
530
|
-
* @param {string} packageName package name of your app.
|
|
531
|
-
* @param {string} productId product id for your in app product.
|
|
532
|
-
* @param {string} productToken token for your purchase.
|
|
533
|
-
* @param {string} accessToken accessToken from googleApis.
|
|
534
|
-
* @param {boolean} isSub whether this is subscription or inapp. `true` for subscription.
|
|
535
|
-
* @returns {Promise<object>}
|
|
536
|
-
*/
|
|
537
|
-
|
|
538
|
-
|
|
539
|
-
exports.validateReceiptIos = validateReceiptIos;
|
|
540
|
-
|
|
541
|
-
const validateReceiptAndroid = async _ref10 => {
|
|
542
|
-
let {
|
|
543
|
-
packageName,
|
|
544
|
-
productId,
|
|
545
|
-
productToken,
|
|
546
|
-
accessToken,
|
|
547
|
-
isSub
|
|
548
|
-
} = _ref10;
|
|
549
|
-
const type = isSub ? 'subscriptions' : 'products';
|
|
550
|
-
const url = 'https://androidpublisher.googleapis.com/androidpublisher/v3/applications' + `/${packageName}/purchases/${type}/${productId}` + `/tokens/${productToken}?access_token=${accessToken}`;
|
|
551
|
-
return await (0, _internal.enhancedFetch)(url);
|
|
552
|
-
};
|
|
553
|
-
/**
|
|
554
|
-
* Validate receipt for Amazon. NOTE: This method is here for debugging purposes only. Including
|
|
555
|
-
* your developer secret in the binary you ship to users is potentially dangerous.
|
|
556
|
-
* Use server side validation instead for your production builds
|
|
557
|
-
* @param {string} developerSecret: from the Amazon developer console.
|
|
558
|
-
* @param {string} userId who purchased the item.
|
|
559
|
-
* @param {string} receiptId long obfuscated string returned when purchasing the item
|
|
560
|
-
* @param {boolean} useSandbox Defaults to true, use sandbox environment or production.
|
|
561
|
-
* @returns {Promise<object>}
|
|
562
|
-
*/
|
|
563
|
-
|
|
564
|
-
|
|
565
|
-
exports.validateReceiptAndroid = validateReceiptAndroid;
|
|
566
|
-
|
|
567
|
-
const validateReceiptAmazon = async _ref11 => {
|
|
568
|
-
let {
|
|
569
|
-
developerSecret,
|
|
570
|
-
userId,
|
|
571
|
-
receiptId,
|
|
572
|
-
useSandbox = true
|
|
573
|
-
} = _ref11;
|
|
574
|
-
const sandBoxUrl = useSandbox ? 'sandbox/' : '';
|
|
575
|
-
const url = `https://appstore-sdk.amazon.com/${sandBoxUrl}version/1.0/verifyReceiptId/developer/${developerSecret}/user/${userId}/receiptId/${receiptId}`;
|
|
576
|
-
return await (0, _internal.enhancedFetch)(url);
|
|
577
|
-
};
|
|
578
|
-
/**
|
|
579
|
-
* Get the current receipt base64 encoded in IOS.
|
|
580
|
-
* @param {forceRefresh?:boolean}
|
|
581
|
-
* @returns {Promise<ProductPurchase[]>}
|
|
582
|
-
*/
|
|
583
|
-
|
|
584
|
-
|
|
585
|
-
exports.validateReceiptAmazon = validateReceiptAmazon;
|
|
586
|
-
|
|
587
|
-
const getPendingPurchasesIOS = async () => getIosModule().getPendingTransactions();
|
|
588
|
-
/**
|
|
589
|
-
* Get the current receipt base64 encoded in IOS.
|
|
590
|
-
* @param {forceRefresh?:boolean}
|
|
591
|
-
* @returns {Promise<string>}
|
|
592
|
-
*/
|
|
593
|
-
|
|
594
|
-
|
|
595
|
-
exports.getPendingPurchasesIOS = getPendingPurchasesIOS;
|
|
596
|
-
|
|
597
|
-
const getReceiptIOS = async _ref12 => {
|
|
598
|
-
let {
|
|
599
|
-
forceRefresh
|
|
600
|
-
} = _ref12;
|
|
601
|
-
return getIosModule().requestReceipt(forceRefresh ?? false);
|
|
602
|
-
};
|
|
603
|
-
/**
|
|
604
|
-
* Launches a modal to register the redeem offer code in IOS.
|
|
605
|
-
* @returns {Promise<null>}
|
|
606
|
-
*/
|
|
607
|
-
|
|
608
|
-
|
|
609
|
-
exports.getReceiptIOS = getReceiptIOS;
|
|
610
|
-
|
|
611
|
-
const presentCodeRedemptionSheetIOS = async () => getIosModule().presentCodeRedemptionSheet();
|
|
612
|
-
|
|
613
|
-
exports.presentCodeRedemptionSheetIOS = presentCodeRedemptionSheetIOS;
|
|
614
677
|
//# sourceMappingURL=iap.js.map
|