2024-02-04T06:40:22.298Z
nova-2
2-general-nova
2024-01-09.29447
30089e05-99d1-4376-b32e-c263170674af
b5dc7f07-0783-453a-b979-3885edbe11ac
6de82fac73572b5668d336bcf9ce2f59e4274df91c3f3cebdb0c27bd0319c8ba
67875a7f-c9c4-48a0-aa55-5bdb8a91c34a
deprecated
In 2018, the game Candy Crush made an estimated $4,000,000 from in app purchases and micro transactions per day.
And like most of the top grossing mobile apps, they sell useless digital products to casual gamers.
In today's video, you'll learn how to implement consumable in app purchases in Flutter, allowing you to sell your own digital products on iOS or Android via microtransactions.
Not just doing this for money.
We're doing it for a shitload money.
If you're new here, like and subscribe, and you can find the source code on FireShip.
Io.
And congrats to Andre Hava, he won the t shirt from last week's sweater video.
Let's start by talking about how in app purchases work from a high level, and how to use them successfully in your app.
The first thing you should know is that there are 3 main types of in app fizz.
Consumables are products that are depleted that can be purchased multiple times, like coins in a game.
Consumables are what we're focused on in this video, and we'll build a feature that allows the user to buy some gyms, to consume them and then buy some more.
The second type is a non consumable, which is something the user purchases once like an upgrade and then should never have to purchase it again in the future.
And the 3rd type is a subscription, which gives the user access to the purchase for a limited amount of time.
Now these concepts apply to both iOS from Android, but there are some subtle yet important differences that we'll look at when we get into the code in a few minutes.
And another thing you should know about in app purchases is that they're almost always required if you're selling digital content.
That means APIs like Stripe and PayPal are out of the question.
But luckily, Flutter just recently released an officially supported plugin for in app purchases that provides a unified interface across iOS in Android.
That's what we'll be using in this video, but it is currently in beta, so things may change in the future.
Now when it comes to making 1,000,000 of dollars per day, you need to build an app that's fold highly addictive, and that targets a wide audience.
I wasted everyone's money, I wasted everyone's everything, and I feel bad.
You don't think I feel bad?
You should design your interface around dopamine hits and compulsion loops.
In other words, reward the user on a regular basis, but always keep them chasing the dragon.
Dad, get off our Xbox.
Hang on, I almost cut the dragon!
You almost got it!
No!
No ice it!
I am your father!
Put it back hard!
Mommy, you get dad out of here.
So now that you know how to design your app, let's go ahead and get into the technical details.
The first thing we'll take care of is the initial setup for both iOS and Android.
For iOS, you'll need to have an Apple developer account, and I'm making the assumption that you have a release of your iOS app on App Store Connect.
It doesn't need to be on the public app storage, just App Store Connect, for use with things like TestFlight.
There are a lot of small but easy steps involved with that that are beyond the scope of this video, but the Flutter documentation has a detailed guide for preparing an iOS release, and I also have a video that covers it in my full Flutter course.
In App Store Connect, we'll go to the features tab, add a new in app purchase, making sure that it's a consumable type.
Then we'll give it a name and a product ID, and we want to keep a note of this product ID because we want that to be the same on the Google Play Store.
And everything else is just the pricing and display details for your actual product.
So now that we have our product, we'll go into Xcode and enable the In App Purchases capability.
Select the build target, go to the Capabilities tab, and then flip the In App Purchases switch to On.
So that takes care of the Apple App Store.
Now let's switch gears to Android and the Google Play Store.
At this point, I'm assuming that you have a Google Play Developer account, and you'll also need to go through the steps to create a signed release that can be uploaded to Google Play.
And once again, there are a lot of easy steps involved beyond the scope of this video, so refer to the Flutter documentation or the full Flutter course.
Once you create the actual signed APK, you'll need to create at least an alpha release for your app, and that will allow you to test the Google Play Billing API locally on your device.
The Google Billing API simply won't work if you don't have a release created for your app.
And you'll also want to add your email address as a tester on that track.
From there we'll go to the Store Presence tab, then to In App Products, and then go to Manage Products.
Now on Google Play you don't actually select a distinction between consumable and non consumable, Instead, you handle that directly in the app.
And we'll see how that works in the source code in just a minute.
For now, we'll go ahead and create a new product with the same product ID that we used on iOS.
Now make sure to set your product to active, and then everything else should be pretty self explanatory.
Now that we have the initial setup out of the way, we can start developing our Flutter app.
Now, I wanna start by saying that the code I'm about to show you focuses on the API of the in app purchases plugin.
I want to keep the implementation details as unopinionated as possible, So I'm only using the tools that are built into Flutter, but this is a type of feature that could benefit from things like Provider, Block, or Firebase to manage the state of your purchases across multiple devices and screens.
But I'll leave those decisions up to you.
I just wanna show you how to build a minimum viable product using nothing but a stateful widget.
The first thing we'll do is add the plugin to our Pubspec YAML, then we'll go ahead and import it in our Dart file along with IO so we can do platform checking.
I'm calling this the market screen, and let's start by looking at the different properties or state available on this widget.
First, we'll make a reference to the in app purchase connection instance, which gives us access to all of the API methods in the plugin.
That'll just keep our code nice and concise.
The first part of the initialization process is to check if the API is actually available on this device.
Then we'll set up a list that keeps the product details that we query from the Google Play Store or the Apple App Store, and then also a set of purchase details that gives us the user's past purchases.
Then we'll also set up a subscription that listens to a stream of updates to the purchase details.
So this stream will emit a new value when the user buys a product in the app, or if they buy a product from a different client.
And lastly, I have a placeholder for credits, which is just used to represent the consumable product in this demo.
Now moving on to the life cycle hooks, during init state, we're going to fetch the products and purchases from the corresponding marketplace.
And that stuff is all asynchronous, so we'll move it into its own method.
And we also have a stream on this widget, so we'll want to make sure to cancel it.
Now the next thing we'll look at is the actual UI itself, which is very simple in this case.
We have a Scaffold with an app bar that will either display open for business or not available depending on whether or not the in Snap Purchases APIs available.
From there, we'll loop over the products that we fetch from the marketplace.
And then for each product, we'll need to determine if the user has a past purchase for it.
If they have purchased a product, then we'll create some custom logic to allow them to consume it.
Otherwise, we'll just go ahead and display a button that allows them to make a new purchase.
This is just a bare minimum UI example, so you'll definitely want to customize it to fit within your own app.
Now the next major hurdle that we'll tackle is initializing all of the data in this widget.
We'll We'll do that with an async method called initialize that we call during the init state lifecycle hook.
First, we'll check to see if the API is available, And then if so, we'll go ahead and retrieve the products and the users' past purchases.
And I've moved that logic into individual private methods just so we get a clear picture of all the steps involved.
And I'm sure someone will call me out on this, so instead of awaiting products and then awaiting purchases, you can do it concurrently by using Future Wait and add both of them together in a list.
And that will run them concurrently for better performance.
Now just because you have retrieved a purchase does not necessarily mean that it's valid.
So we'll also need to implement some business logic to verify a purchase.
And then throughout the lifecycle of the app, the user will hopefully purchase additional products, so we'll want to set up a subscription to the purchase updated stream.
A stream will emit a list of newly created purchase details.
So when the stream emits a new value, we can take those new purchases and then append them to the existing list on this widget.
What you don't want to do is override the existing list because the stream only emits new purchases.
So that's just something to keep in mind.
So now let's look at the implementation details for this data retrieval.
1st, we get products, which is no different than making an API call or reading from a Firestore document.
We just create a set of the product IDs that we want to retrieve from either the App Store or the Google Play Store, and then we run In App Purchases Query Product Details.
That's going to give us a response, and then we can check that response for errors or to see if any of the product IDs are missing.
But for the sake of simplicity, we'll call Set estate and set the products equal to the response product details.
So that gives us our products for sale.
Now we need to get the users past Purchases.
This is a very similar process, but instead we call query past purchases.
But there's one major caveat, and this method does not return consumed products.
Because a consumed product can be purchased multiple times, it's not going to be returned by this method.
That means you need to save the state of a consumed product in your database.
That's the only way the user will be able to retrieve it after this widget has been destroyed.
So getting past purchases from the actual marketplace itself is really only relevant for non consumable products.
But one other caveat that you should know about is if you retrieve past purchases, you'll also want to mark them as complete on iOS.
Now if you do have a consumable product, It will be 100% your own business logic to retrieve it.
If this were my app, I would be using Firebase, so I would most likely retrieve it from the Firestore database.
In any case, the final step here is to call SetState and set the Purchases list on this widget.
Now the next thing we need to do is figure out if a user has purchased a specific product.
In this case, I'm just going to create a helper method that takes a product ID as its argument, and then it loops through the purchases list to see if we have any matching IDs.
If we have a match, then we'll go ahead and return the purchase details, otherwise, we'll return null.
Now the next method is also going to be 100% your own business logic that will take a purchase and then actually deliver it in the app itself.
In this demo, we only have a single product, so we're going to see if that user has purchased the product, And we'll also go ahead and make sure that that purchase is valid.
The status can also be error or pending, so we wouldn't want to deliver the credits or the gems to the app if the user hasn't fully paid.
You'll want to verify purchases both when the app is initialized and then also when a new purchase is emitted through that purchase updated stream.
And you may even want to do that server side.
So at this point we have all of the necessary data loaded into our widget, and now we need to give the user a way to purchase a product as well as consume a product.
Inside of our products loop, we'll have access to individual product details, which we can then pass to this byproduct method to create a purchase param That will send the necessary data over to the corresponding marketplace.
And then because Android doesn't make the distinction between consumable and non consumable, you need to do that when you purchase the product.
So for one time purchases, you'll use Buy Non Consumable.
But in our case, we want the user to buy this multiple times, so we'll say Buy Consumable.
Now by default it will be marked as consumed automatically, which means it's up to your own business logic to control the state of that purchase.
However, I would like to point out that you can set auto consume to false, which only applies to Android, and that will prevent the user from purchasing that product again until you actually mark it as consumed.
And we can actually demonstrate how that works with our next method here called Spend Credits.
It takes the purchase details as its argument and then it will decrement the credits on this widget every time the user taps to button.
When the user runs out of credits or when they equal 0, we'll go ahead and tell the Google Play Store that that purchase has been consumed, and that will allow the user to purchase another instance of this product.
Otherwise, they'll get an error that they already own this product.
And that's all there is to it.
We now have all the pieces in place to sell our users an infinite number of useless list gems, and we just need to refine our dopamine hits and compulsion loops to start making 1,000,000 of dollars per day.
If this video helped you, please like and subscribe, and consider becoming a pro member on Fireship.
Io to get access fizz to the Full Flutter course and a bunch of other exclusive content.
Thanks for watching and I will talk to you soon.

Speaker 0: In 2018, the game Candy Crush made an estimated $4,000,000 from in app purchases and micro transactions per day. And like most of the top grossing mobile apps, they sell useless digital products to casual gamers. In today's video, you'll learn how to implement consumable in app purchases in Flutter, allowing you to sell your own digital products on iOS or Android via microtransactions. Not just doing this for money. We're doing it for a shitload money.

If you're new here, like and subscribe, and you can find the source code on FireShip. Io. And congrats to Andre Hava, he won the t shirt from last week's sweater video. Let's start by talking about how in app purchases work from a high level, and how to use them successfully in your app. The first thing you should know is that there are 3 main types of in app fizz.

Consumables are products that are depleted that can be purchased multiple times, like coins in a game. Consumables are what we're focused on in this video, and we'll build a feature that allows the user to buy some gyms, to consume them and then buy some more. The second type is a non consumable, which is something the user purchases once like an upgrade and then should never have to purchase it again in the future. And the 3rd type is a subscription, which gives the user access to the purchase for a limited amount of time. Now these concepts apply to both iOS from Android, but there are some subtle yet important differences that we'll look at when we get into the code in a few minutes.

And another thing you should know about in app purchases is that they're almost always required if you're selling digital content. That means APIs like Stripe and PayPal are out of the question. But luckily, Flutter just recently released an officially supported plugin for in app purchases that provides a unified interface across iOS in Android. That's what we'll be using in this video, but it is currently in beta, so things may change in the future. Now when it comes to making 1,000,000 of dollars per day, you need to build an app that's fold highly addictive, and that targets a wide audience.

I wasted everyone's money, I wasted everyone's everything, and I feel bad. You don't think I feel bad? You should design your interface around dopamine hits and compulsion loops. In other words, reward the user on a regular basis, but always keep them chasing the dragon. Dad, get off our Xbox.

Hang on, I almost cut the dragon! You almost got it! No! No ice it! I am your father!

Put it back hard! Mommy, you get dad out of here. So now that you know how to design your app, let's go ahead and get into the technical details. The first thing we'll take care of is the initial setup for both iOS and Android. For iOS, you'll need to have an Apple developer account, and I'm making the assumption that you have a release of your iOS app on App Store Connect.

It doesn't need to be on the public app storage, just App Store Connect, for use with things like TestFlight. There are a lot of small but easy steps involved with that that are beyond the scope of this video, but the Flutter documentation has a detailed guide for preparing an iOS release, and I also have a video that covers it in my full Flutter course. In App Store Connect, we'll go to the features tab, add a new in app purchase, making sure that it's a consumable type. Then we'll give it a name and a product ID, and we want to keep a note of this product ID because we want that to be the same on the Google Play Store. And everything else is just the pricing and display details for your actual product.

So now that we have our product, we'll go into Xcode and enable the In App Purchases capability. Select the build target, go to the Capabilities tab, and then flip the In App Purchases switch to On. So that takes care of the Apple App Store. Now let's switch gears to Android and the Google Play Store. At this point, I'm assuming that you have a Google Play Developer account, and you'll also need to go through the steps to create a signed release that can be uploaded to Google Play.

And once again, there are a lot of easy steps involved beyond the scope of this video, so refer to the Flutter documentation or the full Flutter course. Once you create the actual signed APK, you'll need to create at least an alpha release for your app, and that will allow you to test the Google Play Billing API locally on your device. The Google Billing API simply won't work if you don't have a release created for your app. And you'll also want to add your email address as a tester on that track. From there we'll go to the Store Presence tab, then to In App Products, and then go to Manage Products.

Now on Google Play you don't actually select a distinction between consumable and non consumable, Instead, you handle that directly in the app. And we'll see how that works in the source code in just a minute. For now, we'll go ahead and create a new product with the same product ID that we used on iOS. Now make sure to set your product to active, and then everything else should be pretty self explanatory. Now that we have the initial setup out of the way, we can start developing our Flutter app.

Now, I wanna start by saying that the code I'm about to show you focuses on the API of the in app purchases plugin. I want to keep the implementation details as unopinionated as possible, So I'm only using the tools that are built into Flutter, but this is a type of feature that could benefit from things like Provider, Block, or Firebase to manage the state of your purchases across multiple devices and screens. But I'll leave those decisions up to you. I just wanna show you how to build a minimum viable product using nothing but a stateful widget. The first thing we'll do is add the plugin to our Pubspec YAML, then we'll go ahead and import it in our Dart file along with IO so we can do platform checking.

I'm calling this the market screen, and let's start by looking at the different properties or state available on this widget. First, we'll make a reference to the in app purchase connection instance, which gives us access to all of the API methods in the plugin. That'll just keep our code nice and concise. The first part of the initialization process is to check if the API is actually available on this device. Then we'll set up a list that keeps the product details that we query from the Google Play Store or the Apple App Store, and then also a set of purchase details that gives us the user's past purchases.

Then we'll also set up a subscription that listens to a stream of updates to the purchase details. So this stream will emit a new value when the user buys a product in the app, or if they buy a product from a different client. And lastly, I have a placeholder for credits, which is just used to represent the consumable product in this demo. Now moving on to the life cycle hooks, during init state, we're going to fetch the products and purchases from the corresponding marketplace. And that stuff is all asynchronous, so we'll move it into its own method.

And we also have a stream on this widget, so we'll want to make sure to cancel it. Now the next thing we'll look at is the actual UI itself, which is very simple in this case. We have a Scaffold with an app bar that will either display open for business or not available depending on whether or not the in Snap Purchases APIs available. From there, we'll loop over the products that we fetch from the marketplace. And then for each product, we'll need to determine if the user has a past purchase for it.

If they have purchased a product, then we'll create some custom logic to allow them to consume it. Otherwise, we'll just go ahead and display a button that allows them to make a new purchase. This is just a bare minimum UI example, so you'll definitely want to customize it to fit within your own app. Now the next major hurdle that we'll tackle is initializing all of the data in this widget. We'll We'll do that with an async method called initialize that we call during the init state lifecycle hook.

First, we'll check to see if the API is available, And then if so, we'll go ahead and retrieve the products and the users' past purchases. And I've moved that logic into individual private methods just so we get a clear picture of all the steps involved. And I'm sure someone will call me out on this, so instead of awaiting products and then awaiting purchases, you can do it concurrently by using Future Wait and add both of them together in a list. And that will run them concurrently for better performance. Now just because you have retrieved a purchase does not necessarily mean that it's valid.

So we'll also need to implement some business logic to verify a purchase. And then throughout the lifecycle of the app, the user will hopefully purchase additional products, so we'll want to set up a subscription to the purchase updated stream. A stream will emit a list of newly created purchase details. So when the stream emits a new value, we can take those new purchases and then append them to the existing list on this widget. What you don't want to do is override the existing list because the stream only emits new purchases.

So that's just something to keep in mind. So now let's look at the implementation details for this data retrieval. 1st, we get products, which is no different than making an API call or reading from a Firestore document. We just create a set of the product IDs that we want to retrieve from either the App Store or the Google Play Store, and then we run In App Purchases Query Product Details. That's going to give us a response, and then we can check that response for errors or to see if any of the product IDs are missing.

But for the sake of simplicity, we'll call Set estate and set the products equal to the response product details. So that gives us our products for sale. Now we need to get the users past Purchases. This is a very similar process, but instead we call query past purchases. But there's one major caveat, and this method does not return consumed products.

Because a consumed product can be purchased multiple times, it's not going to be returned by this method. That means you need to save the state of a consumed product in your database. That's the only way the user will be able to retrieve it after this widget has been destroyed. So getting past purchases from the actual marketplace itself is really only relevant for non consumable products. But one other caveat that you should know about is if you retrieve past purchases, you'll also want to mark them as complete on iOS.

Now if you do have a consumable product, It will be 100% your own business logic to retrieve it. If this were my app, I would be using Firebase, so I would most likely retrieve it from the Firestore database. In any case, the final step here is to call SetState and set the Purchases list on this widget. Now the next thing we need to do is figure out if a user has purchased a specific product. In this case, I'm just going to create a helper method that takes a product ID as its argument, and then it loops through the purchases list to see if we have any matching IDs.

If we have a match, then we'll go ahead and return the purchase details, otherwise, we'll return null. Now the next method is also going to be 100% your own business logic that will take a purchase and then actually deliver it in the app itself. In this demo, we only have a single product, so we're going to see if that user has purchased the product, And we'll also go ahead and make sure that that purchase is valid. The status can also be error or pending, so we wouldn't want to deliver the credits or the gems to the app if the user hasn't fully paid. You'll want to verify purchases both when the app is initialized and then also when a new purchase is emitted through that purchase updated stream.

And you may even want to do that server side. So at this point we have all of the necessary data loaded into our widget, and now we need to give the user a way to purchase a product as well as consume a product. Inside of our products loop, we'll have access to individual product details, which we can then pass to this byproduct method to create a purchase param That will send the necessary data over to the corresponding marketplace. And then because Android doesn't make the distinction between consumable and non consumable, you need to do that when you purchase the product. So for one time purchases, you'll use Buy Non Consumable.

But in our case, we want the user to buy this multiple times, so we'll say Buy Consumable. Now by default it will be marked as consumed automatically, which means it's up to your own business logic to control the state of that purchase. However, I would like to point out that you can set auto consume to false, which only applies to Android, and that will prevent the user from purchasing that product again until you actually mark it as consumed. And we can actually demonstrate how that works with our next method here called Spend Credits. It takes the purchase details as its argument and then it will decrement the credits on this widget every time the user taps to button.

When the user runs out of credits or when they equal 0, we'll go ahead and tell the Google Play Store that that purchase has been consumed, and that will allow the user to purchase another instance of this product. Otherwise, they'll get an error that they already own this product. And that's all there is to it. We now have all the pieces in place to sell our users an infinite number of useless list gems, and we just need to refine our dopamine hits and compulsion loops to start making 1,000,000 of dollars per day. If this video helped you, please like and subscribe, and consider becoming a pro member on Fireship.

Io to get access fizz to the Full Flutter course and a bunch of other exclusive content. Thanks for watching and I will talk to you soon.
In 2018, the game Candy Crush made an estimated $4,000,000 from in app purchases and micro transactions per day. And like most of the top grossing mobile apps, they sell useless digital products to casual gamers. In today's video, you'll learn how to implement consumable in app purchases in Flutter, allowing you to sell your own digital products on iOS or Android via microtransactions.
candy
toys
games
gambling
Not just doing this for money. We're doing it for a shitload money. If you're new here, like and subscribe, and you can find the source code on FireShip. Io. And congrats to Andre Hava, he won the t shirt from last week's sweater video. Let's start by talking about how in app purchases work from a high level, and how to use them successfully in your app. The first thing you should know is that there are 3 main types of in app fizz. Consumables are products that are depleted that can be purchased multiple times, like coins in a game. Consumables are what we're focused on in this video, and we'll build a feature that allows the user to buy some gyms, to consume them and then buy some more. The second type is a non consumable, which is something the user purchases once like an upgrade and then should never have to purchase it again in the future.
toys
products
games
apple
youtube
purchasing
And the 3rd type is a subscription, which gives the user access to the purchase for a limited amount of time. Now these concepts apply to both iOS from Android, but there are some subtle yet important differences that we'll look at when we get into the code in a few minutes.
And another thing you should know about in app purchases is that they're almost always required if you're selling digital content. That means APIs like Stripe and PayPal are out of the question. But luckily, Flutter just recently released an officially supported plugin for in app purchases that provides a unified interface across iOS in Android. That's what we'll be using in this video, but it is currently in beta, so things may change in the future. Now when it comes to making 1,000,000 of dollars per day, you need to build an app that's fold highly addictive, and that targets a wide audience. I wasted everyone's money, I wasted everyone's everything, and I feel bad. You don't think I feel bad? You should design your interface around dopamine hits and compulsion loops. In other words, reward the user on a regular basis, but always keep them chasing the dragon. Dad, get off our Xbox.
gambling
purchasing
youtube
recreational drugs
Hang on, I almost cut the dragon!
You almost got it! No! No ice it! I am your father! Put it back hard! Mommy, you get dad out of here. So now that you know how to design your app, let's go ahead and get into the technical details. The first thing we'll take care of is the initial setup for both iOS and Android. For iOS, you'll need to have an Apple developer account, and I'm making the assumption that you have a release of your iOS app on App Store Connect. It doesn't need to be on the public app storage, just App Store Connect, for use with things like TestFlight. There are a lot of small but easy steps involved with that that are beyond the scope of this video, but the Flutter documentation has a detailed guide for preparing an iOS release, and I also have a video that covers it in my full Flutter course.
apple
streaming
In App Store Connect, we'll go to the features tab, add a new in app purchase, making sure that it's a consumable type. Then we'll give it a name and a product ID, and we want to keep a note of this product ID because we want that to be the same on the Google Play Store.
And everything else is just the pricing and display details for your actual product. So now that we have our product, we'll go into Xcode and enable the In App Purchases capability. Select the build target, go to the Capabilities tab, and then flip the In App Purchases switch to On. So that takes care of the Apple App Store. Now let's switch gears to Android and the Google Play Store. At this point, I'm assuming that you have a Google Play Developer account, and you'll also need to go through the steps to create a signed release that can be uploaded to Google Play. And once again, there are a lot of easy steps involved beyond the scope of this video, so refer to the Flutter documentation or the full Flutter course. Once you create the actual signed APK, you'll need to create at least an alpha release for your app, and that will allow you to test the Google Play Billing API locally on your device. The Google Billing API simply won't work if you don't have a release created for your app. And you'll also want to add your email address as a tester on that track. From there we'll go to the Store Presence tab, then to In App Products, and then go to Manage Products. Now on Google Play you don't actually select a distinction between consumable and non consumable, Instead, you handle that directly in the app. And we'll see how that works in the source code in just a minute.
billing
google
purchasing
commerce
youtube
For now, we'll go ahead and create a new product with the same product ID that we used on iOS.
Now make sure to set your product to active, and then everything else should be pretty self explanatory. Now that we have the initial setup out of the way, we can start developing our Flutter app. Now, I wanna start by saying that the code I'm about to show you focuses on the API of the in app purchases plugin. I want to keep the implementation details as unopinionated as possible, So I'm only using the tools that are built into Flutter, but this is a type of feature that could benefit from things like Provider, Block, or Firebase to manage the state of your purchases across multiple devices and screens. But I'll leave those decisions up to you. I just wanna show you how to build a minimum viable product using nothing but a stateful widget. The first thing we'll do is add the plugin to our Pubspec YAML, then we'll go ahead and import it in our Dart file along with IO so we can do platform checking. I'm calling this the market screen, and let's start by looking at the different properties or state available on this widget. First, we'll make a reference to the in app purchase connection instance, which gives us access to all of the API methods in the plugin. That'll just keep our code nice and concise. The first part of the initialization process is to check if the API is actually available on this device. Then we'll set up a list that keeps the product details that we query from the Google Play Store or the Apple App Store, and then also a set of purchase details that gives us the user's past purchases. Then we'll also set up a subscription that listens to a stream of updates to the purchase details. So this stream will emit a new value when the user buys a product in the app, or if they buy a product from a different client. And lastly, I have a placeholder for credits, which is just used to represent the consumable product in this demo. Now moving on to the life cycle hooks, during init state, we're going to fetch the products and purchases from the corresponding marketplace. And that stuff is all asynchronous, so we'll move it into its own method. And we also have a stream on this widget, so we'll want to make sure to cancel it. Now the next thing we'll look at is the actual UI itself, which is very simple in this case.
software
commerce
billing
purchasing
copyright licenses
customers
google
customer support
telecommunications
programming
trade
marketing
advertising
software development
streaming
shipping
We have a Scaffold with an app bar that will either display open for business or not available depending on whether or not the in Snap Purchases APIs available.
From there, we'll loop over the products that we fetch from the marketplace. And then for each product, we'll need to determine if the user has a past purchase for it. If they have purchased a product, then we'll create some custom logic to allow them to consume it. Otherwise, we'll just go ahead and display a button that allows them to make a new purchase. This is just a bare minimum UI example, so you'll definitely want to customize it to fit within your own app. Now the next major hurdle that we'll tackle is initializing all of the data in this widget. We'll We'll do that with an async method called initialize that we call during the init state lifecycle hook.
customers
purchasing
commerce
sales
programming
products
First, we'll check to see if the API is available, And then if so, we'll go ahead and retrieve the products and the users' past purchases.
And I've moved that logic into individual private methods just so we get a clear picture of all the steps involved. And I'm sure someone will call me out on this, so instead of awaiting products and then awaiting purchases, you can do it concurrently by using Future Wait and add both of them together in a list. And that will run them concurrently for better performance. Now just because you have retrieved a purchase does not necessarily mean that it's valid. So we'll also need to implement some business logic to verify a purchase. And then throughout the lifecycle of the app, the user will hopefully purchase additional products, so we'll want to set up a subscription to the purchase updated stream. A stream will emit a list of newly created purchase details. So when the stream emits a new value, we can take those new purchases and then append them to the existing list on this widget.
purchasing
streaming
operations
customers
commerce
billing
customer support
What you don't want to do is override the existing list because the stream only emits new purchases. So that's just something to keep in mind. So now let's look at the implementation details for this data retrieval. 1st, we get products, which is no different than making an API call or reading from a Firestore document. We just create a set of the product IDs that we want to retrieve from either the App Store or the Google Play Store, and then we run In App Purchases Query Product Details. That's going to give us a response, and then we can check that response for errors or to see if any of the product IDs are missing. But for the sake of simplicity, we'll call Set estate and set the products equal to the response product details. So that gives us our products for sale. Now we need to get the users past Purchases. This is a very similar process, but instead we call query past purchases. But there's one major caveat, and this method does not return consumed products. Because a consumed product can be purchased multiple times, it's not going to be returned by this method.
purchasing
google
sales
customers
real estate
commerce
products
streaming
That means you need to save the state of a consumed product in your database.
That's the only way the user will be able to retrieve it after this widget has been destroyed. So getting past purchases from the actual marketplace itself is really only relevant for non consumable products. But one other caveat that you should know about is if you retrieve past purchases, you'll also want to mark them as complete on iOS. Now if you do have a consumable product, It will be 100% your own business logic to retrieve it. If this were my app, I would be using Firebase, so I would most likely retrieve it from the Firestore database.
purchasing
commerce
theft
In any case, the final step here is to call SetState and set the Purchases list on this widget. Now the next thing we need to do is figure out if a user has purchased a specific product. In this case, I'm just going to create a helper method that takes a product ID as its argument, and then it loops through the purchases list to see if we have any matching IDs.
purchasing
If we have a match, then we'll go ahead and return the purchase details, otherwise, we'll return null. Now the next method is also going to be 100% your own business logic that will take a purchase and then actually deliver it in the app itself. In this demo, we only have a single product, so we're going to see if that user has purchased the product, And we'll also go ahead and make sure that that purchase is valid. The status can also be error or pending, so we wouldn't want to deliver the credits or the gems to the app if the user hasn't fully paid. You'll want to verify purchases both when the app is initialized and then also when a new purchase is emitted through that purchase updated stream. And you may even want to do that server side. So at this point we have all of the necessary data loaded into our widget, and now we need to give the user a way to purchase a product as well as consume a product. Inside of our products loop, we'll have access to individual product details, which we can then pass to this byproduct method to create a purchase param That will send the necessary data over to the corresponding marketplace. And then because Android doesn't make the distinction between consumable and non consumable, you need to do that when you purchase the product. So for one time purchases, you'll use Buy Non Consumable. But in our case, we want the user to buy this multiple times, so we'll say Buy Consumable. Now by default it will be marked as consumed automatically, which means it's up to your own business logic to control the state of that purchase. However, I would like to point out that you can set auto consume to false, which only applies to Android, and that will prevent the user from purchasing that product again until you actually mark it as consumed.
purchasing
sales
customers
logic
commerce
products
marketing
billing
customer support
patents
And we can actually demonstrate how that works with our next method here called Spend Credits. It takes the purchase details as its argument and then it will decrement the credits on this widget every time the user taps to button. When the user runs out of credits or when they equal 0, we'll go ahead and tell the Google Play Store that that purchase has been consumed, and that will allow the user to purchase another instance of this product. Otherwise, they'll get an error that they already own this product. And that's all there is to it. We now have all the pieces in place to sell our users an infinite number of useless list gems, and we just need to refine our dopamine hits and compulsion loops to start making 1,000,000 of dollars per day. If this video helped you, please like and subscribe, and consider becoming a pro member on Fireship. Io to get access fizz to the Full Flutter course and a bunch of other exclusive content. Thanks for watching and I will talk to you soon.
youtube
streaming
billing
video gaming
purchasing
candy
google
revenue
cryptocurrency
In 2018, the game Candy Crush made an estimated $4,000,000 from in app purchases and micro transactions per day. And like most of the top grossing mobile apps, they sell useless digital products to casual gamers. In today's video, you'll learn how to implement consumable in app purchases in Flutter, allowing you to sell your own digital products on iOS or Android via microtransactions. Not just doing this for money. We're doing it for a shitload money. If you're new here, like and subscribe, and you can find the source code on FireShip. Io. And congrats to Andre Hava, he won the t shirt from last week's sweater video. Let's start by talking about how in app purchases work from a high level, and how to use them successfully in your app. The first thing you should know is that there are 3 main types of in app fizz. Consumables are products that are depleted that can be purchased multiple times, like coins in a game. Consumables are what we're focused on in this video, and we'll build a feature that allows the user to buy some gyms, to consume them and then buy some more. The second type is a non consumable, which is something the user purchases once like an upgrade and then should never have to purchase it again in the future. And the 3rd type is a subscription, which gives the user access to the purchase for a limited amount of time. Now these concepts apply to both iOS from Android, but there are some subtle yet important differences that we'll look at when we get into the code in a few minutes. And another thing you should know about in app purchases is that they're almost always required if you're selling digital content. That means APIs like Stripe and PayPal are out of the question. But luckily, Flutter just recently released an officially supported plugin for in app purchases that provides a unified interface across iOS in Android. That's what we'll be using in this video, but it is currently in beta, so things may change in the future. Now when it comes to making 1,000,000 of dollars per day, you need to build an app that's fold highly addictive, and that targets a wide audience. I wasted everyone's money, I wasted everyone's everything, and I feel bad. You don't think I feel bad? You should design your interface around dopamine hits and compulsion loops. In other words, reward the user on a regular basis, but always keep them chasing the dragon. Dad, get off our Xbox. Hang on, I almost cut the dragon! You almost got it! No! No ice it! I am your father! Put it back hard! Mommy, you get dad out of here. So now that you know how to design your app, let's go ahead and get into the technical details. The first thing we'll take care of is the initial setup for both iOS and Android. For iOS, you'll need to have an Apple developer account, and I'm making the assumption that you have a release of your iOS app on App Store Connect. It doesn't need to be on the public app storage, just App Store Connect, for use with things like TestFlight. There are a lot of small but easy steps involved with that that are beyond the scope of this video, but the Flutter documentation has a detailed guide for preparing an iOS release, and I also have a video that covers it in my full Flutter course. In App Store Connect, we'll go to the features tab, add a new in app purchase, making sure that it's a consumable type. Then we'll give it a name and a product ID, and we want to keep a note of this product ID because we want that to be the same on the Google Play Store. And everything else is just the pricing and display details for your actual product. So now that we have our product, we'll go into Xcode and enable the In App Purchases capability. Select the build target, go to the Capabilities tab, and then flip the In App Purchases switch to On. So that takes care of the Apple App Store. Now let's switch gears to Android and the Google Play Store. At this point, I'm assuming that you have a Google Play Developer account, and you'll also need to go through the steps to create a signed release that can be uploaded to Google Play. And once again, there are a lot of easy steps involved beyond the scope of this video, so refer to the Flutter documentation or the full Flutter course. Once you create the actual signed APK, you'll need to create at least an alpha release for your app, and that will allow you to test the Google Play Billing API locally on your device. The Google Billing API simply won't work if you don't have a release created for your app. And you'll also want to add your email address as a tester on that track. From there we'll go to the Store Presence tab, then to In App Products, and then go to Manage Products. Now on Google Play you don't actually select a distinction between consumable and non consumable, Instead, you handle that directly in the app. And we'll see how that works in the source code in just a minute. For now, we'll go ahead and create a new product with the same product ID that we used on iOS. Now make sure to set your product to active, and then everything else should be pretty self explanatory. Now that we have the initial setup out of the way, we can start developing our Flutter app. Now, I wanna start by saying that the code I'm about to show you focuses on the API of the in app purchases plugin. I want to keep the implementation details as unopinionated as possible, So I'm only using the tools that are built into Flutter, but this is a type of feature that could benefit from things like Provider, Block, or Firebase to manage the state of your purchases across multiple devices and screens. But I'll leave those decisions up to you. I just wanna show you how to build a minimum viable product using nothing but a stateful widget. The first thing we'll do is add the plugin to our Pubspec YAML, then we'll go ahead and import it in our Dart file along with IO so we can do platform checking. I'm calling this the market screen, and let's start by looking at the different properties or state available on this widget. First, we'll make a reference to the in app purchase connection instance, which gives us access to all of the API methods in the plugin. That'll just keep our code nice and concise. The first part of the initialization process is to check if the API is actually available on this device. Then we'll set up a list that keeps the product details that we query from the Google Play Store or the Apple App Store, and then also a set of purchase details that gives us the user's past purchases. Then we'll also set up a subscription that listens to a stream of updates to the purchase details. So this stream will emit a new value when the user buys a product in the app, or if they buy a product from a different client. And lastly, I have a placeholder for credits, which is just used to represent the consumable product in this demo. Now moving on to the life cycle hooks, during init state, we're going to fetch the products and purchases from the corresponding marketplace. And that stuff is all asynchronous, so we'll move it into its own method. And we also have a stream on this widget, so we'll want to make sure to cancel it. Now the next thing we'll look at is the actual UI itself, which is very simple in this case. We have a Scaffold with an app bar that will either display open for business or not available depending on whether or not the in Snap Purchases APIs available. From there, we'll loop over the products that we fetch from the marketplace. And then for each product, we'll need to determine if the user has a past purchase for it. If they have purchased a product, then we'll create some custom logic to allow them to consume it. Otherwise, we'll just go ahead and display a button that allows them to make a new purchase. This is just a bare minimum UI example, so you'll definitely want to customize it to fit within your own app. Now the next major hurdle that we'll tackle is initializing all of the data in this widget. We'll We'll do that with an async method called initialize that we call during the init state lifecycle hook. First, we'll check to see if the API is available, And then if so, we'll go ahead and retrieve the products and the users' past purchases. And I've moved that logic into individual private methods just so we get a clear picture of all the steps involved. And I'm sure someone will call me out on this, so instead of awaiting products and then awaiting purchases, you can do it concurrently by using Future Wait and add both of them together in a list. And that will run them concurrently for better performance. Now just because you have retrieved a purchase does not necessarily mean that it's valid. So we'll also need to implement some business logic to verify a purchase. And then throughout the lifecycle of the app, the user will hopefully purchase additional products, so we'll want to set up a subscription to the purchase updated stream. A stream will emit a list of newly created purchase details. So when the stream emits a new value, we can take those new purchases and then append them to the existing list on this widget. What you don't want to do is override the existing list because the stream only emits new purchases. So that's just something to keep in mind. So now let's look at the implementation details for this data retrieval. 1st, we get products, which is no different than making an API call or reading from a Firestore document. We just create a set of the product IDs that we want to retrieve from either the App Store or the Google Play Store, and then we run In App Purchases Query Product Details. That's going to give us a response, and then we can check that response for errors or to see if any of the product IDs are missing. But for the sake of simplicity, we'll call Set estate and set the products equal to the response product details. So that gives us our products for sale. Now we need to get the users past Purchases. This is a very similar process, but instead we call query past purchases. But there's one major caveat, and this method does not return consumed products. Because a consumed product can be purchased multiple times, it's not going to be returned by this method. That means you need to save the state of a consumed product in your database. That's the only way the user will be able to retrieve it after this widget has been destroyed. So getting past purchases from the actual marketplace itself is really only relevant for non consumable products. But one other caveat that you should know about is if you retrieve past purchases, you'll also want to mark them as complete on iOS. Now if you do have a consumable product, It will be 100% your own business logic to retrieve it. If this were my app, I would be using Firebase, so I would most likely retrieve it from the Firestore database. In any case, the final step here is to call SetState and set the Purchases list on this widget. Now the next thing we need to do is figure out if a user has purchased a specific product. In this case, I'm just going to create a helper method that takes a product ID as its argument, and then it loops through the purchases list to see if we have any matching IDs. If we have a match, then we'll go ahead and return the purchase details, otherwise, we'll return null. Now the next method is also going to be 100% your own business logic that will take a purchase and then actually deliver it in the app itself. In this demo, we only have a single product, so we're going to see if that user has purchased the product, And we'll also go ahead and make sure that that purchase is valid. The status can also be error or pending, so we wouldn't want to deliver the credits or the gems to the app if the user hasn't fully paid. You'll want to verify purchases both when the app is initialized and then also when a new purchase is emitted through that purchase updated stream. And you may even want to do that server side. So at this point we have all of the necessary data loaded into our widget, and now we need to give the user a way to purchase a product as well as consume a product. Inside of our products loop, we'll have access to individual product details, which we can then pass to this byproduct method to create a purchase param That will send the necessary data over to the corresponding marketplace. And then because Android doesn't make the distinction between consumable and non consumable, you need to do that when you purchase the product. So for one time purchases, you'll use Buy Non Consumable. But in our case, we want the user to buy this multiple times, so we'll say Buy Consumable. Now by default it will be marked as consumed automatically, which means it's up to your own business logic to control the state of that purchase. However, I would like to point out that you can set auto consume to false, which only applies to Android, and that will prevent the user from purchasing that product again until you actually mark it as consumed. And we can actually demonstrate how that works with our next method here called Spend Credits. It takes the purchase details as its argument and then it will decrement the credits on this widget every time the user taps to button. When the user runs out of credits or when they equal 0, we'll go ahead and tell the Google Play Store that that purchase has been consumed, and that will allow the user to purchase another instance of this product. Otherwise, they'll get an error that they already own this product. And that's all there is to it. We now have all the pieces in place to sell our users an infinite number of useless list gems, and we just need to refine our dopamine hits and compulsion loops to start making 1,000,000 of dollars per day. If this video helped you, please like and subscribe, and consider becoming a pro member on Fireship. Io to get access fizz to the Full Flutter course and a bunch of other exclusive content. Thanks for watching and I will talk to you soon.
In
in
2018,
2018
the
the
game
game
Candy
candy
Crush
crush
made
made
an
an
estimated
estimated
$4,000,000
$4,000,000
from
from
in
in
app
app
purchases
purchases
and
and
micro
micro
transactions
transactions
per
per
day.
day
And
and
like
like
most
most
of
of
the
the
top
top
grossing
grossing
mobile
mobile
apps,
apps
they
they
sell
sell
useless
useless
digital
digital
products
products
to
to
casual
casual
gamers.
gamers
In
in
today's
today's
video,
video
you'll
you'll
learn
learn
how
how
to
to
implement
implement
consumable
consumable
in
in
app
app
purchases
purchases
in
in
Flutter,
flutter
allowing
allowing
you
you
to
to
sell
sell
your
your
own
own
digital
digital
products
products
on
on
iOS
ios
or
or
Android
android
via
via
microtransactions.
microtransactions
Not
not
just
just
doing
doing
this
this
for
for
money.
money
We're
we're
doing
doing
it
it
for
for
a
a
shitload
shitload
money.
money
If
if
you're
you're
new
new
here,
here
like
like
and
and
subscribe,
subscribe
and
and
you
you
can
can
find
find
the
the
source
source
code
code
on
on
FireShip.
fireship
Io.
io
And
and
congrats
congrats
to
to
Andre
andre
Hava,
hava
he
he
won
won
the
the
t
t
shirt
shirt
from
from
last
last
week's
week's
sweater
sweater
video.
video
Let's
let's
start
start
by
by
talking
talking
about
about
how
how
in
in
app
app
purchases
purchases
work
work
from
from
a
a
high
high
level,
level
and
and
how
how
to
to
use
use
them
them
successfully
successfully
in
in
your
your
app.
app
The
the
first
first
thing
thing
you
you
should
should
know
know
is
is
that
that
there
there
are
are
3
3
main
main
types
types
of
of
in
in
app
app
fizz.
fizz
Consumables
consumables
are
are
products
products
that
that
are
are
depleted
depleted
that
that
can
can
be
be
purchased
purchased
multiple
multiple
times,
times
like
like
coins
coins
in
in
a
a
game.
game
Consumables
consumables
are
are
what
what
we're
we're
focused
focused
on
on
in
in
this
this
video,
video
and
and
we'll
we'll
build
build
a
a
feature
feature
that
that
allows
allows
the
the
user
user
to
to
buy
buy
some
some
gyms,
gyms
to
to
consume
consume
them
them
and
and
then
then
buy
buy
some
some
more.
more
The
the
second
second
type
type
is
is
a
a
non
non
consumable,
consumable
which
which
is
is
something
something
the
the
user
user
purchases
purchases
once
once
like
like
an
an
upgrade
upgrade
and
and
then
then
should
should
never
never
have
have
to
to
purchase
purchase
it
it
again
again
in
in
the
the
future.
future
And
and
the
the
3rd
3rd
type
type
is
is
a
a
subscription,
subscription
which
which
gives
gives
the
the
user
user
access
access
to
to
the
the
purchase
purchase
for
for
a
a
limited
limited
amount
amount
of
of
time.
time
Now
now
these
these
concepts
concepts
apply
apply
to
to
both
both
iOS
ios
from
from
Android,
android
but
but
there
there
are
are
some
some
subtle
subtle
yet
yet
important
important
differences
differences
that
that
we'll
we'll
look
look
at
at
when
when
we
we
get
get
into
into
the
the
code
code
in
in
a
a
few
few
minutes.
minutes
And
and
another
another
thing
thing
you
you
should
should
know
know
about
about
in
in
app
app
purchases
purchases
is
is
that
that
they're
they're
almost
almost
always
always
required
required
if
if
you're
you're
selling
selling
digital
digital
content.
content
That
that
means
means
APIs
apis
like
like
Stripe
stripe
and
and
PayPal
paypal
are
are
out
out
of
of
the
the
question.
question
But
but
luckily,
luckily
Flutter
flutter
just
just
recently
recently
released
released
an
an
officially
officially
supported
supported
plugin
plugin
for
for
in
in
app
app
purchases
purchases
that
that
provides
provides
a
a
unified
unified
interface
interface
across
across
iOS
ios
in
in
Android.
android
That's
that's
what
what
we'll
we'll
be
be
using
using
in
in
this
this
video,
video
but
but
it
it
is
is
currently
currently
in
in
beta,
beta
so
so
things
things
may
may
change
change
in
in
the
the
future.
future
Now
now
when
when
it
it
comes
comes
to
to
making
making
1,000,000
1,000,000
of
of
dollars
dollars
per
per
day,
day
you
you
need
need
to
to
build
build
an
an
app
app
that's
that's
fold
fold
highly
highly
addictive,
addictive
and
and
that
that
targets
targets
a
a
wide
wide
audience.
audience
I
i
wasted
wasted
everyone's
everyone's
money,
money
I
i
wasted
wasted
everyone's
everyone's
everything,
everything
and
and
I
i
feel
feel
bad.
bad
You
you
don't
don't
think
think
I
i
feel
feel
bad?
bad
You
you
should
should
design
design
your
your
interface
interface
around
around
dopamine
dopamine
hits
hits
and
and
compulsion
compulsion
loops.
loops
In
in
other
other
words,
words
reward
reward
the
the
user
user
on
on
a
a
regular
regular
basis,
basis
but
but
always
always
keep
keep
them
them
chasing
chasing
the
the
dragon.
dragon
Dad,
dad
get
get
off
off
our
our
Xbox.
xbox
Hang
hang
on,
on
I
i
almost
almost
cut
cut
the
the
dragon!
dragon
You
you
almost
almost
got
got
it!
it
No!
no
No
no
ice
ice
it!
it
I
i
am
am
your
your
father!
father
Put
put
it
it
back
back
hard!
hard
Mommy,
mommy
you
you
get
get
dad
dad
out
out
of
of
here.
here
So
so
now
now
that
that
you
you
know
know
how
how
to
to
design
design
your
your
app,
app
let's
let's
go
go
ahead
ahead
and
and
get
get
into
into
the
the
technical
technical
details.
details
The
the
first
first
thing
thing
we'll
we'll
take
take
care
care
of
of
is
is
the
the
initial
initial
setup
setup
for
for
both
both
iOS
ios
and
and
Android.
android
For
for
iOS,
ios
you'll
you'll
need
need
to
to
have
have
an
an
Apple
apple
developer
developer
account,
account
and
and
I'm
i'm
making
making
the
the
assumption
assumption
that
that
you
you
have
have
a
a
release
release
of
of
your
your
iOS
ios
app
app
on
on
App
app
Store
store
Connect.
connect
It
it
doesn't
doesn't
need
need
to
to
be
be
on
on
the
the
public
public
app
app
storage,
storage
just
just
App
app
Store
store
Connect,
connect
for
for
use
use
with
with
things
things
like
like
TestFlight.
testflight
There
there
are
are
a
a
lot
lot
of
of
small
small
but
but
easy
easy
steps
steps
involved
involved
with
with
that
that
that
that
are
are
beyond
beyond
the
the
scope
scope
of
of
this
this
video,
video
but
but
the
the
Flutter
flutter
documentation
documentation
has
has
a
a
detailed
detailed
guide
guide
for
for
preparing
preparing
an
an
iOS
ios
release,
release
and
and
I
i
also
also
have
have
a
a
video
video
that
that
covers
covers
it
it
in
in
my
my
full
full
Flutter
flutter
course.
course
In
in
App
app
Store
store
Connect,
connect
we'll
we'll
go
go
to
to
the
the
features
features
tab,
tab
add
add
a
a
new
new
in
in
app
app
purchase,
purchase
making
making
sure
sure
that
that
it's
it's
a
a
consumable
consumable
type.
type
Then
then
we'll
we'll
give
give
it
it
a
a
name
name
and
and
a
a
product
product
ID,
id
and
and
we
we
want
want
to
to
keep
keep
a
a
note
note
of
of
this
this
product
product
ID
id
because
because
we
we
want
want
that
that
to
to
be
be
the
the
same
same
on
on
the
the
Google
google
Play
play
Store.
store
And
and
everything
everything
else
else
is
is
just
just
the
the
pricing
pricing
and
and
display
display
details
details
for
for
your
your
actual
actual
product.
product
So
so
now
now
that
that
we
we
have
have
our
our
product,
product
we'll
we'll
go
go
into
into
Xcode
xcode
and
and
enable
enable
the
the
In
in
App
app
Purchases
purchases
capability.
capability
Select
select
the
the
build
build
target,
target
go
go
to
to
the
the
Capabilities
capabilities
tab,
tab
and
and
then
then
flip
flip
the
the
In
in
App
app
Purchases
purchases
switch
switch
to
to
On.
on
So
so
that
that
takes
takes
care
care
of
of
the
the
Apple
apple
App
app
Store.
store
Now
now
let's
let's
switch
switch
gears
gears
to
to
Android
android
and
and
the
the
Google
google
Play
play
Store.
store
At
at
this
this
point,
point
I'm
i'm
assuming
assuming
that
that
you
you
have
have
a
a
Google
google
Play
play
Developer
developer
account,
account
and
and
you'll
you'll
also
also
need
need
to
to
go
go
through
through
the
the
steps
steps
to
to
create
create
a
a
signed
signed
release
release
that
that
can
can
be
be
uploaded
uploaded
to
to
Google
google
Play.
play
And
and
once
once
again,
again
there
there
are
are
a
a
lot
lot
of
of
easy
easy
steps
steps
involved
involved
beyond
beyond
the
the
scope
scope
of
of
this
this
video,
video
so
so
refer
refer
to
to
the
the
Flutter
flutter
documentation
documentation
or
or
the
the
full
full
Flutter
flutter
course.
course
Once
once
you
you
create
create
the
the
actual
actual
signed
signed
APK,
apk
you'll
you'll
need
need
to
to
create
create
at
at
least
least
an
an
alpha
alpha
release
release
for
for
your
your
app,
app
and
and
that
that
will
will
allow
allow
you
you
to
to
test
test
the
the
Google
google
Play
play
Billing
billing
API
api
locally
locally
on
on
your
your
device.
device
The
the
Google
google
Billing
billing
API
api
simply
simply
won't
won't
work
work
if
if
you
you
don't
don't
have
have
a
a
release
release
created
created
for
for
your
your
app.
app
And
and
you'll
you'll
also
also
want
want
to
to
add
add
your
your
email
email
address
address
as
as
a
a
tester
tester
on
on
that
that
track.
track
From
from
there
there
we'll
we'll
go
go
to
to
the
the
Store
store
Presence
presence
tab,
tab
then
then
to
to
In
in
App
app
Products,
products
and
and
then
then
go
go
to
to
Manage
manage
Products.
products
Now
now
on
on
Google
google
Play
play
you
you
don't
don't
actually
actually
select
select
a
a
distinction
distinction
between
between
consumable
consumable
and
and
non
non
consumable,
consumable
Instead,
instead
you
you
handle
handle
that
that
directly
directly
in
in
the
the
app.
app
And
and
we'll
we'll
see
see
how
how
that
that
works
works
in
in
the
the
source
source
code
code
in
in
just
just
a
a
minute.
minute
For
for
now,
now
we'll
we'll
go
go
ahead
ahead
and
and
create
create
a
a
new
new
product
product
with
with
the
the
same
same
product
product
ID
id
that
that
we
we
used
used
on
on
iOS.
ios
Now
now
make
make
sure
sure
to
to
set
set
your
your
product
product
to
to
active,
active
and
and
then
then
everything
everything
else
else
should
should
be
be
pretty
pretty
self
self
explanatory.
explanatory
Now
now
that
that
we
we
have
have
the
the
initial
initial
setup
setup
out
out
of
of
the
the
way,
way
we
we
can
can
start
start
developing
developing
our
our
Flutter
flutter
app.
app
Now,
now
I
i
wanna
wanna
start
start
by
by
saying
saying
that
that
the
the
code
code
I'm
i'm
about
about
to
to
show
show
you
you
focuses
focuses
on
on
the
the
API
api
of
of
the
the
in
in
app
app
purchases
purchases
plugin.
plugin
I
i
want
want
to
to
keep
keep
the
the
implementation
implementation
details
details
as
as
unopinionated
unopinionated
as
as
possible,
possible
So
so
I'm
i'm
only
only
using
using
the
the
tools
tools
that
that
are
are
built
built
into
into
Flutter,
flutter
but
but
this
this
is
is
a
a
type
type
of
of
feature
feature
that
that
could
could
benefit
benefit
from
from
things
things
like
like
Provider,
provider
Block,
block
or
or
Firebase
firebase
to
to
manage
manage
the
the
state
state
of
of
your
your
purchases
purchases
across
across
multiple
multiple
devices
devices
and
and
screens.
screens
But
but
I'll
i'll
leave
leave
those
those
decisions
decisions
up
up
to
to
you.
you
I
i
just
just
wanna
wanna
show
show
you
you
how
how
to
to
build
build
a
a
minimum
minimum
viable
viable
product
product
using
using
nothing
nothing
but
but
a
a
stateful
stateful
widget.
widget
The
the
first
first
thing
thing
we'll
we'll
do
do
is
is
add
add
the
the
plugin
plugin
to
to
our
our
Pubspec
pubspec
YAML,
yaml
then
then
we'll
we'll
go
go
ahead
ahead
and
and
import
import
it
it
in
in
our
our
Dart
dart
file
file
along
along
with
with
IO
io
so
so
we
we
can
can
do
do
platform
platform
checking.
checking
I'm
i'm
calling
calling
this
this
the
the
market
market
screen,
screen
and
and
let's
let's
start
start
by
by
looking
looking
at
at
the
the
different
different
properties
properties
or
or
state
state
available
available
on
on
this
this
widget.
widget
First,
first
we'll
we'll
make
make
a
a
reference
reference
to
to
the
the
in
in
app
app
purchase
purchase
connection
connection
instance,
instance
which
which
gives
gives
us
us
access
access
to
to
all
all
of
of
the
the
API
api
methods
methods
in
in
the
the
plugin.
plugin
That'll
that'll
just
just
keep
keep
our
our
code
code
nice
nice
and
and
concise.
concise
The
the
first
first
part
part
of
of
the
the
initialization
initialization
process
process
is
is
to
to
check
check
if
if
the
the
API
api
is
is
actually
actually
available
available
on
on
this
this
device.
device
Then
then
we'll
we'll
set
set
up
up
a
a
list
list
that
that
keeps
keeps
the
the
product
product
details
details
that
that
we
we
query
query
from
from
the
the
Google
google
Play
play
Store
store
or
or
the
the
Apple
apple
App
app
Store,
store
and
and
then
then
also
also
a
a
set
set
of
of
purchase
purchase
details
details
that
that
gives
gives
us
us
the
the
user's
user's
past
past
purchases.
purchases
Then
then
we'll
we'll
also
also
set
set
up
up
a
a
subscription
subscription
that
that
listens
listens
to
to
a
a
stream
stream
of
of
updates
updates
to
to
the
the
purchase
purchase
details.
details
So
so
this
this
stream
stream
will
will
emit
emit
a
a
new
new
value
value
when
when
the
the
user
user
buys
buys
a
a
product
product
in
in
the
the
app,
app
or
or
if
if
they
they
buy
buy
a
a
product
product
from
from
a
a
different
different
client.
client
And
and
lastly,
lastly
I
i
have
have
a
a
placeholder
placeholder
for
for
credits,
credits
which
which
is
is
just
just
used
used
to
to
represent
represent
the
the
consumable
consumable
product
product
in
in
this
this
demo.
demo
Now
now
moving
moving
on
on
to
to
the
the
life
life
cycle
cycle
hooks,
hooks
during
during
init
init
state,
state
we're
we're
going
going
to
to
fetch
fetch
the
the
products
products
and
and
purchases
purchases
from
from
the
the
corresponding
corresponding
marketplace.
marketplace
And
and
that
that
stuff
stuff
is
is
all
all
asynchronous,
asynchronous
so
so
we'll
we'll
move
move
it
it
into
into
its
its
own
own
method.
method
And
and
we
we
also
also
have
have
a
a
stream
stream
on
on
this
this
widget,
widget
so
so
we'll
we'll
want
want
to
to
make
make
sure
sure
to
to
cancel
cancel
it.
it
Now
now
the
the
next
next
thing
thing
we'll
we'll
look
look
at
at
is
is
the
the
actual
actual
UI
ui
itself,
itself
which
which
is
is
very
very
simple
simple
in
in
this
this
case.
case
We
we
have
have
a
a
Scaffold
scaffold
with
with
an
an
app
app
bar
bar
that
that
will
will
either
either
display
display
open
open
for
for
business
business
or
or
not
not
available
available
depending
depending
on
on
whether
whether
or
or
not
not
the
the
in
in
Snap
snap
Purchases
purchases
APIs
apis
available.
available
From
from
there,
there
we'll
we'll
loop
loop
over
over
the
the
products
products
that
that
we
we
fetch
fetch
from
from
the
the
marketplace.
marketplace
And
and
then
then
for
for
each
each
product,
product
we'll
we'll
need
need
to
to
determine
determine
if
if
the
the
user
user
has
has
a
a
past
past
purchase
purchase
for
for
it.
it
If
if
they
they
have
have
purchased
purchased
a
a
product,
product
then
then
we'll
we'll
create
create
some
some
custom
custom
logic
logic
to
to
allow
allow
them
them
to
to
consume
consume
it.
it
Otherwise,
otherwise
we'll
we'll
just
just
go
go
ahead
ahead
and
and
display
display
a
a
button
button
that
that
allows
allows
them
them
to
to
make
make
a
a
new
new
purchase.
purchase
This
this
is
is
just
just
a
a
bare
bare
minimum
minimum
UI
ui
example,
example
so
so
you'll
you'll
definitely
definitely
want
want
to
to
customize
customize
it
it
to
to
fit
fit
within
within
your
your
own
own
app.
app
Now
now
the
the
next
next
major
major
hurdle
hurdle
that
that
we'll
we'll
tackle
tackle
is
is
initializing
initializing
all
all
of
of
the
the
data
data
in
in
this
this
widget.
widget
We'll
we'll
We'll
we'll
do
do
that
that
with
with
an
an
async
async
method
method
called
called
initialize
initialize
that
that
we
we
call
call
during
during
the
the
init
init
state
state
lifecycle
lifecycle
hook.
hook
First,
first
we'll
we'll
check
check
to
to
see
see
if
if
the
the
API
api
is
is
available,
available
And
and
then
then
if
if
so,
so
we'll
we'll
go
go
ahead
ahead
and
and
retrieve
retrieve
the
the
products
products
and
and
the
the
users'
users'
past
past
purchases.
purchases
And
and
I've
i've
moved
moved
that
that
logic
logic
into
into
individual
individual
private
private
methods
methods
just
just
so
so
we
we
get
get
a
a
clear
clear
picture
picture
of
of
all
all
the
the
steps
steps
involved.
involved
And
and
I'm
i'm
sure
sure
someone
someone
will
will
call
call
me
me
out
out
on
on
this,
this
so
so
instead
instead
of
of
awaiting
awaiting
products
products
and
and
then
then
awaiting
awaiting
purchases,
purchases
you
you
can
can
do
do
it
it
concurrently
concurrently
by
by
using
using
Future
future
Wait
wait
and
and
add
add
both
both
of
of
them
them
together
together
in
in
a
a
list.
list
And
and
that
that
will
will
run
run
them
them
concurrently
concurrently
for
for
better
better
performance.
performance
Now
now
just
just
because
because
you
you
have
have
retrieved
retrieved
a
a
purchase
purchase
does
does
not
not
necessarily
necessarily
mean
mean
that
that
it's
it's
valid.
valid
So
so
we'll
we'll
also
also
need
need
to
to
implement
implement
some
some
business
business
logic
logic
to
to
verify
verify
a
a
purchase.
purchase
And
and
then
then
throughout
throughout
the
the
lifecycle
lifecycle
of
of
the
the
app,
app
the
the
user
user
will
will
hopefully
hopefully
purchase
purchase
additional
additional
products,
products
so
so
we'll
we'll
want
want
to
to
set
set
up
up
a
a
subscription
subscription
to
to
the
the
purchase
purchase
updated
updated
stream.
stream
A
a
stream
stream
will
will
emit
emit
a
a
list
list
of
of
newly
newly
created
created
purchase
purchase
details.
details
So
so
when
when
the
the
stream
stream
emits
emits
a
a
new
new
value,
value
we
we
can
can
take
take
those
those
new
new
purchases
purchases
and
and
then
then
append
append
them
them
to
to
the
the
existing
existing
list
list
on
on
this
this
widget.
widget
What
what
you
you
don't
don't
want
want
to
to
do
do
is
is
override
override
the
the
existing
existing
list
list
because
because
the
the
stream
stream
only
only
emits
emits
new
new
purchases.
purchases
So
so
that's
that's
just
just
something
something
to
to
keep
keep
in
in
mind.
mind
So
so
now
now
let's
let's
look
look
at
at
the
the
implementation
implementation
details
details
for
for
this
this
data
data
retrieval.
retrieval
1st,
1st
we
we
get
get
products,
products
which
which
is
is
no
no
different
different
than
than
making
making
an
an
API
api
call
call
or
or
reading
reading
from
from
a
a
Firestore
firestore
document.
document
We
we
just
just
create
create
a
a
set
set
of
of
the
the
product
product
IDs
ids
that
that
we
we
want
want
to
to
retrieve
retrieve
from
from
either
either
the
the
App
app
Store
store
or
or
the
the
Google
google
Play
play
Store,
store
and
and
then
then
we
we
run
run
In
in
App
app
Purchases
purchases
Query
query
Product
product
Details.
details
That's
that's
going
going
to
to
give
give
us
us
a
a
response,
response
and
and
then
then
we
we
can
can
check
check
that
that
response
response
for
for
errors
errors
or
or
to
to
see
see
if
if
any
any
of
of
the
the
product
product
IDs
ids
are
are
missing.
missing
But
but
for
for
the
the
sake
sake
of
of
simplicity,
simplicity
we'll
we'll
call
call
Set
set
estate
estate
and
and
set
set
the
the
products
products
equal
equal
to
to
the
the
response
response
product
product
details.
details
So
so
that
that
gives
gives
us
us
our
our
products
products
for
for
sale.
sale
Now
now
we
we
need
need
to
to
get
get
the
the
users
users
past
past
Purchases.
purchases
This
this
is
is
a
a
very
very
similar
similar
process,
process
but
but
instead
instead
we
we
call
call
query
query
past
past
purchases.
purchases
But
but
there's
there's
one
one
major
major
caveat,
caveat
and
and
this
this
method
method
does
does
not
not
return
return
consumed
consumed
products.
products
Because
because
a
a
consumed
consumed
product
product
can
can
be
be
purchased
purchased
multiple
multiple
times,
times
it's
it's
not
not
going
going
to
to
be
be
returned
returned
by
by
this
this
method.
method
That
that
means
means
you
you
need
need
to
to
save
save
the
the
state
state
of
of
a
a
consumed
consumed
product
product
in
in
your
your
database.
database
That's
that's
the
the
only
only
way
way
the
the
user
user
will
will
be
be
able
able
to
to
retrieve
retrieve
it
it
after
after
this
this
widget
widget
has
has
been
been
destroyed.
destroyed
So
so
getting
getting
past
past
purchases
purchases
from
from
the
the
actual
actual
marketplace
marketplace
itself
itself
is
is
really
really
only
only
relevant
relevant
for
for
non
non
consumable
consumable
products.
products
But
but
one
one
other
other
caveat
caveat
that
that
you
you
should
should
know
know
about
about
is
is
if
if
you
you
retrieve
retrieve
past
past
purchases,
purchases
you'll
you'll
also
also
want
want
to
to
mark
mark
them
them
as
as
complete
complete
on
on
iOS.
ios
Now
now
if
if
you
you
do
do
have
have
a
a
consumable
consumable
product,
product
It
it
will
will
be
be
100%
100%
your
your
own
own
business
business
logic
logic
to
to
retrieve
retrieve
it.
it
If
if
this
this
were
were
my
my
app,
app
I
i
would
would
be
be
using
using
Firebase,
firebase
so
so
I
i
would
would
most
most
likely
likely
retrieve
retrieve
it
it
from
from
the
the
Firestore
firestore
database.
database
In
in
any
any
case,
case
the
the
final
final
step
step
here
here
is
is
to
to
call
call
SetState
setstate
and
and
set
set
the
the
Purchases
purchases
list
list
on
on
this
this
widget.
widget
Now
now
the
the
next
next
thing
thing
we
we
need
need
to
to
do
do
is
is
figure
figure
out
out
if
if
a
a
user
user
has
has
purchased
purchased
a
a
specific
specific
product.
product
In
in
this
this
case,
case
I'm
i'm
just
just
going
going
to
to
create
create
a
a
helper
helper
method
method
that
that
takes
takes
a
a
product
product
ID
id
as
as
its
its
argument,
argument
and
and
then
then
it
it
loops
loops
through
through
the
the
purchases
purchases
list
list
to
to
see
see
if
if
we
we
have
have
any
any
matching
matching
IDs.
ids
If
if
we
we
have
have
a
a
match,
match
then
then
we'll
we'll
go
go
ahead
ahead
and
and
return
return
the
the
purchase
purchase
details,
details
otherwise,
otherwise
we'll
we'll
return
return
null.
null
Now
now
the
the
next
next
method
method
is
is
also
also
going
going
to
to
be
be
100%
100%
your
your
own
own
business
business
logic
logic
that
that
will
will
take
take
a
a
purchase
purchase
and
and
then
then
actually
actually
deliver
deliver
it
it
in
in
the
the
app
app
itself.
itself
In
in
this
this
demo,
demo
we
we
only
only
have
have
a
a
single
single
product,
product
so
so
we're
we're
going
going
to
to
see
see
if
if
that
that
user
user
has
has
purchased
purchased
the
the
product,
product
And
and
we'll
we'll
also
also
go
go
ahead
ahead
and
and
make
make
sure
sure
that
that
that
that
purchase
purchase
is
is
valid.
valid
The
the
status
status
can
can
also
also
be
be
error
error
or
or
pending,
pending
so
so
we
we
wouldn't
wouldn't
want
want
to
to
deliver
deliver
the
the
credits
credits
or
or
the
the
gems
gems
to
to
the
the
app
app
if
if
the
the
user
user
hasn't
hasn't
fully
fully
paid.
paid
You'll
you'll
want
want
to
to
verify
verify
purchases
purchases
both
both
when
when
the
the
app
app
is
is
initialized
initialized
and
and
then
then
also
also
when
when
a
a
new
new
purchase
purchase
is
is
emitted
emitted
through
through
that
that
purchase
purchase
updated
updated
stream.
stream
And
and
you
you
may
may
even
even
want
want
to
to
do
do
that
that
server
server
side.
side
So
so
at
at
this
this
point
point
we
we
have
have
all
all
of
of
the
the
necessary
necessary
data
data
loaded
loaded
into
into
our
our
widget,
widget
and
and
now
now
we
we
need
need
to
to
give
give
the
the
user
user
a
a
way
way
to
to
purchase
purchase
a
a
product
product
as
as
well
well
as
as
consume
consume
a
a
product.
product
Inside
inside
of
of
our
our
products
products
loop,
loop
we'll
we'll
have
have
access
access
to
to
individual
individual
product
product
details,
details
which
which
we
we
can
can
then
then
pass
pass
to
to
this
this
byproduct
byproduct
method
method
to
to
create
create
a
a
purchase
purchase
param
param
That
that
will
will
send
send
the
the
necessary
necessary
data
data
over
over
to
to
the
the
corresponding
corresponding
marketplace.
marketplace
And
and
then
then
because
because
Android
android
doesn't
doesn't
make
make
the
the
distinction
distinction
between
between
consumable
consumable
and
and
non
non
consumable,
consumable
you
you
need
need
to
to
do
do
that
that
when
when
you
you
purchase
purchase
the
the
product.
product
So
so
for
for
one
one
time
time
purchases,
purchases
you'll
you'll
use
use
Buy
buy
Non
non
Consumable.
consumable
But
but
in
in
our
our
case,
case
we
we
want
want
the
the
user
user
to
to
buy
buy
this
this
multiple
multiple
times,
times
so
so
we'll
we'll
say
say
Buy
buy
Consumable.
consumable
Now
now
by
by
default
default
it
it
will
will
be
be
marked
marked
as
as
consumed
consumed
automatically,
automatically
which
which
means
means
it's
it's
up
up
to
to
your
your
own
own
business
business
logic
logic
to
to
control
control
the
the
state
state
of
of
that
that
purchase.
purchase
However,
however
I
i
would
would
like
like
to
to
point
point
out
out
that
that
you
you
can
can
set
set
auto
auto
consume
consume
to
to
false,
false
which
which
only
only
applies
applies
to
to
Android,
android
and
and
that
that
will
will
prevent
prevent
the
the
user
user
from
from
purchasing
purchasing
that
that
product
product
again
again
until
until
you
you
actually
actually
mark
mark
it
it
as
as
consumed.
consumed
And
and
we
we
can
can
actually
actually
demonstrate
demonstrate
how
how
that
that
works
works
with
with
our
our
next
next
method
method
here
here
called
called
Spend
spend
Credits.
credits
It
it
takes
takes
the
the
purchase
purchase
details
details
as
as
its
its
argument
argument
and
and
then
then
it
it
will
will
decrement
decrement
the
the
credits
credits
on
on
this
this
widget
widget
every
every
time
time
the
the
user
user
taps
taps
to
to
button.
button
When
when
the
the
user
user
runs
runs
out
out
of
of
credits
credits
or
or
when
when
they
they
equal
equal
0,
0
we'll
we'll
go
go
ahead
ahead
and
and
tell
tell
the
the
Google
google
Play
play
Store
store
that
that
that
that
purchase
purchase
has
has
been
been
consumed,
consumed
and
and
that
that
will
will
allow
allow
the
the
user
user
to
to
purchase
purchase
another
another
instance
instance
of
of
this
this
product.
product
Otherwise,
otherwise
they'll
they'll
get
get
an
an
error
error
that
that
they
they
already
already
own
own
this
this
product.
product
And
and
that's
that's
all
all
there
there
is
is
to
to
it.
it
We
we
now
now
have
have
all
all
the
the
pieces
pieces
in
in
place
place
to
to
sell
sell
our
our
users
users
an
an
infinite
infinite
number
number
of
of
useless
useless
list
list
gems,
gems
and
and
we
we
just
just
need
need
to
to
refine
refine
our
our
dopamine
dopamine
hits
hits
and
and
compulsion
compulsion
loops
loops
to
to
start
start
making
making
1,000,000
1,000,000
of
of
dollars
dollars
per
per
day.
day
If
if
this
this
video
video
helped
helped
you,
you
please
please
like
like
and
and
subscribe,
subscribe
and
and
consider
consider
becoming
becoming
a
a
pro
pro
member
member
on
on
Fireship.
fireship
Io
io
to
to
get
get
access
access
fizz
fizz
to
to
the
the
Full
full
Flutter
flutter
course
course
and
and
a
a
bunch
bunch
of
of
other
other
exclusive
exclusive
content.
content
Thanks
thanks
for
for
watching
watching
and
and
I
i
will
will
talk
talk
to
to
you
you
soon.
soon
success
In App Store purchases are a way for users to access a limited amount of time and can be purchased multiple times. Subscription is a way for users to access a limited amount of time and can be purchased with a minimal viable product. A widget for the in-the-door purchase process is created, including checking the status of a purchase and the implementation of business logic to verify purchases. A demo is provided to show the widget and viewers can subscribe to the Flutter course.
In App Purchases in Flutter
Learn how to setup In App Purchases in Flutter to sell 💎 consumable digital products for real money 🤑 on iOS and Android https://fireship.io/lessons/flutter-inapp-purchases/

- Flutter IAP plugin https://github.com/flutter/plugins/tree/master/packages/in_app_purchase
- Apple App Store Release https://flutter.dev/docs/deployment/ios
- Google Play Release https://flutter.dev/docs/deployment/android

#flutter #ios #android

Don't forget to take the quizzes 🤓

iOS https://itunes.apple.com/us/app/fireship/id1462592372?mt=8
Android https://play.google.com/store/apps/details?id=io.fireship.quizapp

Upgrade to Fireship PRO at https://fireship.io/pro
Use code lORhwXd2 for 25% off your first payment.