Research
Security News
Quasar RAT Disguised as an npm Package for Detecting Vulnerabilities in Ethereum Smart Contracts
Socket researchers uncover a malicious npm package posing as a tool for detecting vulnerabilities in Etherium smart contracts.
react-native-iap
Advanced tools
We are willing to share same in-app-purchase experience for both android and ios platform and will continuously merge methods which are standing alone.
Android iap is implemented with iap version 3 which is currently recent.
Do not use version 0.3.4
~ 0.3.8
because there was some issues in merging PR. Also please commit to dev
branch and not master
branch please if requesting PR.
react-native-iap
module versions that are not described in change logs
may not run as expected so please refer to version mentioned in Changelogs
below.
Difference between 0.3.*
and 1.0.0
has only one method renaming refreshItems
to consumeAllItems
.
To migrate 0.2.*
to 0.3.*
, You can follow below guide.
0.2.* | 0.3.* |
---|---|
prepareAndroid | prepare |
getItems | getProducts |
getSubscribeItems | getSubscriptions |
getPurchasedItemsAndroid | getPurchaseHistory |
`` | getAvailablePurchases |
buySubscribeItem | buySubscription |
buyItem | buyProduct |
consumeItemAndroid | consumePurchase |
refreshAllItems | Not Available |
refreshPurchaseItemsAndroid | Not Available |
From above method changes, getProducts
gets itemSkus
as parameter in different way then as used in getItems
. In getItems
you had to put parameter as
const itemSkus = {
ios: [
'point_1000',
],
android: [
'point_1000',
],
};
But now you should do like below which will just pass single array instead of object.
const itemSkus = Platform.select({
ios: [
'point_1000',
],
android: [
'point_1000',
],
});
Also, note that this is our last migration for renaming method names without any deprecation warning. Thank you for your understanding.
0.3.0-alpha1
has released. All the methods are renamed and current methods are merged into each single method. See Methods
section below to see what's been changed.
Breaking changes have made from 0.2.17
. refreshAllItems
has changed name to fetchHistory
. See the changelogs below.
Breaking changes have made from 0.2.16
in android. Package name has been fixed to com.dooboolab.RNIap.RNIapPackage
. Read the changelogs below. There was linking issue with wrong package name.
Breaking changes have made from 0.2.12
. Please read the changelogs below. The summary of change is that it now returns receipt in different format.
Changes from react-native-iap@0.1.*
to react-native-iap@0.2.*
is that you have prepare()
method deprecated which you should call before using RNIap
methods. Now you have to call prepareAndroid()
instead just to know that it is just android dependent method.
Also to import module, previously in react-native-iap@0.1.*
you had to import RNIap from 'react-native-iap'
but now you have to do like import * as RNIap from 'react-native-iap'
.
For new method, refreshAllItems has been implemented for both ios and android. This feature will support senario for non-consumable products.
Also there are some other methods that is not supported in ios and implemented in android. You can see more in Changelogs below.
Lastly, this module also supports types for typescript users from 0.2.5
.
refreshItems
to consumeAllItems
for clear understanding.subs
only.itemType
of Product
information always returns sub
. It is unnecessary in iOS and will be deprecated.buyProductWithoutFinishTransaction
and finishTransaction
.validateReceiptIos
and validateReceiptAndroid
methods to support all RN version.Receipt validation
section in the readme. For android
, you should have your own backend to get access_token
from googleapis
.refreshItems
in android. This is to consume all products in anroid to rebuy the item. Becareful to use this method because if will affect your history of playstore. Only use this when you don't care about the history in playstore. Use this method after prepare
method.endConnection
in android.prepare
, getProducts
, getSubscriptions
, getPurchaseHistory
, getAvailablePurchases
, buySubscription
, buyProduct
, consumeProduct
. Please compare these methods with your previous methods used in 0.2.*
if you want to upgrade to 0.3.0
.refreshAllItems
has changed name to fetchHistory
since android and ios had different functionality and fixed to fetching history of purchases.com.reactlibrary.RNIapPackage
to com.dooboolab.RNIap.RNIapPackage
;.buySubscribeItem
callback.homepage
now is mandatory attribute in cocoapods from pull request.buyItem
cancel callback.Func | Param | Return | Description |
---|---|---|---|
prepare | Promise<void> | Prepare IAP module. Must be called on Android before any other purchase flow methods. No-op on iOS. | |
getProducts | string[] Product IDs/skus | Promise<Product[]> | Get a list of products (consumable and non-consumable items, but not subscriptions). Note: On iOS versions earlier than 11.2 this method will return subscriptions if they are included in your list of SKUs. This is because we cannot differentiate between IAP products and subscriptions prior to 11.2. |
getSubscriptions | string[] Subscription IDs/skus | Promise<Subscription[]> | Get a list of subscriptions. Note: On iOS this method has the same output as getProducts . Because iOS does not differentiate between IAP products and subscriptions. |
getPurchaseHistory | Promise<Purchase[]> | Gets an invetory of purchases made by the user regardless of consumption status (where possible) | |
getAvailablePurchases | Promise<Purchase[]> | Get all purchases made by the user (either non-consumable, or haven't been consumed yet) | |
buySubscription | string Subscription ID/sku | Promise<Purchase> | Create (buy) a subscription to a sku |
buyProduct | string Product ID/sku | Promise<Purchase> | Buy a product |
buyProductWithoutFinishTransaction | string Product ID/sku | Promise<Purchase> | Buy a product without finish transaction call (iOS only) |
finishTransaction | void | void | Send finishTransaction call to Apple IAP server. Call this function after receipt validation process |
consumeProduct | string Purchase token | Promise<void> | Consume a product (on Android.) No-op on iOS. |
endConnection | Promise<void> | End billing connection (on Android.) No-op on iOS. | |
consumeAllItems | Promise<void> | Consume all items in android so they are able to buy again (on Android.) No-op on iOS. | |
validateReceiptIos | object receiptBody, boolean isTest, number RNVersion | object or boolean result | validate receipt for ios. |
validateReceiptAndroid | string packageName, string productId, string productToken, string accessToken, boolean isSubscription, number RNVersion | object or boolean result | validate receipt for android. |
https://www.npmjs.com/package/react-native-iap
https://github.com/dooboolab/react-native-iap
$ npm install react-native-iap --save
$ react-native link react-native-iap
Note for Ejected iOS Apps:
The above command will add the following to your Podfile
:
pod 'RNIap', :path => '../node_modules/react-native-iap'
You should remove this before running pod install
and follow the manual installation instructions below.
Libraries
➜ Add Files to [your project's name]
node_modules
➜ react-native-iap
and add RNIap.xcodeproj
libRNIap.a
to your project's Build Phases
➜ Link Binary With Libraries
Cmd+R
)<android/app/src/main/java/[...]/MainApplication.java
import com.dooboolab.RNIap.RNIapPackage;
to the imports at the top of the filenew RNIapPackage()
to the list returned by the getPackages()
methodandroid/settings.gradle
:
include ':react-native-iap'
project(':react-native-iap').projectDir = new File(rootProject.projectDir, '../node_modules/react-native-iap/android')
android/app/build.gradle
:
compile project(':react-native-iap')
<permission>
block in android/app/src/main/AndroidManifest.xml
:
<uses-permission android:name="com.android.vending.BILLING" />
You can look in the RNIapExample folder to try the example. Below is basic implementation which is also provided in RNIapExample project.
First thing you should do is to define your items for iOS and android separately like defined below.
import * as RNIap from 'react-native-iap';
const itemSkus = Platform.select({
ios: [
'com.example.coins100'
],
android: [
'com.example.coins100'
]
});
Next, call the prepare function (ios it's not needed, but android it is. No need to check platform though since nothing will happen in ios:
async function() {
try {
await RNIap.prepare();
// Ready to call RNIap.getProducts(), etc.
} catch(err) {
console.warn(err); // standardized err.code and err.message available
}
}
Once you called prepare(), call getProducts(). Both are async funcs. You can do it in componentDidMount(), or other area as appropriate for you app. Since a user may first start your app with a bad internet connection, then later have an internet connection, making preparing/getting items more than once may be a good idea. Like if the user has no IAPs available when the app first starts, you may want to check again when the user enters the your IAP store.
async componentDidMount() {
try {
await RNIap.prepare();
const products = await RNIap.getProducts(itemSkus);
this.setState({ items });
} catch(err) {
console.warn(err); // standardized err.code and err.message available
}
}
iOS | Android | Comment | |
---|---|---|---|
price | ✓ | ✓ | Will return localizedPrice on Android (default) or a string price (eg. 1.99 ) (iOS) |
productId | ✓ | ✓ | Returns a string needed to purchase the item later |
currency | ✓ | ✓ | Returns the currency code |
localizedPrice | ✓ | ✓ | Use localizedPrice if you want to display the price to the user so you don't need to worry about currency symbols. |
title | ✓ | ✓ | Returns the title Android and localizedTitle on iOS |
description | ✓ | ✓ | Returns the description of the product |
type | ✓ | ✓ | Returns SKU type (subscription or in-app product). iOS < 11.2 will always return null |
When you are done with the billing, you should release it for android(READ). It is not needed in ios. No need to check platform either since nothing will happen in ios. This can be used in componentWillUnMount
.
Once you have called getProducts(), and you have a valid response, you can call buyProduct().
// Will return a purchase object with a receipt which can be used to validate on your server.
const purchase = await RNIap.buyProduct('com.example.coins100');
In RNIapExample, upon receiving receiving a purchase receipt, main page will navigate to Second.js.
this.setState({ progressTitle: 'Please wait...' });
RNIap.buyProduct('com.example.coins100').then(purchase => {
this.setState({
receipt: purchase.transactionReceipt, // save the receipt if you need it, whether locally, or to your server.
progressTitle: 'Purchase Successful!',
coins: this.state.coins + 100
});
}).catch(err => {
// resetting UI
console.warn(err); // standardized err.code and err.message available
this.setState({ progressTitle: 'Buy 100 Coins for only $0.99' });
alert(err.message);
})
Subscribable products can be purchased just like consumable products. Users can cancel subscriptions by using the iOS System Settings.
You can use getAvailablePurchases()
to do what's commonly understood as "restoring" purchases. Once an item is consumed, it will no longer be available in getAvailablePurchases()
and will only be available via getPurchaseHistory()
. However, this method has some caveats on Android -- namely that purchase history only exists for the single most recent purchase of each SKU -- so your best bet is to track consumption in your app yourself. By default all items that are purchased will not be consumed unless they are automatically consumed by the store (for example, if you create a consumable item for iOS.) This means that you must manage consumption yourself. Purchases can be consumed by calling consumePurchase()
. If you want to consume all items, you have to iterate over the purchases returned by getAvailablePurchases()
.
getPurchases = async() => {
try {
const purchases = await RNIap.getAvailablePurchases();
let restoredTitles = '';
let coins = CoinStore.getCount();
purchases.forEach(purchase => {
if (purchase.productId == 'com.example.premium') {
this.setState({ premium: true });
restoredTitles += 'Premium Version';
} else if (purchase.productId == 'com.example.no_ads') {
this.setState({ ads: false });
restoredTitles += restoredTitles.length > 0 ? 'No Ads' : ', No Ads';
} else if (purchase.productId == 'com.example.coins100') {
CoinStore.addCoins(100);
await RNIap.consumePurchase(purchase.purchaseToken);
}
})
Alert.alert('Restore Successful', 'You successfully restored the following purchases: ' + restoredTitles);
} catch(err) {
console.warn(err); // standardized err.code and err.message available
Alert.alert(err.message);
}
}
Returned purchases is an array of each purchase transaction with the following keys:
{
transactionDate,
transactionId,
productId,
transactionReceipt,
purchaseToken, // available on Android (same as transactionReceipt)
autoRenewing, // available on Android
originalTransactionDate, // available on iOS
originalTransactionIdentifier // available on iOS
}
You need to test with one sandbox account, because the account holds previous purchase history.
From react-native-iap@0.3.16
, we support receipt validation. For android, you need seperate json file from service account to get the access_token
from google-apis
, therefore it is impossible to implement serverlessly. You should have your own backend and get access_token
. With access_token
you can simplly call validateReceiptAndroid
method we implemented. Further reading is here.
Currently, serverless receipt validation is possible using validateReceiptIos
method. First parameter, you should pass transactionReceipt
which returns after buyProduct
. Second parameter, you should pass whether this is test
environment. If true
, it will request to sandbox
and false
it will request to production
.
const receiptBody = {
'receipt-data': purchase.transactionReceipt,
};
const result = await validateReceiptIos(receiptBody, false, 54);
console.log(result);
For further information, please refer to guide.
Purchasing consumable products in iOS consists of the following steps.
Step 1 : Purchasing via IAP (Apple server)
Step 2 : Check the validation of the receipt (either on device or server)
Step 3 : Apply the product to the Application
But, sometimes app doesn't make it to step 3, and user loose the product with successful payment. Non-consumable products can be restored via getPurchaseHistory function, but consumable products can be lost. In this case, use buyProductWithoutFinishTransaction to purchase action and use finishTransaction to finish payment after receipt validation and supply the products to user.
master
branch.Please follow the Coding conventions as much as possible when contributing your code.
{}
in curly brackets such as function, if, foreach, for, and while should be in the following format. Also if you installed eslint in vscode or in your code editor, it will help you with linting.
{
should be placed in same line and }
should be placed in next line.for (let i = 0; i < 10; i++) {
...
}
array.forEach((e) => {
...
});
(
and after )
.The MIT License (MIT)
Copyright (c) 2017 dooboolab
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
FAQs
React Native In App Purchase Module.
The npm package react-native-iap receives a total of 35,242 weekly downloads. As such, react-native-iap popularity was classified as popular.
We found that react-native-iap demonstrated a healthy version release cadence and project activity because the last version was released less than a year ago. It has 2 open source maintainers collaborating on the project.
Did you know?
Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.
Research
Security News
Socket researchers uncover a malicious npm package posing as a tool for detecting vulnerabilities in Etherium smart contracts.
Security News
Research
A supply chain attack on Rspack's npm packages injected cryptomining malware, potentially impacting thousands of developers.
Research
Security News
Socket researchers discovered a malware campaign on npm delivering the Skuld infostealer via typosquatted packages, exposing sensitive data.