react-native-iap 7.2.1 → 7.5.0

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/CHANGELOG.md CHANGED
@@ -1,5 +1,27 @@
1
1
  ## Changelogs
2
2
 
3
+ # 7.5.0
4
+
5
+ ### Bugfix
6
+ - Fix canceled purchase dangling [#1504](https://github.com/dooboolab/react-native-iap/pull/1504)
7
+
8
+ ### Dependencies
9
+ - Set default `androidX` version [#1505](https://github.com/dooboolab/react-native-iap/pull/1505)
10
+ - Update packages [#1506](https://github.com/dooboolab/react-native-iap/pull/1506)
11
+
12
+ # 7.4.1
13
+
14
+ - [iOS] Add `quantityIOS` in purchase data [#1476](https://github.com/dooboolab/react-native-iap/pull/1476)
15
+
16
+ # 7.4.0
17
+
18
+ - Now using React's Context to manage IAP state
19
+ - Introduce `withIAPContext` HOC ([how to use](docs/docs/usage_instructions/using_hooks.md))
20
+
21
+ # 7.3.0
22
+
23
+ _Breaking Change_:Amazon's receipt was incorrectly being put in `originalJson` it now matches the other platforms: `transactionReceipt` [#1461](https://github.com/dooboolab/react-native-iap/pull/1461)
24
+
3
25
  # 7.2.1
4
26
 
5
27
  Fix android crash by delaying ios check [#1456](https://github.com/dooboolab/react-native-iap/pull/1456)
package/README.md CHANGED
@@ -6,7 +6,7 @@
6
6
  [![CI](https://github.com/dooboolab/react-native-iap/actions/workflows/ci.yml/badge.svg)](https://github.com/dooboolab/react-native-iap/actions/workflows/ci.yml)
7
7
  [![document](https://github.com/dooboolab/react-native-iap/actions/workflows/deploy-document.yml/badge.svg)](https://github.com/dooboolab/react-native-iap/actions/workflows/deploy-document.yml)
8
8
  [![License](https://img.shields.io/npm/l/react-native-iap.svg)](https://npmjs.org/package/react-native-iap)
9
- [![Vulnerabilites](https://img.shields.io/snyk/vulnerabilities/github/dooboolab/react-native-iap.svg)](https://github.com/dooboolab/react-native-iap)
9
+ [![Vulnerabilities](https://img.shields.io/snyk/vulnerabilities/github/dooboolab/react-native-iap.svg)](https://github.com/dooboolab/react-native-iap)
10
10
  [![Issue Opened](https://img.shields.io/opencollective/all/react-native-iap.svg)](https://opencollective.com/react-native-iap#backers)
11
11
  [![Issue Opened](https://img.shields.io/github/issues/dooboolab/react-native-iap.svg)](https://github.com/dooboolab/react-native-iap/issues)
12
12
  [![Issue Closed](https://img.shields.io/github/issues-closed/dooboolab/react-native-iap.svg)](https://github.com/dooboolab/react-native-iap/issues?q=is%3Aissue+is%3Aclosed)
@@ -90,17 +90,21 @@ Quick News
90
90
  - We had hard time supporting `react-native-iap` issues that did not provide working codes or any other examples. Therefore, we've decided to make an `example` app called [DoobooIAP](https://github.com/hyochan/DoobooIAP), which will contain all the features of `IAP`'s and willing to continuously improve to support real-life examples. [@Bang9](http://github.com/bang9) who had been helping many others for `react-native-iap`, is willing to support this repo so he will grant $300 of our income in `opencollective` as described in [#855](https://github.com/dooboolab/react-native-iap/issues/855) :tada:.
91
91
  - `react-native-iap@4.0.8` ~ `react-native-iap@4.1.0` is incompatible with `react-native <0.61`. This is fixed in `react-native-iap@4.1.1` and above.
92
92
  - `react-native-iap@4.0.0` has been released. You can see [#716](https://github.com/dooboolab/react-native-iap/pull/716) for updates.
93
- - In the past, `react-native-iap@^3.*` has been updated very prompty for migration issues.
94
- Don't get suprised too much on why it is bumping up version so quickly these days.
93
+ - In the past, `react-native-iap@^3.*` has been updated very promptly for migration issues.
94
+ Don't get surprised too much on why it is bumping up version so quickly these days.
95
95
  1. Migrated to new `AndroidX` APIs.
96
96
  2. Migrated to new `Android` billing client which is `> 2.0.0`.
97
97
  - [`acknowledgePurchase()`][android-acknowledge-purchase] has been added since `3.2.0` which is very important.
98
98
  3. New [Purchase Flow][a-purchase-flow]
99
- 4. More is comming in `iOS 13`.
99
+ 4. More is coming in `iOS 13`.
100
100
 
101
101
  Breaking Changes
102
102
  ----------------
103
103
 
104
+ [7.4.0]
105
+ - Now using React's Context to manage IAP state
106
+ - Introduce `withIAPContext` HOC ([how to use](docs/docs/usage_instructions/using_hooks.md))
107
+
104
108
  [7.1.0]
105
109
  - `androidOldSku` is no longer required [#1438](https://github.com/dooboolab/react-native-iap/pull/1438).
106
110
 
@@ -71,7 +71,7 @@ dependencies {
71
71
  implementation "com.android.support:support-annotations:$supportLibVersion"
72
72
  implementation "com.android.support:customtabs:$supportLibVersion"
73
73
  } else {
74
- def defaultAndroidXVersion = "1.+"
74
+ def defaultAndroidXVersion = "1.2.0"
75
75
  if (androidXVersion == null) {
76
76
  androidXVersion = defaultAndroidXVersion
77
77
  }
@@ -1,6 +1,7 @@
1
1
  package com.dooboolab.RNIap;
2
2
 
3
3
  import android.util.Log;
4
+ import androidx.annotation.NonNull;
4
5
  import androidx.annotation.Nullable;
5
6
  import com.amazon.device.iap.PurchasingListener;
6
7
  import com.amazon.device.iap.PurchasingService;
@@ -154,14 +155,7 @@ public class RNIapAmazonListener implements PurchasingListener {
154
155
  WritableMap promiseItem = null;
155
156
  final List<Receipt> purchases = response.getReceipts();
156
157
  for (Receipt receipt : purchases) {
157
- WritableMap item = Arguments.createMap();
158
- item.putString("productId", receipt.getSku());
159
- item.putDouble("transactionDate", receipt.getPurchaseDate().getTime());
160
- item.putString("purchaseToken", receipt.getReceiptId());
161
- item.putString("originalJson", receipt.toJSON().toString());
162
- item.putString("userIdAmazon", userData.getUserId());
163
- item.putString("userMarketplaceAmazon", userData.getMarketplace());
164
- item.putString("userJsonAmazon", userData.toJSON().toString());
158
+ WritableMap item = receiptToMap(userData, receipt);
165
159
 
166
160
  promiseItem = new WritableNativeMap();
167
161
  promiseItem.merge(item);
@@ -234,6 +228,20 @@ public class RNIapAmazonListener implements PurchasingListener {
234
228
  }
235
229
  }
236
230
 
231
+ @NonNull
232
+ private WritableMap receiptToMap(UserData userData, Receipt receipt) {
233
+ WritableMap item = Arguments.createMap();
234
+ item.putString("productId", receipt.getSku());
235
+ item.putDouble("transactionDate", receipt.getPurchaseDate().getTime());
236
+ item.putString("purchaseToken", receipt.getReceiptId());
237
+ item.putString("transactionReceipt", receipt.toJSON().toString());
238
+ item.putString("userIdAmazon", userData.getUserId());
239
+ item.putString("userMarketplaceAmazon", userData.getMarketplace());
240
+ item.putString("userJsonAmazon", userData.toJSON().toString());
241
+ item.putBoolean("isCanceledAmazon", receipt.isCanceled());
242
+ return item;
243
+ }
244
+
237
245
  @Override
238
246
  public void onPurchaseResponse(final PurchaseResponse response) {
239
247
  final String requestId = response.getRequestId().toString();
@@ -249,14 +257,7 @@ public class RNIapAmazonListener implements PurchasingListener {
249
257
  case SUCCESSFUL:
250
258
  final Receipt receipt = response.getReceipt();
251
259
  final UserData userData = response.getUserData();
252
- WritableMap item = Arguments.createMap();
253
- item.putString("productId", receipt.getSku());
254
- item.putDouble("transactionDate", receipt.getPurchaseDate().getTime());
255
- item.putString("purchaseToken", receipt.getReceiptId());
256
- item.putString("originalJson", receipt.toJSON().toString());
257
- item.putString("userIdAmazon", userData.getUserId());
258
- item.putString("userMarketplaceAmazon", userData.getMarketplace());
259
- item.putString("userJsonAmazon", userData.toJSON().toString());
260
+ WritableMap item = receiptToMap(userData, receipt);
260
261
 
261
262
  WritableMap promiseItem = new WritableNativeMap();
262
263
  promiseItem.merge(item);
@@ -583,9 +583,7 @@ public class RNIapModule extends ReactContextBaseJavaModule implements Purchases
583
583
  error.putString("message", errorData[1]);
584
584
  sendEvent(reactContext, "purchase-error", error);
585
585
 
586
- if (responseCode != BillingClient.BillingResponseCode.USER_CANCELED) {
587
- PlayUtils.getInstance().rejectPromisesWithBillingError(PROMISE_BUY_ITEM, responseCode);
588
- }
586
+ PlayUtils.getInstance().rejectPromisesWithBillingError(PROMISE_BUY_ITEM, responseCode);
589
587
  return;
590
588
  }
591
589
 
@@ -247,7 +247,7 @@
247
247
  GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
248
248
  GCC_WARN_UNUSED_FUNCTION = YES;
249
249
  GCC_WARN_UNUSED_VARIABLE = YES;
250
- IPHONEOS_DEPLOYMENT_TARGET = 8.0;
250
+ IPHONEOS_DEPLOYMENT_TARGET = 10.0;
251
251
  MTL_ENABLE_DEBUG_INFO = YES;
252
252
  ONLY_ACTIVE_ARCH = YES;
253
253
  SDKROOT = iphoneos;
@@ -293,7 +293,7 @@
293
293
  GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
294
294
  GCC_WARN_UNUSED_FUNCTION = YES;
295
295
  GCC_WARN_UNUSED_VARIABLE = YES;
296
- IPHONEOS_DEPLOYMENT_TARGET = 8.0;
296
+ IPHONEOS_DEPLOYMENT_TARGET = 10.0;
297
297
  MTL_ENABLE_DEBUG_INFO = NO;
298
298
  SDKROOT = iphoneos;
299
299
  VALIDATE_PRODUCT = YES;
package/ios/RNIapIos.m CHANGED
@@ -327,6 +327,7 @@ RCT_EXPORT_METHOD(getPendingTransactions:(RCTPromiseResolveBlock)resolve
327
327
  @(item.transactionDate.timeIntervalSince1970 * 1000), @"transactionDate",
328
328
  item.transactionIdentifier, @"transactionId",
329
329
  item.payment.productIdentifier, @"productId",
330
+ @(item.payment.quantity), @"quantityIOS",
330
331
  [receiptData base64EncodedStringWithOptions:0], @"transactionReceipt",
331
332
  nil
332
333
  ];
@@ -462,11 +463,9 @@ RCT_EXPORT_METHOD(presentCodeRedemptionSheet:(RCTPromiseResolveBlock)resolve
462
463
  [self sendEventWithName:@"purchase-error" body:err];
463
464
  }
464
465
 
465
- if (transaction.error.code != SKErrorPaymentCancelled) {
466
- [self rejectPromisesForKey:transaction.payment.productIdentifier code:[self standardErrorCode:(int)transaction.error.code]
467
- message:transaction.error.localizedDescription
468
- error:transaction.error];
469
- }
466
+ [self rejectPromisesForKey:transaction.payment.productIdentifier code:[self standardErrorCode:(int)transaction.error.code]
467
+ message:transaction.error.localizedDescription
468
+ error:transaction.error];
470
469
  });
471
470
  break;
472
471
  }
@@ -768,6 +767,7 @@ RCT_EXPORT_METHOD(presentCodeRedemptionSheet:(RCTPromiseResolveBlock)resolve
768
767
  @(transaction.transactionDate.timeIntervalSince1970 * 1000), @"transactionDate",
769
768
  transaction.transactionIdentifier, @"transactionId",
770
769
  transaction.payment.productIdentifier, @"productId",
770
+ @(transaction.payment.quantity), @"quantityIOS",
771
771
  [receiptData base64EncodedStringWithOptions:0], @"transactionReceipt",
772
772
  nil
773
773
  ];
@@ -0,0 +1,11 @@
1
+ // WIP Migrating from Objective C to swift
2
+ func paymentQueue(_ queue: SKPaymentQueue, removedTransactions transactions: [SKPaymentTransaction]) {
3
+ print("removedTransactions")
4
+ if countPendingTransaction != nil && countPendingTransaction > 0 {
5
+ countPendingTransaction -= transactions.count
6
+ if countPendingTransaction == 0 {
7
+ resolvePromises(forKey: "cleaningTransactions", value: nil)
8
+ countPendingTransaction = nil
9
+ }
10
+ }
11
+ }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "react-native-iap",
3
- "version": "7.2.1",
3
+ "version": "7.5.0",
4
4
  "description": "React Native In App Purchase Module.",
5
5
  "main": "index.js",
6
6
  "types": "index.d.ts",
@@ -43,31 +43,31 @@
43
43
  "dooboolab-welcome": "1.3.2"
44
44
  },
45
45
  "devDependencies": {
46
- "@babel/core": "7.14.8",
46
+ "@babel/core": "7.15.5",
47
47
  "@babel/plugin-proposal-class-properties": "7.14.5",
48
48
  "@babel/plugin-proposal-private-methods": "7.14.5",
49
- "@babel/preset-env": "7.14.8",
49
+ "@babel/preset-env": "7.15.6",
50
50
  "@babel/preset-react": "7.14.5",
51
- "@babel/preset-typescript": "7.14.5",
52
- "@dooboo/eslint-config": "0.8.2",
53
- "@testing-library/jest-native": "4.0.1",
51
+ "@babel/preset-typescript": "7.15.0",
52
+ "@dooboo/eslint-config": "0.8.5",
53
+ "@testing-library/jest-native": "4.0.2",
54
54
  "@testing-library/react-native": "7.2.0",
55
55
  "@types/eslint": "7.28.0",
56
- "@types/jest": "26.0.24",
57
- "@types/react": "17.0.15",
58
- "@types/react-native": "0.64.12",
56
+ "@types/jest": "27.0.1",
57
+ "@types/react": "17.0.21",
58
+ "@types/react-native": "0.65.0",
59
59
  "babel-core": "7.0.0-bridge.0",
60
60
  "babel-eslint": "10.1.0",
61
- "babel-jest": "27.0.6",
62
- "eslint": "7.31.0",
63
- "flow-bin": "0.156.0",
61
+ "babel-jest": "27.2.0",
62
+ "eslint": "7.32.0",
63
+ "flow-bin": "0.160.0",
64
64
  "flowgen": "1.14.1",
65
- "jest": "27.0.6",
65
+ "jest": "27.2.0",
66
66
  "metro-react-native-babel-preset": "0.66.2",
67
- "monolinter": "1.0.2",
68
- "prettier": "2.3.2",
67
+ "monolinter": "1.0.4",
68
+ "prettier": "2.4.1",
69
69
  "react-native": "0.64.2",
70
- "ts-jest": "27.0.4",
71
- "typescript": "4.3.5"
70
+ "ts-jest": "27.0.5",
71
+ "typescript": "4.4.3"
72
72
  }
73
73
  }
@@ -1,4 +1,5 @@
1
1
  import type { Product, Purchase, PurchaseError, Subscription } from '../types';
2
+ import { requestPurchase as iapRequestPurchase, requestSubscription as iapRequestSubscription } from '../iap';
2
3
  declare type IAP_STATUS = {
3
4
  connected: boolean;
4
5
  products: Product[];
@@ -13,6 +14,8 @@ declare type IAP_STATUS = {
13
14
  getPurchaseHistories: () => Promise<void>;
14
15
  getProducts: (skus: string[]) => Promise<void>;
15
16
  getSubscriptions: (skus: string[]) => Promise<void>;
17
+ requestPurchase: typeof iapRequestPurchase;
18
+ requesSubscription: typeof iapRequestSubscription;
16
19
  };
17
20
  export declare function useIAP(): IAP_STATUS;
18
21
  export {};
@@ -34,53 +34,38 @@ var __generator = (this && this.__generator) || function (thisArg, body) {
34
34
  if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true };
35
35
  }
36
36
  };
37
- var __spreadArray = (this && this.__spreadArray) || function (to, from) {
38
- for (var i = 0, il = from.length, j = to.length; i < il; i++, j++)
39
- to[j] = from[i];
40
- return to;
41
- };
42
- import { NativeEventEmitter, NativeModules, } from 'react-native';
43
- import { endConnection, getPromotedProductIOS, getPurchaseHistory, finishTransaction as iapFinishTransaction, getAvailablePurchases as iapGetAvailablePurchases, getProducts as iapGetProducts, getSubscriptions as iapGetSubscriptions, initConnection, purchaseErrorListener, purchaseUpdatedListener, } from '../iap';
44
- import { useCallback, useEffect, useState } from 'react';
45
- var RNIapIos = NativeModules.RNIapIos;
46
- var IAPEmitter = new NativeEventEmitter(RNIapIos);
47
- var purchaseUpdateSubscription;
48
- var purchaseErrorSubscription;
49
- var promotedProductsSubscription;
37
+ import { getPurchaseHistory, finishTransaction as iapFinishTransaction, getAvailablePurchases as iapGetAvailablePurchases, getProducts as iapGetProducts, getSubscriptions as iapGetSubscriptions, requestPurchase as iapRequestPurchase, requestSubscription as iapRequestSubscription, } from '../iap';
38
+ import { useCallback } from 'react';
39
+ import { useIAPContext } from './withIAPContext';
50
40
  export function useIAP() {
51
41
  var _this = this;
52
- var _a = useState(false), connected = _a[0], setConnected = _a[1];
53
- var _b = useState([]), products = _b[0], setProducts = _b[1];
54
- var _c = useState([]), promotedProductsIOS = _c[0], setPromotedProductsIOS = _c[1];
55
- var _d = useState([]), subscriptions = _d[0], setSubscriptions = _d[1];
56
- var _e = useState([]), purchaseHistories = _e[0], setPurchaseHistories = _e[1];
57
- var _f = useState([]), availablePurchases = _f[0], setAvailablePurchases = _f[1];
58
- var _g = useState(), currentPurchase = _g[0], setCurrentPurchase = _g[1];
59
- var _h = useState(), currentPurchaseError = _h[0], setCurrentPurchaseError = _h[1];
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;
60
43
  var getProducts = useCallback(function (skus) { return __awaiter(_this, void 0, void 0, function () {
61
- var iaps;
62
- return __generator(this, function (_a) {
63
- switch (_a.label) {
64
- case 0: return [4 /*yield*/, iapGetProducts(skus)];
44
+ var _a;
45
+ return __generator(this, function (_b) {
46
+ switch (_b.label) {
47
+ case 0:
48
+ _a = setProducts;
49
+ return [4 /*yield*/, iapGetProducts(skus)];
65
50
  case 1:
66
- iaps = _a.sent();
67
- setProducts(iaps);
51
+ _a.apply(void 0, [_b.sent()]);
68
52
  return [2 /*return*/];
69
53
  }
70
54
  });
71
- }); }, []);
55
+ }); }, [setProducts]);
72
56
  var getSubscriptions = useCallback(function (skus) { return __awaiter(_this, void 0, void 0, function () {
73
- var subs;
74
- return __generator(this, function (_a) {
75
- switch (_a.label) {
76
- case 0: return [4 /*yield*/, iapGetSubscriptions(skus)];
57
+ var _a;
58
+ return __generator(this, function (_b) {
59
+ switch (_b.label) {
60
+ case 0:
61
+ _a = setSubscriptions;
62
+ return [4 /*yield*/, iapGetSubscriptions(skus)];
77
63
  case 1:
78
- subs = _a.sent();
79
- setSubscriptions(subs);
64
+ _a.apply(void 0, [_b.sent()]);
80
65
  return [2 /*return*/];
81
66
  }
82
67
  });
83
- }); }, []);
68
+ }); }, [setSubscriptions]);
84
69
  var getAvailablePurchases = useCallback(function () { return __awaiter(_this, void 0, void 0, function () {
85
70
  var _a;
86
71
  return __generator(this, function (_b) {
@@ -93,7 +78,7 @@ export function useIAP() {
93
78
  return [2 /*return*/];
94
79
  }
95
80
  });
96
- }); }, []);
81
+ }); }, [setAvailablePurchases]);
97
82
  var getPurchaseHistories = useCallback(function () { return __awaiter(_this, void 0, void 0, function () {
98
83
  var _a;
99
84
  return __generator(this, function (_b) {
@@ -106,7 +91,7 @@ export function useIAP() {
106
91
  return [2 /*return*/];
107
92
  }
108
93
  });
109
- }); }, []);
94
+ }); }, [setPurchaseHistories]);
110
95
  var finishTransaction = useCallback(function (purchase, isConsumable, developerPayloadAndroid) { return __awaiter(_this, void 0, void 0, function () {
111
96
  var err_1;
112
97
  return __generator(this, function (_a) {
@@ -117,7 +102,7 @@ export function useIAP() {
117
102
  case 1: return [2 /*return*/, _a.sent()];
118
103
  case 2:
119
104
  err_1 = _a.sent();
120
- throw new Error(err_1);
105
+ throw err_1;
121
106
  case 3:
122
107
  if (purchase.productId === (currentPurchase === null || currentPurchase === void 0 ? void 0 : currentPurchase.productId))
123
108
  setCurrentPurchase(undefined);
@@ -127,58 +112,12 @@ export function useIAP() {
127
112
  case 4: return [2 /*return*/];
128
113
  }
129
114
  });
130
- }); }, [currentPurchase === null || currentPurchase === void 0 ? void 0 : currentPurchase.productId, currentPurchaseError === null || currentPurchaseError === void 0 ? void 0 : currentPurchaseError.productId]);
131
- var initIapWithSubscriptions = useCallback(function () { return __awaiter(_this, void 0, void 0, function () {
132
- var result;
133
- var _this = this;
134
- return __generator(this, function (_a) {
135
- switch (_a.label) {
136
- case 0: return [4 /*yield*/, initConnection()];
137
- case 1:
138
- result = _a.sent();
139
- setConnected(result);
140
- if (result) {
141
- purchaseUpdateSubscription = purchaseUpdatedListener(function (purchase) { return __awaiter(_this, void 0, void 0, function () {
142
- return __generator(this, function (_a) {
143
- setCurrentPurchaseError(undefined);
144
- setCurrentPurchase(purchase);
145
- return [2 /*return*/];
146
- });
147
- }); });
148
- purchaseErrorSubscription = purchaseErrorListener(function (error) {
149
- setCurrentPurchase(undefined);
150
- setCurrentPurchaseError(error);
151
- });
152
- promotedProductsSubscription = IAPEmitter.addListener('iap-promoted-product', function () { return __awaiter(_this, void 0, void 0, function () {
153
- var product;
154
- return __generator(this, function (_a) {
155
- switch (_a.label) {
156
- case 0: return [4 /*yield*/, getPromotedProductIOS()];
157
- case 1:
158
- product = _a.sent();
159
- setPromotedProductsIOS(function (prevProducts) { return __spreadArray(__spreadArray([], prevProducts), (product ? [product] : [])); });
160
- return [2 /*return*/];
161
- }
162
- });
163
- }); });
164
- }
165
- return [2 /*return*/];
166
- }
167
- });
168
- }); }, []);
169
- useEffect(function () {
170
- initIapWithSubscriptions();
171
- return function () {
172
- if (purchaseUpdateSubscription)
173
- purchaseUpdateSubscription.remove();
174
- if (purchaseErrorSubscription)
175
- purchaseErrorSubscription.remove();
176
- if (promotedProductsSubscription)
177
- promotedProductsSubscription.remove();
178
- endConnection();
179
- setConnected(false);
180
- };
181
- }, [initIapWithSubscriptions]);
115
+ }); }, [
116
+ currentPurchase === null || currentPurchase === void 0 ? void 0 : currentPurchase.productId,
117
+ currentPurchaseError === null || currentPurchaseError === void 0 ? void 0 : currentPurchaseError.productId,
118
+ setCurrentPurchase,
119
+ setCurrentPurchaseError,
120
+ ]);
182
121
  return {
183
122
  connected: connected,
184
123
  products: products,
@@ -193,5 +132,7 @@ export function useIAP() {
193
132
  getSubscriptions: getSubscriptions,
194
133
  getAvailablePurchases: getAvailablePurchases,
195
134
  getPurchaseHistories: getPurchaseHistories,
135
+ requestPurchase: iapRequestPurchase,
136
+ requesSubscription: iapRequestSubscription,
196
137
  };
197
138
  }
@@ -0,0 +1,21 @@
1
+ import React from 'react';
2
+ import { Product, Purchase, PurchaseError, Subscription } from '../types';
3
+ declare type IAPContextType = {
4
+ connected: boolean;
5
+ products: Product[];
6
+ promotedProductsIOS: Product[];
7
+ subscriptions: Subscription[];
8
+ purchaseHistories: Purchase[];
9
+ availablePurchases: Purchase[];
10
+ currentPurchase?: Purchase;
11
+ currentPurchaseError?: PurchaseError;
12
+ setProducts: (products: Product[]) => void;
13
+ setSubscriptions: (subscriptions: Subscription[]) => void;
14
+ setPurchaseHistories: (purchaseHistories: Purchase[]) => void;
15
+ setAvailablePurchases: (availablePurchases: Purchase[]) => void;
16
+ setCurrentPurchase: (currentPurchase: Purchase | undefined) => void;
17
+ setCurrentPurchaseError: (currentPurchaseError: PurchaseError | undefined) => void;
18
+ };
19
+ export declare function useIAPContext(): IAPContextType;
20
+ export declare function withIAPContext<T>(Component: React.ComponentType<T>): (props: T) => JSX.Element;
21
+ export {};
@@ -0,0 +1,140 @@
1
+ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
2
+ function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
3
+ return new (P || (P = Promise))(function (resolve, reject) {
4
+ function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
5
+ function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
6
+ function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
7
+ step((generator = generator.apply(thisArg, _arguments || [])).next());
8
+ });
9
+ };
10
+ var __generator = (this && this.__generator) || function (thisArg, body) {
11
+ var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g;
12
+ return g = { next: verb(0), "throw": verb(1), "return": verb(2) }, typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g;
13
+ function verb(n) { return function (v) { return step([n, v]); }; }
14
+ function step(op) {
15
+ if (f) throw new TypeError("Generator is already executing.");
16
+ while (_) try {
17
+ if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t;
18
+ if (y = 0, t) op = [op[0] & 2, t.value];
19
+ switch (op[0]) {
20
+ case 0: case 1: t = op; break;
21
+ case 4: _.label++; return { value: op[1], done: false };
22
+ case 5: _.label++; y = op[1]; op = [0]; continue;
23
+ case 7: op = _.ops.pop(); _.trys.pop(); continue;
24
+ default:
25
+ if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; }
26
+ if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; }
27
+ if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; }
28
+ if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; }
29
+ if (t[2]) _.ops.pop();
30
+ _.trys.pop(); continue;
31
+ }
32
+ op = body.call(thisArg, _);
33
+ } catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; }
34
+ if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true };
35
+ }
36
+ };
37
+ var __spreadArray = (this && this.__spreadArray) || function (to, from, pack) {
38
+ if (pack || arguments.length === 2) for (var i = 0, l = from.length, ar; i < l; i++) {
39
+ if (ar || !(i in from)) {
40
+ if (!ar) ar = Array.prototype.slice.call(from, 0, i);
41
+ ar[i] = from[i];
42
+ }
43
+ }
44
+ return to.concat(ar || Array.prototype.slice.call(from));
45
+ };
46
+ import React, { useContext, useEffect, useMemo, useState } from 'react';
47
+ import { NativeEventEmitter, NativeModules } from 'react-native';
48
+ import { getPromotedProductIOS, initConnection, purchaseErrorListener, purchaseUpdatedListener, } from '../iap';
49
+ var RNIapIos = NativeModules.RNIapIos;
50
+ var IAPEmitter = new NativeEventEmitter(RNIapIos);
51
+ // @ts-ignore
52
+ var IAPContext = React.createContext(null);
53
+ export function useIAPContext() {
54
+ var ctx = useContext(IAPContext);
55
+ if (!ctx)
56
+ throw new Error('You need wrap your app with withIAPContext HOC');
57
+ return ctx;
58
+ }
59
+ export function withIAPContext(Component) {
60
+ return function WrapperComponent(props) {
61
+ var _this = this;
62
+ var _a = useState(false), connected = _a[0], setConnected = _a[1];
63
+ var _b = useState([]), products = _b[0], setProducts = _b[1];
64
+ var _c = useState([]), promotedProductsIOS = _c[0], setPromotedProductsIOS = _c[1];
65
+ var _d = useState([]), subscriptions = _d[0], setSubscriptions = _d[1];
66
+ var _e = useState([]), purchaseHistories = _e[0], setPurchaseHistories = _e[1];
67
+ var _f = useState([]), availablePurchases = _f[0], setAvailablePurchases = _f[1];
68
+ var _g = useState(), currentPurchase = _g[0], setCurrentPurchase = _g[1];
69
+ var _h = useState(), currentPurchaseError = _h[0], setCurrentPurchaseError = _h[1];
70
+ var context = useMemo(function () { return ({
71
+ connected: connected,
72
+ products: products,
73
+ subscriptions: subscriptions,
74
+ promotedProductsIOS: promotedProductsIOS,
75
+ purchaseHistories: purchaseHistories,
76
+ availablePurchases: availablePurchases,
77
+ currentPurchase: currentPurchase,
78
+ currentPurchaseError: currentPurchaseError,
79
+ setProducts: setProducts,
80
+ setSubscriptions: setSubscriptions,
81
+ setPurchaseHistories: setPurchaseHistories,
82
+ setAvailablePurchases: setAvailablePurchases,
83
+ setCurrentPurchase: setCurrentPurchase,
84
+ setCurrentPurchaseError: setCurrentPurchaseError,
85
+ }); }, [
86
+ connected,
87
+ products,
88
+ subscriptions,
89
+ promotedProductsIOS,
90
+ purchaseHistories,
91
+ availablePurchases,
92
+ currentPurchase,
93
+ currentPurchaseError,
94
+ setProducts,
95
+ setSubscriptions,
96
+ setPurchaseHistories,
97
+ setAvailablePurchases,
98
+ setCurrentPurchase,
99
+ setCurrentPurchaseError,
100
+ ]);
101
+ useEffect(function () {
102
+ initConnection().then(setConnected);
103
+ }, []);
104
+ useEffect(function () {
105
+ if (!connected)
106
+ return;
107
+ var purchaseUpdateSubscription = purchaseUpdatedListener(function (purchase) { return __awaiter(_this, void 0, void 0, function () {
108
+ return __generator(this, function (_a) {
109
+ setCurrentPurchaseError(undefined);
110
+ setCurrentPurchase(purchase);
111
+ return [2 /*return*/];
112
+ });
113
+ }); });
114
+ var purchaseErrorSubscription = purchaseErrorListener(function (error) {
115
+ setCurrentPurchase(undefined);
116
+ setCurrentPurchaseError(error);
117
+ });
118
+ var promotedProductsSubscription = IAPEmitter.addListener('iap-promoted-product', function () { return __awaiter(_this, void 0, void 0, function () {
119
+ var product;
120
+ return __generator(this, function (_a) {
121
+ switch (_a.label) {
122
+ case 0: return [4 /*yield*/, getPromotedProductIOS()];
123
+ case 1:
124
+ product = _a.sent();
125
+ setPromotedProductsIOS(function (prevProducts) { return __spreadArray(__spreadArray([], prevProducts, true), (product ? [product] : []), true); });
126
+ return [2 /*return*/];
127
+ }
128
+ });
129
+ }); });
130
+ return function () {
131
+ purchaseUpdateSubscription.remove();
132
+ purchaseErrorSubscription.remove();
133
+ promotedProductsSubscription.remove();
134
+ };
135
+ }, [connected]);
136
+ return (<IAPContext.Provider value={context}>
137
+ <Component {...props}/>
138
+ </IAPContext.Provider>);
139
+ };
140
+ }
@@ -0,0 +1,150 @@
1
+ import React, {useContext, useEffect, useMemo, useState} from 'react';
2
+ import {NativeEventEmitter, NativeModules} from 'react-native';
3
+ import {
4
+ InAppPurchase,
5
+ Product,
6
+ Purchase,
7
+ PurchaseError,
8
+ Subscription,
9
+ SubscriptionPurchase,
10
+ } from '../types';
11
+ import {
12
+ getPromotedProductIOS,
13
+ initConnection,
14
+ purchaseErrorListener,
15
+ purchaseUpdatedListener,
16
+ } from '../iap';
17
+
18
+ type IAPContextType = {
19
+ connected: boolean;
20
+ products: Product[];
21
+ promotedProductsIOS: Product[];
22
+ subscriptions: Subscription[];
23
+ purchaseHistories: Purchase[];
24
+ availablePurchases: Purchase[];
25
+ currentPurchase?: Purchase;
26
+ currentPurchaseError?: PurchaseError;
27
+ setProducts: (products: Product[]) => void;
28
+ setSubscriptions: (subscriptions: Subscription[]) => void;
29
+ setPurchaseHistories: (purchaseHistories: Purchase[]) => void;
30
+ setAvailablePurchases: (availablePurchases: Purchase[]) => void;
31
+ setCurrentPurchase: (currentPurchase: Purchase | undefined) => void;
32
+ setCurrentPurchaseError: (
33
+ currentPurchaseError: PurchaseError | undefined,
34
+ ) => void;
35
+ };
36
+
37
+ const {RNIapIos} = NativeModules;
38
+ const IAPEmitter = new NativeEventEmitter(RNIapIos);
39
+
40
+ // @ts-ignore
41
+ const IAPContext = React.createContext<IAPContextType>(null);
42
+
43
+ export function useIAPContext(): IAPContextType {
44
+ const ctx = useContext(IAPContext);
45
+ if (!ctx) throw new Error('You need wrap your app with withIAPContext HOC');
46
+
47
+ return ctx;
48
+ }
49
+
50
+ export function withIAPContext<T>(Component: React.ComponentType<T>) {
51
+ return function WrapperComponent(props: T) {
52
+ const [connected, setConnected] = useState<boolean>(false);
53
+ const [products, setProducts] = useState<Product[]>([]);
54
+
55
+ const [promotedProductsIOS, setPromotedProductsIOS] = useState<Product[]>(
56
+ [],
57
+ );
58
+ const [subscriptions, setSubscriptions] = useState<Subscription[]>([]);
59
+ const [purchaseHistories, setPurchaseHistories] = useState<Purchase[]>([]);
60
+
61
+ const [availablePurchases, setAvailablePurchases] = useState<Purchase[]>(
62
+ [],
63
+ );
64
+ const [currentPurchase, setCurrentPurchase] = useState<Purchase>();
65
+
66
+ const [currentPurchaseError, setCurrentPurchaseError] =
67
+ useState<PurchaseError>();
68
+
69
+ const context = useMemo(
70
+ () => ({
71
+ connected,
72
+ products,
73
+ subscriptions,
74
+ promotedProductsIOS,
75
+ purchaseHistories,
76
+ availablePurchases,
77
+ currentPurchase,
78
+ currentPurchaseError,
79
+ setProducts,
80
+ setSubscriptions,
81
+ setPurchaseHistories,
82
+ setAvailablePurchases,
83
+ setCurrentPurchase,
84
+ setCurrentPurchaseError,
85
+ }),
86
+ [
87
+ connected,
88
+ products,
89
+ subscriptions,
90
+ promotedProductsIOS,
91
+ purchaseHistories,
92
+ availablePurchases,
93
+ currentPurchase,
94
+ currentPurchaseError,
95
+ setProducts,
96
+ setSubscriptions,
97
+ setPurchaseHistories,
98
+ setAvailablePurchases,
99
+ setCurrentPurchase,
100
+ setCurrentPurchaseError,
101
+ ],
102
+ );
103
+
104
+ useEffect(() => {
105
+ initConnection().then(setConnected);
106
+ }, []);
107
+
108
+ useEffect(() => {
109
+ if (!connected) return;
110
+
111
+ const purchaseUpdateSubscription = purchaseUpdatedListener(
112
+ async (purchase: InAppPurchase | SubscriptionPurchase) => {
113
+ setCurrentPurchaseError(undefined);
114
+ setCurrentPurchase(purchase);
115
+ },
116
+ );
117
+
118
+ const purchaseErrorSubscription = purchaseErrorListener(
119
+ (error: PurchaseError) => {
120
+ setCurrentPurchase(undefined);
121
+ setCurrentPurchaseError(error);
122
+ },
123
+ );
124
+
125
+ const promotedProductsSubscription = IAPEmitter.addListener(
126
+ 'iap-promoted-product',
127
+ async () => {
128
+ const product = await getPromotedProductIOS();
129
+
130
+ setPromotedProductsIOS((prevProducts) => [
131
+ ...prevProducts,
132
+ ...(product ? [product] : []),
133
+ ]);
134
+ },
135
+ );
136
+
137
+ return () => {
138
+ purchaseUpdateSubscription.remove();
139
+ purchaseErrorSubscription.remove();
140
+ promotedProductsSubscription.remove();
141
+ };
142
+ }, [connected]);
143
+
144
+ return (
145
+ <IAPContext.Provider value={context}>
146
+ <Component {...props} />
147
+ </IAPContext.Provider>
148
+ );
149
+ };
150
+ }
package/src/iap.d.ts CHANGED
@@ -24,7 +24,7 @@ export declare const flushFailedPurchasesCachedAsPendingAndroid: () => Promise<s
24
24
  * @param {string[]} skus The item skus
25
25
  * @returns {Promise<Product[]>}
26
26
  */
27
- export declare const getProducts: <SkuType extends string>(skus: SkuType[]) => Promise<Product<SkuType>[]>;
27
+ export declare const getProducts: (skus: string[]) => Promise<Array<Product>>;
28
28
  /**
29
29
  * Get a list of subscriptions
30
30
  * @param {string[]} skus The item skus
@@ -49,7 +49,7 @@ export declare const getAvailablePurchases: () => Promise<(InAppPurchase | Subsc
49
49
  * @param {string} [obfuscatedProfileIdAndroid] Specifies an optional obfuscated string that is uniquely associated with the user's profile in your app.
50
50
  * @returns {Promise<InAppPurchase>}
51
51
  */
52
- export declare const requestPurchase: (sku: string, andDangerouslyFinishTransactionAutomaticallyIOS?: boolean | undefined, obfuscatedAccountIdAndroid?: string | undefined, obfuscatedProfileIdAndroid?: string | undefined) => Promise<InAppPurchase>;
52
+ export declare const requestPurchase: (sku: string, andDangerouslyFinishTransactionAutomaticallyIOS?: boolean, obfuscatedAccountIdAndroid?: string | undefined, obfuscatedProfileIdAndroid?: string | undefined) => Promise<InAppPurchase>;
53
53
  /**
54
54
  * Request a purchase for product. This will be received in `PurchaseUpdatedListener`.
55
55
  * @param {string} [sku] The product's sku/ID
@@ -60,7 +60,7 @@ export declare const requestPurchase: (sku: string, andDangerouslyFinishTransact
60
60
  * @param {string} [obfuscatedProfileIdAndroid] Specifies an optional obfuscated string that is uniquely associated with the user's profile in your app.
61
61
  * @returns {Promise<SubscriptionPurchase | null>} Promise resolves to null when using proratioModesAndroid=DEFERRED, and to a SubscriptionPurchase otherwise
62
62
  */
63
- export declare const requestSubscription: (sku: string, andDangerouslyFinishTransactionAutomaticallyIOS?: boolean | undefined, purchaseTokenAndroid?: string | undefined, prorationModeAndroid?: ProrationModesAndroid | undefined, obfuscatedAccountIdAndroid?: string | undefined, obfuscatedProfileIdAndroid?: string | undefined) => Promise<SubscriptionPurchase | null>;
63
+ export declare const requestSubscription: (sku: string, andDangerouslyFinishTransactionAutomaticallyIOS?: boolean, purchaseTokenAndroid?: string | undefined, prorationModeAndroid?: ProrationModesAndroid, obfuscatedAccountIdAndroid?: string | undefined, obfuscatedProfileIdAndroid?: string | undefined) => Promise<SubscriptionPurchase | null>;
64
64
  /**
65
65
  * Request a purchase for product. This will be received in `PurchaseUpdatedListener`.
66
66
  * @param {string} sku The product's sku/ID
@@ -165,12 +165,12 @@ export declare const validateReceiptAndroid: (packageName: string, productId: st
165
165
  */
166
166
  export declare const validateReceiptAmazon: (developerSecret: string, userId: string, receiptId: string, useSandbox?: boolean) => Promise<Amazon.ReceiptType>;
167
167
  /**
168
- * Add IAP purchase event in ios.
168
+ * Add IAP purchase event
169
169
  * @returns {callback(e: InAppPurchase | ProductPurchase)}
170
170
  */
171
171
  export declare const purchaseUpdatedListener: (listener: (event: InAppPurchase | SubscriptionPurchase) => void) => EmitterSubscription;
172
172
  /**
173
- * Add IAP purchase error event in ios.
173
+ * Add IAP purchase error event
174
174
  * @returns {callback(e: PurchaseError)}
175
175
  */
176
176
  export declare const purchaseErrorListener: (listener: (errorEvent: PurchaseError) => void) => EmitterSubscription;
package/src/iap.js CHANGED
@@ -132,14 +132,14 @@ var fillProductsAdditionalData = function (products) { return __awaiter(void 0,
132
132
  export var getProducts = function (skus) {
133
133
  return (Platform.select({
134
134
  ios: function () { return __awaiter(void 0, void 0, void 0, function () {
135
+ var items;
135
136
  return __generator(this, function (_a) {
136
- return [2 /*return*/, getIosModule()
137
- .getItems(skus)
138
- .then(function (items) {
139
- return items.filter(function (item) {
140
- return skus.includes(item.productId);
141
- });
142
- })];
137
+ switch (_a.label) {
138
+ case 0: return [4 /*yield*/, getIosModule().getItems(skus)];
139
+ case 1:
140
+ items = _a.sent();
141
+ return [2 /*return*/, items.filter(function (item) { return skus.includes(item.productId); })];
142
+ }
143
143
  });
144
144
  }); },
145
145
  android: function () { return __awaiter(void 0, void 0, void 0, function () {
@@ -163,12 +163,16 @@ export var getProducts = function (skus) {
163
163
  export var getSubscriptions = function (skus) {
164
164
  return (Platform.select({
165
165
  ios: function () { return __awaiter(void 0, void 0, void 0, function () {
166
+ var items;
166
167
  return __generator(this, function (_a) {
167
- return [2 /*return*/, getIosModule()
168
- .getItems(skus)
169
- .then(function (items) {
170
- return items.filter(function (item) { return skus.includes(item.productId); });
171
- })];
168
+ switch (_a.label) {
169
+ case 0: return [4 /*yield*/, getIosModule().getItems(skus)];
170
+ case 1:
171
+ items = _a.sent();
172
+ return [2 /*return*/, items.filter(function (item) {
173
+ return skus.includes(item.productId);
174
+ })];
175
+ }
172
176
  });
173
177
  }); },
174
178
  android: function () { return __awaiter(void 0, void 0, void 0, function () {
@@ -247,13 +251,12 @@ export var getAvailablePurchases = function () {
247
251
  * @returns {Promise<InAppPurchase>}
248
252
  */
249
253
  export var requestPurchase = function (sku, andDangerouslyFinishTransactionAutomaticallyIOS, obfuscatedAccountIdAndroid, obfuscatedProfileIdAndroid) {
254
+ if (andDangerouslyFinishTransactionAutomaticallyIOS === void 0) { andDangerouslyFinishTransactionAutomaticallyIOS = false; }
255
+ if (obfuscatedAccountIdAndroid === void 0) { obfuscatedAccountIdAndroid = undefined; }
256
+ if (obfuscatedProfileIdAndroid === void 0) { obfuscatedProfileIdAndroid = undefined; }
250
257
  return (Platform.select({
251
258
  ios: function () { return __awaiter(void 0, void 0, void 0, function () {
252
259
  return __generator(this, function (_a) {
253
- andDangerouslyFinishTransactionAutomaticallyIOS =
254
- andDangerouslyFinishTransactionAutomaticallyIOS === undefined
255
- ? false
256
- : andDangerouslyFinishTransactionAutomaticallyIOS;
257
260
  if (andDangerouslyFinishTransactionAutomaticallyIOS)
258
261
  // eslint-disable-next-line no-console
259
262
  console.warn(
@@ -280,13 +283,14 @@ export var requestPurchase = function (sku, andDangerouslyFinishTransactionAutom
280
283
  * @returns {Promise<SubscriptionPurchase | null>} Promise resolves to null when using proratioModesAndroid=DEFERRED, and to a SubscriptionPurchase otherwise
281
284
  */
282
285
  export var requestSubscription = function (sku, andDangerouslyFinishTransactionAutomaticallyIOS, purchaseTokenAndroid, prorationModeAndroid, obfuscatedAccountIdAndroid, obfuscatedProfileIdAndroid) {
286
+ if (andDangerouslyFinishTransactionAutomaticallyIOS === void 0) { andDangerouslyFinishTransactionAutomaticallyIOS = false; }
287
+ if (purchaseTokenAndroid === void 0) { purchaseTokenAndroid = undefined; }
288
+ if (prorationModeAndroid === void 0) { prorationModeAndroid = -1; }
289
+ if (obfuscatedAccountIdAndroid === void 0) { obfuscatedAccountIdAndroid = undefined; }
290
+ if (obfuscatedProfileIdAndroid === void 0) { obfuscatedProfileIdAndroid = undefined; }
283
291
  return (Platform.select({
284
292
  ios: function () { return __awaiter(void 0, void 0, void 0, function () {
285
293
  return __generator(this, function (_a) {
286
- andDangerouslyFinishTransactionAutomaticallyIOS =
287
- andDangerouslyFinishTransactionAutomaticallyIOS === undefined
288
- ? false
289
- : andDangerouslyFinishTransactionAutomaticallyIOS;
290
294
  if (andDangerouslyFinishTransactionAutomaticallyIOS)
291
295
  // eslint-disable-next-line no-console
292
296
  console.warn(
@@ -297,8 +301,6 @@ export var requestSubscription = function (sku, andDangerouslyFinishTransactionA
297
301
  }); },
298
302
  android: function () { return __awaiter(void 0, void 0, void 0, function () {
299
303
  return __generator(this, function (_a) {
300
- if (!prorationModeAndroid)
301
- prorationModeAndroid = -1;
302
304
  return [2 /*return*/, getAndroidModule().buyItemByType(ANDROID_ITEM_TYPE_SUBSCRIPTION, sku, purchaseTokenAndroid, prorationModeAndroid, obfuscatedAccountIdAndroid, obfuscatedProfileIdAndroid)];
303
305
  });
304
306
  }); },
@@ -553,33 +555,22 @@ export var validateReceiptAmazon = function (developerSecret, userId, receiptId,
553
555
  });
554
556
  };
555
557
  /**
556
- * Add IAP purchase event in ios.
558
+ * Add IAP purchase event
557
559
  * @returns {callback(e: InAppPurchase | ProductPurchase)}
558
560
  */
559
561
  export var purchaseUpdatedListener = function (listener) {
560
- if (Platform.OS === 'ios') {
561
- var myModuleEvt = new NativeEventEmitter(getIosModule());
562
- return myModuleEvt.addListener('purchase-updated', listener);
563
- }
564
- else {
565
- var myRNIapModule = getAndroidModule();
566
- var myModuleEvt = new NativeEventEmitter(myRNIapModule);
567
- var emitterSubscription = myModuleEvt.addListener('purchase-updated', listener);
568
- myRNIapModule.startListening();
569
- return emitterSubscription;
570
- }
562
+ var myModuleEvt = new NativeEventEmitter(getNativeModule());
563
+ var emitterSubscription = myModuleEvt.addListener('purchase-updated', listener);
564
+ if (Platform.OS === 'android')
565
+ getAndroidModule().startListening();
566
+ return emitterSubscription;
571
567
  };
572
568
  /**
573
- * Add IAP purchase error event in ios.
569
+ * Add IAP purchase error event
574
570
  * @returns {callback(e: PurchaseError)}
575
571
  */
576
572
  export var purchaseErrorListener = function (listener) {
577
- if (Platform.OS === 'ios') {
578
- var myModuleEvt = new NativeEventEmitter(getIosModule());
579
- return myModuleEvt.addListener('purchase-error', listener);
580
- }
581
- else
582
- return new NativeEventEmitter(getAndroidModule()).addListener('purchase-error', listener);
573
+ return new NativeEventEmitter(getNativeModule()).addListener('purchase-error', listener);
583
574
  };
584
575
  /**
585
576
  * Get the current receipt base64 encoded in IOS.
package/src/index.d.ts CHANGED
@@ -1,3 +1,4 @@
1
1
  export * from './types';
2
2
  export * from './hooks/useIAP';
3
+ export * from './hooks/withIAPContext';
3
4
  export * from './iap';
package/src/index.js CHANGED
@@ -1,3 +1,4 @@
1
1
  export * from './types';
2
2
  export * from './hooks/useIAP';
3
+ export * from './hooks/withIAPContext';
3
4
  export * from './iap';
@@ -48,12 +48,13 @@ export interface ProductPurchase {
48
48
  transactionDate: number;
49
49
  transactionReceipt: string;
50
50
  purchaseToken?: string;
51
+ quantityIOS?: number;
52
+ originalTransactionDateIOS?: string;
53
+ originalTransactionIdentifierIOS?: string;
51
54
  dataAndroid?: string;
52
55
  signatureAndroid?: string;
53
56
  autoRenewingAndroid?: boolean;
54
57
  purchaseStateAndroid?: PurchaseStateAndroid;
55
- originalTransactionDateIOS?: string;
56
- originalTransactionIdentifierIOS?: string;
57
58
  isAcknowledgedAndroid?: boolean;
58
59
  packageNameAndroid?: string;
59
60
  developerPayloadAndroid?: string;
@@ -62,6 +63,7 @@ export interface ProductPurchase {
62
63
  userIdAmazon?: string;
63
64
  userMarketplaceAmazon?: string;
64
65
  userJsonAmazon?: string;
66
+ isCanceledAmazon?: boolean;
65
67
  }
66
68
  export interface PurchaseResult {
67
69
  responseCode?: number;
@@ -92,9 +94,9 @@ export interface Discount {
92
94
  paymentMode: '' | 'FREETRIAL' | 'PAYASYOUGO' | 'PAYUPFRONT';
93
95
  subscriptionPeriod: string;
94
96
  }
95
- export interface Product<ProductId extends string = string> extends ProductCommon {
97
+ export interface Product extends ProductCommon {
96
98
  type: 'inapp' | 'iap';
97
- productId: ProductId;
99
+ productId: string;
98
100
  }
99
101
  export interface Subscription extends ProductCommon {
100
102
  type: 'subs' | 'sub';