flutter / flutter

Flutter makes it easy and fast to build beautiful apps for mobile and beyond

Home Page:https://flutter.dev

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Would like a plugin for In-App Payments (IAP)

eseidelGoogle opened this issue · comments

Or at least help building one. Requested by @lukef

commented

Second this. For monetization purposes we need both IAP and ad support. These are both are really critical to getting traction for flutter in the developer community.

@saads thanks for the feedback!

commented

@sethladd no worries! Any road map for this? Or any way I can help to accelerate bringing in app purchases to Flutter? Got an urgent need for it and really want to be able to use the platform because it's so helpful with accelerating development. Let me know! :)

We have no ETA on writing this plugin ourselves. However you can always just use normal iOS or Android APIs or SDKs from the Objective-C/Java parts of your app and then communicate to the Flutter parts via https://flutter.io/platform-channels/.

This bug is about bundling those bits up so that folks can use common payment APIs w/o having to write any Objective-C/Java code themselves, which means taking that code you could write above, but then also bundling it up into a https://flutter.io/platform-plugins/ container.

commented

I made an iOS implementation https://github.com/JackAppDev/flutter_iap/ if someone wants to help me out by adding android support that would be great.

Thanks very much for the iOS implementation!

commented

Tentatively closing this. The plugin @JackAppDev created seems to support iOS and Android.

Note that IAP (in-app payment) functionality (such as in the flutter_iap plugin) is a subset of Apple Pay used for selling digital goods of which Apple takes a 30% cut. This plugin is not useful for an app that sells physical goods or services and simply uses Apple Pay as a simpler alternative to credit card input.

Linking a plugin I am working on that features non-consumable products for iOS and Android with products caching and purchases restoration.

@JackAppDev would it be possible to get @frederickcook's post in your README.md for your plugin? Would make it clear to anyone using your plugin that Apple will take a 30% cut.

Renaming this back to In-app Purchases (as it started originally). I logged #17837 to track physical good transactions. If you would like that support, please vote (using the thumbs-up button) over in that issue.

We expect the present plugin to wrap the following APIs:

Android: Google Play Billing
https://developer.android.com/google/play/billing/billing_overview

iOS: In-App Purchase
https://developer.apple.com/in-app-purchase/

@mit-mit do you have a tentative release date for the plugin?

Sorry I don't, we had a bit of a change on the personnel side here.

No problem @mit-mit.

What do you guys think is the better approach now to receive iOS/Android payments? We need to offer auto-renewable subscriptions to users on both platforms. The above plugins works for that or do you think platform channel approach is the way? Appreciate.

Yes, I think platform channels should work great for this.

Rubber is about to hit the road and I need support for IAP. Are there any options available or am I stepping away from Flutter for a few months while it matures?

Adding my 2 cents here, IAP is a must have plugin which should be managed by the flutter team. There are plugins which works partially... but don't provide enough informations for validate iap on server side. IAP is critical on both side, customer & developer.

Yeah, I hate to "second" this, but I'm looking around and I haven't found an IAP plugin yet that is ready for use. I have invested considerable hours into writing this Flutter app and if I cannot monetize it with subscription IAPs I'm kinda up a creek. I cannot make my own because I'm using Flutter so I don't have to learn native development. And AdMob is not an appropriate monetization method for this app.

commented

It's doable today (as @mit-mit says) using platform channels. You just have to write the code yourself. It's decently trivial to do so. There probably won't be a plug-in in a short time frame but I can't speak for Google 😀

@lukepighetti - I know you said you are using flutter so you don't have to learn native. I don't think the intention of flutter is to ever fully eliminate native. The two (primary) ecosystems are too rich and too different to ever acheive that. My advice is to learn the little you need. Flutter is a powerful tool that eliminates a massive amount of redundancy while still providing native "hooks". Over time there may be plugins for everything but we aren't there yet.

There are two packages that appear to be prime for community development. One has Subscriptions flutter_payments and the other flutter_iap seems to have more community use, hard to say from here.

I will be attempting to use flutter_payments tomorrow to handle subscriptions.

@lukef I totally see the benefit to learning native, but at the beginning of my mobile journey it's not an option yet. Maybe in the future!

@lukef yes indeed, it's doable... and I would even say: easily doable to have something working. In the past I made several Native Extensions code (equivalent to Flutter's platform channel but for Adobe AIR).
But my main concern is IAPs are one of the most critical part of an app, regarding payment process for the customer (with restoring purchase, subscription...), and validation of the payment from developer point of view. It's not just calling some native code... but to be sure all the process works well and in several cases. We already had strange bugs in ANEs.
In the Adobe AIR community, this plugin is sold by companies with proper documentation & support. I wouldn't mind paying some bucks here too for this flutter plugin. Obviously, it would be even better to have it from flutter team directly as an open source plugin.

@alamboley This is certainly on our list, just hasn't reached the top yet. Right now all of our plugin-focused engineers are busy working on Maps, WebView and Add-flutter-to-an-existing-application workflows. We're also hiring as fast as we can: https://twitter.com/_eseidel/status/1012025593628512256 :)

You can hire me to be lead cheerleader and liaison for newbie RN devs trying to use Flutter! 💃

You can use this plugin for basic non consumable products. I had to create it for my app. https://pub.dartlang.org/packages/flutter_billing

commented

I've just created one here to support features like subscription.
Actual url: https://github.com/dooboolab/flutter_inapp_purchase

Wow @dooboolab , I dreamed a port of your React Native iap plugin to flutter! Will test it asap!

commented

@alamboley Thanks. I need more time for testing tough. Will do it as much as I can taking my time.

So after some test & help, I can say we finally have an awesome flutter plugin for iap. Many many thanks to @dooboolab!

@dooboolab has saved this community as far as I am concerned. I just tested consumable on iOS and Android and it works awesome. I considered porting your package over but it was not the right task for me. So glad to see you have taken it upon yourself to complete.

Since we now have a community-contributed IAP plugin, do we still need to keep this issue open?

What's the verdict from people that have tested the plugin -- does it cover what they need?

It would be great to have solid official implementation for IAP. All current plugins are not complete and lack testing. It's really sad that flutter monetization options are so complicated and limited.

Basically now it's not possible to have all IAP options in a secure and stable way.

Tested following plugins:

https://github.com/VolodymyrLykhonis/flutter_billing

+ Version 0.2.3 is stable for simple purchases + receipts.
- later versions include consumables and android subscriptions. However also some bugs and crashes.
- needs ios subscriptions, slow development.

https://github.com/dooboolab/flutter_inapp_purchase

+ This plugin works great locally on test devices, and great features set. Suppose to have it all.
+ fast development.
- no receipts for already purchased products
- lots of crashes in Google Play console from live users.

https://github.com/JackAppDev/flutter_iap

- only lightly tested. Not enough features in the description.

I think that's all your options now. Still no perfect plugin

commented

@opensourcegps Trying to solve the crashing report in the console as soon as possible. What version of flutter_inapp_purchase are you using? I'll follow up in here.

@opensourcegps I am using flutter_inapp_purchase (just finished Alpha/Beta and releasing prod this week) with iOS and Android doing consumable purchases and auto-renewable subscriptions and haven't had any issues with any of the things you're mentioning. As a note, I am a contributor on the project.

commented

Yeah. I thought it was resolved currently.

@dooboolab @lukepighetti I really appreciate your work, your plugin looks awesome, thank you for creating it and contributing. I just listed my experiences with flutter IAP.

Regarding the fix, it was done with this commit: dooboolab-community/flutter_inapp_purchase@0afa99d

So in case problem was real, it's now hidden forever with try/catch. Will it still affect sales? Nobody knows. However if answer is Yes, you can imagine consequences for flutter community. If you miss 10% of sales and there are no errors, it's much worse.

Creating official implementation by Google will really help here.

In this case I must agree. Such 'fixes' shouldn't exist in payments library.
IAP is most critical functionality. Clients are very sensitive to issues/bugs which are related to purchases and money. I would expect rock solid quality official library.

I was in both of your positions and found flutter_inapp_purchase to be the closest of all implementations to being usable. I too would like Google to offer something rock solid and cohesive, but until they are willing to do that, which seems like it's going to be a long time, putting our money where our mouth is and improving flutter_inapp_purchase is, in my opinion, the best use of community efforts around IAPs.

You pointed out a perfect candidate for a pull request, and I'm sure @dooboolab is not arrogant enough to think his package is perfect. If it were perfect I wouldn't have made a contribution and we wouldn't be having this discussion.

So as far as @InMatrix question goes. No, I don't think this should be closed. IMHO Google needs to support their ecosystem with a solid IAP plugin regardless of what the community does. Their top priority should be enabling cash flow into Flutter development. But until that happens, contributions are not only welcome, but in my mind necessary, for the community to support itself. If not flutter_inapp_purchase, than another package.

I can't speak for others but flutter_inapp_purchase totally bailed my project out and so I shall contribute until Google steps up and offers their own official IAP plugin.

Hi All, I'm author of one the plugins listed here flutter_billing. I would like to explain "slow development". Since there is a commitment from Flutter team to provide such plugin, I have frozen development from my side but any contributions are welcomed.

Instability was introduced by recent commits to flutter_billing plugin.

commented

@opensourcegps It isn't anything but I am trying to be more informative with the earlier issue. The issue you've described above is a matter of handling bridge. I bet @lukepighetti didn't had that problem in earlier version either. You should check yourself when you invoke your methods, with some suspicions where the problems may occur. If you see something there, you could report that in issue.

I was just trying to fix crashing for whatever reason. However, if you use some error tracking platform like sentry, you will be able to grab that error message and you won't get totally blind with this. I was sure that it was much better than just crashing even though I've not experienced this in my app.

Let's make this better together. I think we are not that behind.

@dooboolab No complains to "fix crashing for whatever reason". It was just to demonstrate why we need official IAP plugin from Google.

@eseidelGoogle if you could give us some timeline/ETA for official IAP plugin, that would be awesome. This is such a critical plugin to switch current apps to flutter, but instead we got things like "firebase_remote_config".

Maybe it's planned in 1 month and all community developers/contributors will just waste their time with their own plugins at the moment.

I would also like to know what the deal is. If Google is working on this and plans on releasing it soon, community can work on other things.

I agree that facilitating easy monetization of apps is important. I'm not aware of anyone from my team working on this issue at this time. We actively track upvoted issues from the community, as well as Flutter user survey results to aid with our work prioritization. Hopefully as we complete higher priority requests we'll be able to help here as well. Thankfully, as others noted, there are several in-progress solutions from others in the (awesome) Flutter community already.

CC @cbracken @bparrishMines for awareness.

As an update flutter_billing plugin v0.2.5 now supports most of the stuff, except iOS subscriptions.

@eseidelGoogle The problem with the upvotes-get-fixed approach is it rewards issues that have the most views which are not necessarily the most pressing. I would argue that monetization has become more important since Google announced that Beta was production ready.

@lukepighetti The upvotes list is just one of many prioritization inputs we have to balance. :/ But it is an important one. It's one of the ways we seek to balance the needs of the Flutter users we can directly here from (large companies, teams at Google, etc.) vs. the many many users of Flutter who we don't directly speak to. It's imperfect, but it's something, I hope.

commented

Agreed that having an official flutter payments plugin is critical

I've started work on an official IAP plugin. It's not ready to be used yet, but it would be great to get some eyes on it to see if the general architecture fits your usecase! I've opened #24540 to track feedback on it.

For those who are still looking for alternatives, here is my take on this: https://pub.dartlang.org/packages/iap

@zoechi @mklim can we get an ETA for when this package will be available? 1 week? 1 month? 3 months?

In general it's very difficult to make predictions about the future. But all Flutter work is done in the public (on GitHub), so following bugs like this one you'll see all the changes being made in this space as soon as they're made.

I second other people's comments that having an official IAP plugin from Google would inspire confidence in adopting the platform. The risk of not having a stable and reliable monetization feature is a big stopper for considering adoption of the platform. 👍 Nice to see work done in #24540 toward this effort.

(I set the milestone for a minimal viable product version of the plugin; after that we expect to have more to add, but we'll do that as additional later work in other bugs.)

This is taking more time than we originally estimated so I'm adjusting the milestone. Thank you everyone for your patience.

This is now available in beta: https://pub.dartlang.org/packages/in_app_purchase. Thanks everyone for waiting! Please file any feedback as new issues on the tracker.

@mklim sorry if this is not the correct place to ask this, I was just wondering about the background to having a global event-emitter and having the purchase methods not return anything. To me it seems like a much more natural API to have e.g. buyNonConsumable return a Future<PurchaseDetails>. This is indeed also how the other IAP Flutter plugins behave.

The drawbacks for me is that it forces me to split up the logic around my IAPs into different parts of the app, and makes it harder to reason about the flow of the purchase. E.g. I have a page that handles signup which requires a subscription. That page then needs to create an account with our backend, to which it also sends the receipt id from the subscription.

Now I need to coordinate two different pieces of information from two parts of the app. 1) the user details from the page state, and 2) the purchase id from the global listener.

Had buyNonConsumable instead returned the PurchaseDetails this would be very simple:

onPressed: () async {
  final purchaseDetails = await InAppPurchaseConnection.instance.buyNonConsumable(...)
  await FoobarApiClient.instance.signup(_emailController.text, purchaseDetails.verificationData)
}

Is the current API designed and thought out, and it's actually the better way for some reason, or was it implemented this way because it was the easiest to get thru the door quickly? If the latter, I would be happy to submit PRs to help on this, since I would like to use this in my app ☺️

Just another flutter user here with some thoughts on this: the global listener allows us to listen for events coming from the App Store itself. Which you’d require a background listener regardless of having a future option, making the future you’re proposing a bit redundant. I don’t think you are forced to put the logic in two places, though you are a bit more forced to use something like scopedmodel or bloc. I am placing my listener at the top of my tree in a stateful widget that’s attached to a scopedmodel and this is where I’m handling all of my IAP logic. I have a feeling they choose to do it this way to help force developers to work in a manner similar to this while also choosing the solution that allows for you to listen to the app stores for whether or not you’ve marked the purchase as completed even if the app crashes, which is needed by apple.

Good job, team Flutter!

[...] making the future you’re proposing a bit redundant.

I personally don't feel that it makes it redundant. In most cases, resuming an interrupted purchase is a different flow than when making a new purchase. E.g. in my case, resuming an interrupted purchase would involve asking the user for the signup details again, since if the app crashed I won't have them.

I don’t think you are forced to put the logic in two places, though you are a bit more forced to use something like scopedmodel or bloc.

That could absolutely work, but it's quite a lot more work than just await-ing a Future. While using e.g. the BLoC pattern is certinely good in many apps, I don't think that plugins should conform themselves to a specific pattern. It seems like there should be easy to implement the BLoC pattern even if buyNonConsumable returned a future with purchase details.

I have a feeling they choose to do it this way to help force developers to work in a manner similar to this [...]

If this was indeed a deliberate decision to force developers to use the plugin in a particular way, I think that we should add documentation for that to make it clear how we're expected to use it. I'm still not sure I'm understanding how to implement crash-resistance, and what events will be emitted if my app crashes during a purchase. If this is as you say "needed by apple" I think it's even more important to document it, so that developers (including me ☺️) knows how to properly implement this.

Good job, team Flutter!

Totally agree, I'm very happy for both Flutter and this plugin! Just trying to see if I can help out lowering the barrier for developers to use this plugin ☺️

I don't know what led Flutter team to this approach, but this is not what I expected. In my conception, Streams are preferable when you are supposed to receive lots of responses that update the screen accordingly and do not block user experience. In this case, you are making a request and the user is supposed to continue to use the app only when the response arrives.
IAPs are pretty simple and straightforward, I cannot see the need to separate the request and response in two different places, unless the developers had no other option, which I think is not the case, since other similar plugins do use Futures.

The interruption was a side note but you’ll still need a global listener for when users make a purchase within the store itself. That’s the part that seemed redundant since that should be the same flow as a direct purchase and you’d need user details there as well.

The requirement by apple is in the documentation when you look in the files themselves. It’s where I found out about the requirement.

My point if it was designed to force a specific pattern was pure speculation. It just seems like something you should do for a flow that can handle any events that could potentially happen in one place. This means you can also catch when a user changes their subscription. Another thing you’d need a listener for.

Thanks all, I responded over in #32423. This issue is already pretty long and was originally just tracking the existence of the plugin at all, so I think it would be better to have new specific discussions about the actual plugin in new and separate issues so they're easier to follow and track. Feel free to cc me directly on them too.

This thread has been automatically locked since there has not been any recent activity after it was closed. If you are still experiencing a similar issue, please open a new bug, including the output of flutter doctor -v and a minimal reproduction of the issue.