react-native-iap 7.5.0 → 7.5.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/CHANGELOG.md CHANGED
@@ -1,11 +1,20 @@
1
1
  ## Changelogs
2
2
 
3
+ # 7.5.1
4
+
5
+ - Refresh SkuDetails (#1566)
6
+ - fix: NativeEventEmitter warnings since ReactNative 0.65 (#1544)
7
+ - Using TCK Tested JDK builds of OpenJDK (#1525)
8
+ - Add missing types for finishTransaction within useIAP() (#1533)
9
+
3
10
  # 7.5.0
4
11
 
5
12
  ### Bugfix
13
+
6
14
  - Fix canceled purchase dangling [#1504](https://github.com/dooboolab/react-native-iap/pull/1504)
7
15
 
8
16
  ### Dependencies
17
+
9
18
  - Set default `androidX` version [#1505](https://github.com/dooboolab/react-native-iap/pull/1505)
10
19
  - Update packages [#1506](https://github.com/dooboolab/react-native-iap/pull/1506)
11
20
 
package/README.md CHANGED
@@ -1,6 +1,7 @@
1
- ![image](https://user-images.githubusercontent.com/27461460/75094417-20321b00-55ce-11ea-8de7-a1df42a4b7df.png)
2
- ================
1
+ # ![image](https://user-images.githubusercontent.com/27461460/75094417-20321b00-55ce-11ea-8de7-a1df42a4b7df.png)
2
+
3
3
  [![Version](http://img.shields.io/npm/v/react-native-iap.svg?style=flat-square)](https://npmjs.org/package/react-native-iap)
4
+ [![Next](https://img.shields.io/npm/v/react-native-iap/next.svg?style=flat-square)](https://npmjs.org/package/react-native-iap)
4
5
  [![Download](http://img.shields.io/npm/dm/react-native-iap.svg?style=flat-square)](https://npmjs.org/package/react-native-iap)
5
6
  [![Build Status](https://travis-ci.com/dooboolab/react-native-iap.svg?branch=master)](https://travis-ci.com/dooboolab/react-native-iap)
6
7
  [![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)
@@ -20,10 +21,17 @@ Published in [website](https://react-native-iap.dooboolab.com).
20
21
 
21
22
  ## Announcement
22
23
 
23
- React Native IAP hook is out. You can see [medium post](https://medium.com/dooboolab/announcing-react-native-iap-hooks-96c7ffd3f19a) on how to use it.
24
+ - Version `8.0.0` is currently in release candidate. The module is completely rewritten with `Kotlin` and `Swift` for maintenenance issue by [andresesfm](https://github.com/andresesfm) 🔆. You may install this for early preview.
25
+
26
+ ```
27
+ yarn add react-native-iap@next
28
+ ```
29
+
30
+ - React Native IAP hook is out. You can see [medium post](https://medium.com/dooboolab/announcing-react-native-iap-hooks-96c7ffd3f19a) on how to use it.
31
+
32
+ - The `react-native-iap` module hasn't been maintained well recently. We are thinking of participating again and make the module healthier. Please refer to [2021 Maintenance plan](https://github.com/dooboolab/react-native-iap/issues/1241) and share with us how you or your organization is using it. Happy new year 🎉
24
33
 
25
- The `react-native-iap` module hasn't been maintained well recently. We are thinking of participating again and make the module healthier. Please refer to [2021 Maintenance plan](https://github.com/dooboolab/react-native-iap/issues/1241) and share with us how you or your organization is using it. Happy new year 🎉
26
- - The sample code is out in [Sponsor page](https://github.com/hyochan/dooboolab.com/blob/master/src/components/pages/Sponsor.tsx) in [dooboolab.com](https://github.com/hyochan/dooboolab.com) repository which sadly is rejected by Apple because of lacking product features. I will work on another example project to support this module. More information in [#1241 commment](https://github.com/dooboolab/react-native-iap/issues/1241#issuecomment-798540785).
34
+ - The sample code is out in [Sponsor page](https://github.com/hyochan/dooboolab.com/blob/master/src/components/pages/Sponsor.tsx) in [dooboolab.com](https://github.com/hyochan/dooboolab.com) repository which sadly is rejected by Apple because of lacking product features. I will work on another example project to support this module. More information in [#1241 commment](https://github.com/dooboolab/react-native-iap/issues/1241#issuecomment-798540785).
27
35
 
28
36
  ## Introduction
29
37
 
@@ -35,26 +43,28 @@ Also, implementing the client side is only one side of the coin, you'll have to
35
43
  If you're looking for a module going further than react-native-iap, we recommend using [react-native-iaphub](https://github.com/iaphub/react-native-iaphub) which is taking care of everything from the client side to the server side.
36
44
 
37
45
  ⚠️ Most of users experiencing issues are caused by:
38
- - A device simulator, use a real device for testing!
39
- - The sandbox environment of the project not being configured properly ([Configure android sandbox](https://www.iaphub.com/docs/set-up-android/configure-sandbox-testing), [Configure ios sandbox](https://www.iaphub.com/docs/set-up-ios/configure-sandbox-testing/))
40
- - An incorrect usage of the library
41
46
 
47
+ - A device simulator, use a real device for testing!
48
+ - The sandbox environment of the project not being configured properly ([Configure android sandbox](https://www.iaphub.com/docs/set-up-android/configure-sandbox-testing), [Configure ios sandbox](https://www.iaphub.com/docs/set-up-ios/configure-sandbox-testing/))
49
+ - An incorrect usage of the library
50
+
51
+ ## Demo
42
52
 
43
- Demo
44
- ----------
45
- >
46
53
  > ![demo.gif](https://user-images.githubusercontent.com/27461460/52619625-87aa8a80-2ee5-11e9-9aee-6691c34408f3.gif)
47
54
 
48
55
  <!-- Inline anchors -->
56
+
49
57
  [a-acknowledge-purchase-android]: #finishing-a-purchase
50
58
  [a-migration-guide]: #migration-guide
51
59
  [a-purchase-flow]: #new-purchase-flow
52
60
 
53
61
  <!-- Official Blog -->
62
+
54
63
  [blog-config-steps]: https://medium.com/p/121622d26b67
55
64
  [blog-v3-note]: https://medium.com/p/1259e0b0c017
56
65
 
57
66
  <!-- Internals -->
67
+
58
68
  [contribute]: https://github.com/dooboolab/react-native-iap/blob/master/CONTRIBUTING.md
59
69
  [example]: https://github.com/dooboolab/react-native-iap/tree/master/IapExample
60
70
  [issue-126-c1]: https://github.com/dooboolab/react-native-iap/issues/126#issuecomment-439084872
@@ -72,8 +82,9 @@ Demo
72
82
  [readme-deprecated]: https://github.com/dooboolab/react-native-iap/blob/master/README_DEPRECATED.md
73
83
 
74
84
  <!-- Externals -->
75
- [android-acknowledge-purchase]: https://developer.android.com/reference/com/android/billingclient/api/BillingClient.html#acknowledgePurchase(com.android.billingclient.api.AcknowledgePurchaseParams,%20com.android.billingclient.api.AcknowledgePurchaseResponseListener) "BillingClient#acknowledgePurchase()"
76
- [android-end-connection]: https://developer.android.com/reference/com/android/billingclient/api/BillingClient.html#endConnection() "BillingClient#endConnection()"
85
+
86
+ [android-acknowledge-purchase]: https://developer.android.com/reference/com/android/billingclient/api/BillingClient.html#acknowledgePurchase(com.android.billingclient.api.AcknowledgePurchaseParams,%20com.android.billingclient.api.AcknowledgePurchaseResponseListener) 'BillingClient#acknowledgePurchase()'
87
+ [android-end-connection]: https://developer.android.com/reference/com/android/billingclient/api/BillingClient.html#endConnection() 'BillingClient#endConnection()'
77
88
  [android-iap-validation-guide]: https://developer.android.com/google/play/billing/billing_library_overview
78
89
  [android-migrate-androidx]: https://developer.android.com/jetpack/androidx/migrate
79
90
  [android-sku-details]: https://developer.android.com/reference/com/android/billingclient/api/SkuDetails
@@ -85,80 +96,87 @@ Demo
85
96
  [stackoverflow-android-iap-validation]: https://stackoverflow.com/questions/35127086
86
97
  [android-access-token-example-repo]: https://github.com/Bang9/android-get-access-token-example
87
98
 
88
- Quick News
89
- ----------
99
+ ## Quick News
100
+
90
101
  - 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
102
  - `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
103
  - `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
104
  - 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.
105
+ Don't get surprised too much on why it is bumping up version so quickly these days.
95
106
  1. Migrated to new `AndroidX` APIs.
96
107
  2. Migrated to new `Android` billing client which is `> 2.0.0`.
97
108
  - [`acknowledgePurchase()`][android-acknowledge-purchase] has been added since `3.2.0` which is very important.
98
109
  3. New [Purchase Flow][a-purchase-flow]
99
110
  4. More is coming in `iOS 13`.
100
111
 
101
- Breaking Changes
102
- ----------------
112
+ ## Breaking Changes
103
113
 
104
114
  [7.4.0]
115
+
105
116
  - Now using React's Context to manage IAP state
106
117
  - Introduce `withIAPContext` HOC ([how to use](docs/docs/usage_instructions/using_hooks.md))
107
118
 
108
119
  [7.1.0]
120
+
109
121
  - `androidOldSku` is no longer required [#1438](https://github.com/dooboolab/react-native-iap/pull/1438).
110
122
 
111
123
  [6.1.0]
124
+
112
125
  - Creates two variants: `play` and `amazon` and only uses the required code.
113
126
  ```
114
127
  NOTE: This would be a breaking change with a very simple fix described in the documentation. To add: `missingDimensionStrategy 'store', 'play'` `in build.gradle`
115
128
  ```
116
- [3.0.0+]
117
- [react-native-iap V3 note][blog-v3-note]
129
+ [3.0.0+]
130
+ [react-native-iap V3 note][blog-v3-note]
131
+
132
+ ## Configuration of Google Play & iTunes Connect
118
133
 
119
- Configuration of Google Play & iTunes Connect
120
- ---------------------------------------------
121
134
  - Please refer to [Blog][blog-config-steps].
122
135
 
123
- [Deprecated README][readme-deprecated]
124
- --------------------------------------
136
+ ## [Deprecated README][readme-deprecated]
137
+
125
138
  - If you are using `react-native-iap@^2.*`, please follow the above README.
126
139
 
127
- Usage
128
- -----
140
+ ## Usage
141
+
129
142
  You can look in the [`RNIapExample/`][example] folder to try the example.
130
143
 
131
144
  NOTE: To run `RNIapExample` on Android use the variant flag as follows:
145
+
132
146
  ```
133
147
  yarn android --variant=MY_VARIANT
134
148
  ```
149
+
135
150
  where `MY_VARIANT` is `PlayDebug` or `AmazonDebug`
136
151
 
137
152
  Below is basic implementation which is also provided in `RNIapExample` project.
138
153
 
139
154
  If you want more advanced one please refer to [dooboolab.com/sponsor.tsx](https://github.com/hyochan/dooboolab.com/blob/master/src/components/pages/Sponsor.tsx)
140
155
 
141
- Sponsoring
142
- ----------
156
+ ## Sponsoring
143
157
 
144
158
  Since `IAP` itself is not perfect on each platform, we desperately need
145
159
  this project to be maintained. If you'd like to help us, please consider being
146
160
  with us in [Open Collective](https://opencollective.com/react-native-iap).
147
161
 
148
162
  ### Sponsors
163
+
149
164
  Support this project by becoming a sponsor. Your logo will show up here with
150
165
  a link to your website. [Become a sponsor][open-collective-sponsor].
151
166
  <a href="https://opencollective.com/react-native-iap#sponsors" target="_blank"><img src="https://opencollective.com/react-native-iap/sponsors.svg?width=890"></a>
152
167
 
153
168
  ### Backers
169
+
154
170
  Please be our [Backers][open-collective-backer].
155
171
  <a href="https://opencollective.com/react-native-iap#backers" target="_blank"><img src="https://opencollective.com/react-native-iap/backers.svg?width=890"></a>
156
172
 
157
173
  ### Contributing
174
+
158
175
  Please make sure to read the [Contributing Guide][contribute] before making a pull request.
159
176
  Thank you to all the people who helped to maintain and upgrade this project!
160
177
 
161
178
  <a href="graphs/contributors"><img src="https://opencollective.com/react-native-iap/contributors.svg?width=890" /></a>
179
+
162
180
  <hr>
163
181
 
164
182
  [![FOSSA Status](https://app.fossa.com/api/projects/git%2Bgithub.com%2Fdooboolab%2Freact-native-iap.svg?type=large)](https://app.fossa.com/projects/git%2Bgithub.com%2Fdooboolab%2Freact-native-iap?ref=badge_large)
@@ -117,4 +117,14 @@ public class RNIapAmazonModule extends ReactContextBaseJavaModule {
117
117
  public void startListening(final Promise promise) {
118
118
  sendUnconsumedPurchases(promise);
119
119
  }
120
+
121
+ @ReactMethod
122
+ public void addListener(String eventName) {
123
+ // Keep: Required for RN built in Event Emitter Calls.
124
+ }
125
+
126
+ @ReactMethod
127
+ public void removeListeners(double count) {
128
+ // Keep: Required for RN built in Event Emitter Calls.
129
+ }
120
130
  }
@@ -36,7 +36,9 @@ import com.google.android.gms.common.ConnectionResult;
36
36
  import com.google.android.gms.common.GoogleApiAvailability;
37
37
  import java.math.BigDecimal;
38
38
  import java.util.ArrayList;
39
+ import java.util.HashMap;
39
40
  import java.util.List;
41
+ import java.util.Map;
40
42
 
41
43
  public class RNIapModule extends ReactContextBaseJavaModule implements PurchasesUpdatedListener {
42
44
  final String TAG = "RNIapModule";
@@ -45,12 +47,12 @@ public class RNIapModule extends ReactContextBaseJavaModule implements Purchases
45
47
  private final ReactContext reactContext;
46
48
  private BillingClient billingClientCache;
47
49
 
48
- private final List<SkuDetails> skus;
50
+ private final Map<String, SkuDetails> skus;
49
51
 
50
52
  public RNIapModule(ReactApplicationContext reactContext) {
51
53
  super(reactContext);
52
54
  this.reactContext = reactContext;
53
- this.skus = new ArrayList<>();
55
+ this.skus = new HashMap<>();
54
56
  LifecycleEventListener lifecycleEventListener =
55
57
  new LifecycleEventListener() {
56
58
  @Override
@@ -245,9 +247,7 @@ public class RNIapModule extends ReactContextBaseJavaModule implements Purchases
245
247
 
246
248
  if (skuDetailsList != null) {
247
249
  for (SkuDetails sku : skuDetailsList) {
248
- if (!skus.contains(sku)) {
249
- skus.add(sku);
250
- }
250
+ skus.put(sku.getSku(), sku);
251
251
  }
252
252
  }
253
253
  WritableNativeArray items = new WritableNativeArray();
@@ -417,13 +417,7 @@ public class RNIapModule extends ReactContextBaseJavaModule implements Purchases
417
417
  DoobooUtils.getInstance().addPromiseForKey(PROMISE_BUY_ITEM, promise);
418
418
  final BillingFlowParams.Builder builder = BillingFlowParams.newBuilder();
419
419
 
420
- SkuDetails selectedSku = null;
421
- for (SkuDetails skuDetail : skus) {
422
- if (skuDetail.getSku().equals(sku)) {
423
- selectedSku = skuDetail;
424
- break;
425
- }
426
- }
420
+ SkuDetails selectedSku = skus.get(sku);
427
421
 
428
422
  if (selectedSku == null) {
429
423
  String debugMessage =
@@ -663,6 +657,16 @@ public class RNIapModule extends ReactContextBaseJavaModule implements Purchases
663
657
  sendUnconsumedPurchases(promise);
664
658
  }
665
659
 
660
+ @ReactMethod
661
+ public void addListener(String eventName) {
662
+ // Keep: Required for RN built in Event Emitter Calls.
663
+ }
664
+
665
+ @ReactMethod
666
+ public void removeListeners(double count) {
667
+ // Keep: Required for RN built in Event Emitter Calls.
668
+ }
669
+
666
670
  @ReactMethod
667
671
  public String getPackageName() {
668
672
  return getReactApplicationContext().getPackageName();
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "react-native-iap",
3
- "version": "7.5.0",
3
+ "version": "7.5.1",
4
4
  "description": "React Native In App Purchase Module.",
5
5
  "main": "index.js",
6
6
  "types": "index.d.ts",
@@ -9,13 +9,13 @@ declare type IAP_STATUS = {
9
9
  availablePurchases: Purchase[];
10
10
  currentPurchase?: Purchase;
11
11
  currentPurchaseError?: PurchaseError;
12
- finishTransaction: (purchase: Purchase) => Promise<string | void>;
12
+ finishTransaction: (purchase: Purchase, isConsumable?: boolean, developerPayloadAndroid?: string) => Promise<string | void>;
13
13
  getAvailablePurchases: () => Promise<void>;
14
14
  getPurchaseHistories: () => Promise<void>;
15
15
  getProducts: (skus: string[]) => Promise<void>;
16
16
  getSubscriptions: (skus: string[]) => Promise<void>;
17
17
  requestPurchase: typeof iapRequestPurchase;
18
- requesSubscription: typeof iapRequestSubscription;
18
+ requestSubscription: typeof iapRequestSubscription;
19
19
  };
20
20
  export declare function useIAP(): IAP_STATUS;
21
21
  export {};
@@ -133,6 +133,6 @@ export function useIAP() {
133
133
  getAvailablePurchases: getAvailablePurchases,
134
134
  getPurchaseHistories: getPurchaseHistories,
135
135
  requestPurchase: iapRequestPurchase,
136
- requesSubscription: iapRequestSubscription,
136
+ requestSubscription: iapRequestSubscription,
137
137
  };
138
138
  }
@@ -40,7 +40,7 @@ export interface ProductCommon {
40
40
  price: string;
41
41
  currency: string;
42
42
  localizedPrice: string;
43
- countryCodeIOS?: string;
43
+ countryCode?: string;
44
44
  }
45
45
  export interface ProductPurchase {
46
46
  productId: string;
@@ -1,150 +0,0 @@
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
- }