react-native-iap 7.3.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 +27 -0
- package/README.md +53 -31
- package/android/build.gradle +1 -1
- package/android/src/amazon/java/com/dooboolab/RNIap/RNIapAmazonModule.java +10 -0
- package/android/src/play/java/com/dooboolab/RNIap/RNIapModule.java +17 -15
- package/ios/RNIap.xcodeproj/project.pbxproj +2 -2
- package/ios/RNIapIos.m +5 -5
- package/ios/RNIapIos.swift +11 -0
- package/package.json +17 -17
- package/src/hooks/useIAP.d.ts +4 -1
- package/src/hooks/useIAP.js +31 -90
- package/src/hooks/withIAPContext.d.ts +21 -0
- package/src/hooks/withIAPContext.js +140 -0
- package/src/index.d.ts +1 -0
- package/src/index.js +1 -0
- package/src/types/index.d.ts +2 -1
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,32 @@
|
|
|
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
|
+
|
|
10
|
+
# 7.5.0
|
|
11
|
+
|
|
12
|
+
### Bugfix
|
|
13
|
+
|
|
14
|
+
- Fix canceled purchase dangling [#1504](https://github.com/dooboolab/react-native-iap/pull/1504)
|
|
15
|
+
|
|
16
|
+
### Dependencies
|
|
17
|
+
|
|
18
|
+
- Set default `androidX` version [#1505](https://github.com/dooboolab/react-native-iap/pull/1505)
|
|
19
|
+
- Update packages [#1506](https://github.com/dooboolab/react-native-iap/pull/1506)
|
|
20
|
+
|
|
21
|
+
# 7.4.1
|
|
22
|
+
|
|
23
|
+
- [iOS] Add `quantityIOS` in purchase data [#1476](https://github.com/dooboolab/react-native-iap/pull/1476)
|
|
24
|
+
|
|
25
|
+
# 7.4.0
|
|
26
|
+
|
|
27
|
+
- Now using React's Context to manage IAP state
|
|
28
|
+
- Introduce `withIAPContext` HOC ([how to use](docs/docs/usage_instructions/using_hooks.md))
|
|
29
|
+
|
|
3
30
|
# 7.3.0
|
|
4
31
|
|
|
5
32
|
_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)
|
package/README.md
CHANGED
|
@@ -1,12 +1,13 @@
|
|
|
1
|
-

|
|
2
|
-
|
|
1
|
+
# 
|
|
2
|
+
|
|
3
3
|
[](https://npmjs.org/package/react-native-iap)
|
|
4
|
+
[](https://npmjs.org/package/react-native-iap)
|
|
4
5
|
[](https://npmjs.org/package/react-native-iap)
|
|
5
6
|
[](https://travis-ci.com/dooboolab/react-native-iap)
|
|
6
7
|
[](https://github.com/dooboolab/react-native-iap/actions/workflows/ci.yml)
|
|
7
8
|
[](https://github.com/dooboolab/react-native-iap/actions/workflows/deploy-document.yml)
|
|
8
9
|
[](https://npmjs.org/package/react-native-iap)
|
|
9
|
-
[](https://github.com/dooboolab/react-native-iap)
|
|
10
11
|
[](https://opencollective.com/react-native-iap#backers)
|
|
11
12
|
[](https://github.com/dooboolab/react-native-iap/issues)
|
|
12
13
|
[](https://github.com/dooboolab/react-native-iap/issues?q=is%3Aissue+is%3Aclosed)
|
|
@@ -20,10 +21,17 @@ Published in [website](https://react-native-iap.dooboolab.com).
|
|
|
20
21
|
|
|
21
22
|
## Announcement
|
|
22
23
|
|
|
23
|
-
|
|
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
|
+
```
|
|
24
29
|
|
|
25
|
-
|
|
26
|
-
|
|
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 🎉
|
|
33
|
+
|
|
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
|
> 
|
|
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
|
-
|
|
76
|
-
[android-
|
|
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,76 +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
|
-
- In the past, `react-native-iap@^3.*` has been updated very
|
|
94
|
-
|
|
104
|
+
- In the past, `react-native-iap@^3.*` has been updated very promptly for migration issues.
|
|
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
|
-
4. More is
|
|
110
|
+
4. More is coming in `iOS 13`.
|
|
111
|
+
|
|
112
|
+
## Breaking Changes
|
|
100
113
|
|
|
101
|
-
|
|
102
|
-
|
|
114
|
+
[7.4.0]
|
|
115
|
+
|
|
116
|
+
- Now using React's Context to manage IAP state
|
|
117
|
+
- Introduce `withIAPContext` HOC ([how to use](docs/docs/usage_instructions/using_hooks.md))
|
|
103
118
|
|
|
104
119
|
[7.1.0]
|
|
120
|
+
|
|
105
121
|
- `androidOldSku` is no longer required [#1438](https://github.com/dooboolab/react-native-iap/pull/1438).
|
|
106
122
|
|
|
107
123
|
[6.1.0]
|
|
124
|
+
|
|
108
125
|
- Creates two variants: `play` and `amazon` and only uses the required code.
|
|
109
126
|
```
|
|
110
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`
|
|
111
128
|
```
|
|
112
|
-
[3.0.0+]
|
|
113
|
-
[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
|
|
114
133
|
|
|
115
|
-
Configuration of Google Play & iTunes Connect
|
|
116
|
-
---------------------------------------------
|
|
117
134
|
- Please refer to [Blog][blog-config-steps].
|
|
118
135
|
|
|
119
|
-
[Deprecated README][readme-deprecated]
|
|
120
|
-
|
|
136
|
+
## [Deprecated README][readme-deprecated]
|
|
137
|
+
|
|
121
138
|
- If you are using `react-native-iap@^2.*`, please follow the above README.
|
|
122
139
|
|
|
123
|
-
Usage
|
|
124
|
-
|
|
140
|
+
## Usage
|
|
141
|
+
|
|
125
142
|
You can look in the [`RNIapExample/`][example] folder to try the example.
|
|
126
143
|
|
|
127
144
|
NOTE: To run `RNIapExample` on Android use the variant flag as follows:
|
|
145
|
+
|
|
128
146
|
```
|
|
129
147
|
yarn android --variant=MY_VARIANT
|
|
130
148
|
```
|
|
149
|
+
|
|
131
150
|
where `MY_VARIANT` is `PlayDebug` or `AmazonDebug`
|
|
132
151
|
|
|
133
152
|
Below is basic implementation which is also provided in `RNIapExample` project.
|
|
134
153
|
|
|
135
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)
|
|
136
155
|
|
|
137
|
-
Sponsoring
|
|
138
|
-
----------
|
|
156
|
+
## Sponsoring
|
|
139
157
|
|
|
140
158
|
Since `IAP` itself is not perfect on each platform, we desperately need
|
|
141
159
|
this project to be maintained. If you'd like to help us, please consider being
|
|
142
160
|
with us in [Open Collective](https://opencollective.com/react-native-iap).
|
|
143
161
|
|
|
144
162
|
### Sponsors
|
|
163
|
+
|
|
145
164
|
Support this project by becoming a sponsor. Your logo will show up here with
|
|
146
165
|
a link to your website. [Become a sponsor][open-collective-sponsor].
|
|
147
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>
|
|
148
167
|
|
|
149
168
|
### Backers
|
|
169
|
+
|
|
150
170
|
Please be our [Backers][open-collective-backer].
|
|
151
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>
|
|
152
172
|
|
|
153
173
|
### Contributing
|
|
174
|
+
|
|
154
175
|
Please make sure to read the [Contributing Guide][contribute] before making a pull request.
|
|
155
176
|
Thank you to all the people who helped to maintain and upgrade this project!
|
|
156
177
|
|
|
157
178
|
<a href="graphs/contributors"><img src="https://opencollective.com/react-native-iap/contributors.svg?width=890" /></a>
|
|
179
|
+
|
|
158
180
|
<hr>
|
|
159
181
|
|
|
160
182
|
[](https://app.fossa.com/projects/git%2Bgithub.com%2Fdooboolab%2Freact-native-iap?ref=badge_large)
|
package/android/build.gradle
CHANGED
|
@@ -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
|
}
|
|
@@ -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
|
|
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
|
|
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
|
-
|
|
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 =
|
|
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 =
|
|
@@ -583,9 +577,7 @@ public class RNIapModule extends ReactContextBaseJavaModule implements Purchases
|
|
|
583
577
|
error.putString("message", errorData[1]);
|
|
584
578
|
sendEvent(reactContext, "purchase-error", error);
|
|
585
579
|
|
|
586
|
-
|
|
587
|
-
PlayUtils.getInstance().rejectPromisesWithBillingError(PROMISE_BUY_ITEM, responseCode);
|
|
588
|
-
}
|
|
580
|
+
PlayUtils.getInstance().rejectPromisesWithBillingError(PROMISE_BUY_ITEM, responseCode);
|
|
589
581
|
return;
|
|
590
582
|
}
|
|
591
583
|
|
|
@@ -665,6 +657,16 @@ public class RNIapModule extends ReactContextBaseJavaModule implements Purchases
|
|
|
665
657
|
sendUnconsumedPurchases(promise);
|
|
666
658
|
}
|
|
667
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
|
+
|
|
668
670
|
@ReactMethod
|
|
669
671
|
public String getPackageName() {
|
|
670
672
|
return getReactApplicationContext().getPackageName();
|
|
@@ -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 =
|
|
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 =
|
|
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
|
-
|
|
466
|
-
|
|
467
|
-
|
|
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.
|
|
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",
|
|
@@ -43,31 +43,31 @@
|
|
|
43
43
|
"dooboolab-welcome": "1.3.2"
|
|
44
44
|
},
|
|
45
45
|
"devDependencies": {
|
|
46
|
-
"@babel/core": "7.
|
|
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.
|
|
49
|
+
"@babel/preset-env": "7.15.6",
|
|
50
50
|
"@babel/preset-react": "7.14.5",
|
|
51
|
-
"@babel/preset-typescript": "7.
|
|
52
|
-
"@dooboo/eslint-config": "0.8.
|
|
53
|
-
"@testing-library/jest-native": "4.0.
|
|
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": "
|
|
57
|
-
"@types/react": "17.0.
|
|
58
|
-
"@types/react-native": "0.
|
|
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
|
|
62
|
-
"eslint": "7.
|
|
63
|
-
"flow-bin": "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
|
|
65
|
+
"jest": "27.2.0",
|
|
66
66
|
"metro-react-native-babel-preset": "0.66.2",
|
|
67
|
-
"monolinter": "1.0.
|
|
68
|
-
"prettier": "2.
|
|
67
|
+
"monolinter": "1.0.4",
|
|
68
|
+
"prettier": "2.4.1",
|
|
69
69
|
"react-native": "0.64.2",
|
|
70
|
-
"ts-jest": "27.0.
|
|
71
|
-
"typescript": "4.3
|
|
70
|
+
"ts-jest": "27.0.5",
|
|
71
|
+
"typescript": "4.4.3"
|
|
72
72
|
}
|
|
73
73
|
}
|
package/src/hooks/useIAP.d.ts
CHANGED
|
@@ -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[];
|
|
@@ -8,11 +9,13 @@ declare type IAP_STATUS = {
|
|
|
8
9
|
availablePurchases: Purchase[];
|
|
9
10
|
currentPurchase?: Purchase;
|
|
10
11
|
currentPurchaseError?: PurchaseError;
|
|
11
|
-
finishTransaction: (purchase: Purchase) => Promise<string | void>;
|
|
12
|
+
finishTransaction: (purchase: Purchase, isConsumable?: boolean, developerPayloadAndroid?: string) => Promise<string | void>;
|
|
12
13
|
getAvailablePurchases: () => Promise<void>;
|
|
13
14
|
getPurchaseHistories: () => Promise<void>;
|
|
14
15
|
getProducts: (skus: string[]) => Promise<void>;
|
|
15
16
|
getSubscriptions: (skus: string[]) => Promise<void>;
|
|
17
|
+
requestPurchase: typeof iapRequestPurchase;
|
|
18
|
+
requestSubscription: typeof iapRequestSubscription;
|
|
16
19
|
};
|
|
17
20
|
export declare function useIAP(): IAP_STATUS;
|
|
18
21
|
export {};
|
package/src/hooks/useIAP.js
CHANGED
|
@@ -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
|
-
|
|
38
|
-
|
|
39
|
-
|
|
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 =
|
|
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
|
|
62
|
-
return __generator(this, function (
|
|
63
|
-
switch (
|
|
64
|
-
case 0:
|
|
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
|
-
|
|
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
|
|
74
|
-
return __generator(this, function (
|
|
75
|
-
switch (
|
|
76
|
-
case 0:
|
|
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
|
-
|
|
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
|
|
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
|
-
}); }, [
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
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
|
+
requestSubscription: 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
|
+
}
|
package/src/index.d.ts
CHANGED
package/src/index.js
CHANGED
package/src/types/index.d.ts
CHANGED
|
@@ -40,7 +40,7 @@ export interface ProductCommon {
|
|
|
40
40
|
price: string;
|
|
41
41
|
currency: string;
|
|
42
42
|
localizedPrice: string;
|
|
43
|
-
|
|
43
|
+
countryCode?: string;
|
|
44
44
|
}
|
|
45
45
|
export interface ProductPurchase {
|
|
46
46
|
productId: string;
|
|
@@ -48,6 +48,7 @@ export interface ProductPurchase {
|
|
|
48
48
|
transactionDate: number;
|
|
49
49
|
transactionReceipt: string;
|
|
50
50
|
purchaseToken?: string;
|
|
51
|
+
quantityIOS?: number;
|
|
51
52
|
originalTransactionDateIOS?: string;
|
|
52
53
|
originalTransactionIdentifierIOS?: string;
|
|
53
54
|
dataAndroid?: string;
|