In-App Purchases In Flutter
Hello everyone, Today we will take a look at flutter’s latest package for handling in-app purchases. So, while I will be covering most of what to do to get in-app purchases working, I highly recommend checking out the official documentation of the package provided by the flutter team — https://pub.dev/packages/in_app_purchase
in_app_purchase | Flutter Package
A Flutter plugin for in-app purchases. Exposes APIs for making in-app purchases through the App Store (on iOS) and…pub.dev
So why in app purchases?
Well these in app purchases are required when we are selling digital content so that means things like stripe api wont work here.
NOTE : THIS PACKAGE IS IN BETA SO THERE MAY BE SOME ERRORS , I WILL MAKE SURE TO UPDATE THE ARTICLE AS SOON AS IT COMES OUT OF BETA VERSION
Now that that’s out of the way we will see the different types of products you can purchases through the use of this package.
- Consumable
- Non-Consumable
- Subscription
In this particular article we will only talk about the first one that is Consumable type of purchases.
These types of purchases are the ones user can make again and again like some sort of currency in a game for example primogems in genshin impact or Iris in Danmemo or gems in Clash of Clans etc,
These purchases are called consumables cause user tend to consume them over time and once depleted they want to buy it again.
Fun Fact : Fate/Grand Order game made about $4 billion as of January 31, 2020 by selling their in-game currency called saint quartz
They were able to achieve this by making their app highly fun and addicting which got people to spend more to get the characters they want. Now that we covered what are consumable types of purchases lets move on to their implementation
First we need to add the package in pubspec.ymal file
in_app_purchase: ^latest version
There are a few steps that need to be completed before we can use it as we like, see here.
After we are done with the native steps and have a signed application on google play store and app store and have products added to them, we will move on to the code
In the void main of your app add this —
void main() {
// without this we will get an error when we try to access any instance
InAppPurchaseConnection.enablePendingPurchases();
runApp(MyApp());
}
Without this we would not be able to access play store or the app store, so it is a must.
After you have added this line in void main we will move onto our code in the initState of the app
initialize() async {
connectionAvailable = await _connection.isAvailable();
if (connectionAvailable) {
await getListOfproductsFromOurStore();
await getListOfPastPurchasesMadebyUser();
_verifyPurchases();
_subscription = _connection.purchaseUpdatedStream.listen((info) {
setState(() {
print('user is making a new purchase');
purchases.addAll(info);
});
});
}
}
So in the initState, of my app I called a method called to initialize that will check if the connection is established or not, if it is available we will get a list of our products from the play store/ app store and get a list of past purchases made by the user, then we call a method to verify() to verify those purchases
then we have a variable of type StreamSubscription<List<PurchaseDetail>>
StreamSubscription<List<PurchaseDetails>> _subscription;
final InAppPurchaseConnection _connection = InAppPurchaseConnection.instance;
bool isAvailable = true;
List<ProductDetails> productDetails = [];
List<PurchaseDetails> purchasesDetails = [];
StreamSubscription subscription;
int gems = 0;
final String testID = 'test_gems';
And we provide it value inside the initialization function like so
_subscription = _connection.purchaseUpdatedStream.listen((info) {
setState(() {
print('!!!!!!!user is making a new purchase!!!!!!!!');
purchasesDetails.addAll(info);
});
});
what this does it, it subscribes to any incoming purchases from either play store or app store.
Now we will work on the getting the list of products from our store which will be done by this method we have already called in initialize
Future<void> getListOfproductsFromOurStore() async {
Set<String> ids = Set.from([testID]);
ProductDetailsResponse response = await _connection.queryProductDetails(
ids);
setState(() {
productDetails = response.productDetails;
});
}
We have done a basic query where we get all the products whose ids match the one we have provided
You can also do this for multiple ids
const Set<String> _kIds = {'product1', 'product2'};
final ProductDetailsResponse response = await InAppPurchaseConnection.instance.queryProductDetails(_kIds);
So after we get the response we set them in our productDetails, now we have the list of all the products we have available on our play store and app store
Now we will try to load our past purchases by using another method defined in initialize() that is
Future<void> getListOfPastPurchasesMadebyUser() async {
QueryPurchaseDetailsResponse response = await _connection.queryPastPurchases();
for (PurchaseDetails purchaseDetails in response.pastPurchases) {
if (Platform.isIOS) {
_connection.completePurchase(purchaseDetails);
}
setState(() {
purchasesDetails = response.pastPurchases;
});
}
}
Here we have simply made a query to get all the past purchases made by the user and then used a for in loop to sort through them and then set the value of purchasesDetails equal to the response.pastPuchases we got from the query
Now to finally do the purchase we will use this function
buy(ProductDetails pd) {
final PurchaseParam purchaseParam = PurchaseParam(productDetails: pd);
_connection.buyConsumable(purchaseParam: purchaseParam);
}
So we create a PuchaseParam type variable and set it same value as the value we will get from a particular value in a list of productDetails list
After that we will use .buyConsumable method which takes a parameter of purchaseParam and then we pass the variable we created there.
That is all we need to do in order to complete an in-app purchase.
Feel free to connect with us:
And read more articles from FlutterDevs.com.
FlutterDevs team of Flutter developers to build high-quality and functionally-rich apps. Hire flutter developer for your cross-platform Flutter mobile app project on an hourly or full-time basis as per your requirement! You can connect with us on Facebook, GitHub, Twitter, and LinkedIn for any flutter related queries.
We welcome feedback and hope that you share what you’re working on using #FlutterDevs. We truly enjoy seeing how you use Flutter to build beautiful, interactive web experiences!.