Stripe Checkout in Flutter Web

by Oct 2, 2020Flutter18 comments

Flutter Web is getting more mature every day. I believe it’s about the time we should start focusing on migrating all the Flutter mobile knowledge to the browser environment. In that spirit, after writing an article on using Stripe Checkout in mobile Flutter apps, I think I should also show you how to easily collect payments on the web and that’s what this article is about.

This article is a continuation of Stripe Checkout in mobile Flutter apps. You may want to read the previous one to get the most of it. 

. . .

Why is it different from mobile?

You may be thinking “Why can’t I just use the code from the previous post and deploy it on the web? It should work, right?”

Well, there is one big reason and one minor reason for that:

  1. The big one is that on mobile we were using WebView package for displaying the checkout page. This package doesn’t support Web so that is a party-stopper for us. Besides, why would we use WebView, when we are already on the web?
  2. The other reason is that we have been using a “server stub” to act a as fake server creating the session. If we run our flutter web app locally, we cannot do https request (as far as I know) and Stripe only accepts those kind requests for creating sessions. Because of that, we will modify our workflow to use client-only integration which is a way to collect payments without the backend server.

. . .

Calling JS functions without webview

As you may remember, to use Stripe Checkout, we need to call JavaScript function redirectToCheckout from the Stripe library. On mobile, we used webviewController.evaluateJavaScript for that, on the web we will use library named js.

For me, this library works like magic, we can use @JS() annotations to create Dart classes that will be used as javascript classes in the running app. Honestly, I still have no idea how it works but it does so we will stay with it. ? First, we need to see what we would have to do in normal HTML/JS environment according to Stripe documentation:

Stripe client-only docs

The easiest part is copying <script src="https://js.stripe.com/v3/"></script> to index.html. You can find it in the web directory of your Flutter project. Just copy that line inside <head>.

Now we need to analyze what are the classes provided in the Stripe library. First, there is a Stripe class that has a constructor accepting the key and the redirectToCheckout method which contains some parameters. What we have to do is to create a Dart class that has the same contract as this one:

Notice that we don’t implement anything. We’re just creating a dummy Dart class and annotate it with @JS. This will cause a running Flutter app to create a JavaScript Stripe object coming from the package we previously added in index.html.

? Ok, but what are CheckoutOptions and how will Stripe know how to process them?

It’s just another class that will represent data needed by Stripe library. We are using them to determine products we want to sell, what time of payment we will accept and where to redirect in cases of success or cancellation.

Besides @JS annotation, we are also using @anonymous because in JS example from the docs you can see, that there are no class names, just anonymous objects with fields.

? Alright, we have created a few weird-looking classes that don’t really do anything. How do we use them?

The same you use any Dart code! The Dart-JS mapping will happen without you doing anything more!

Technically, that’s all. This code when run on Flutter Web should redirect you to the Stripe Checkout page. After succeeding it will then redirect you to a specified URL. In our case it’s http://localhost:8080/#/success.
Obviously, it’s better to not redirect to the localhost in the production app and point to a nice and fancy domain. ?

On button click, we will call redirectToCheckout and that how it should look like:

. . .

One codebase for all platforms

In this post, I showed you how to do stripe checkout which will work only on the web. In the previous one, it worked only on mobile. I think it might be a good idea to show you how to make it work on both platforms at the same time.

The crucial problem to overcome is that we cannot use JS library on mobile. We can’t even import it! In order make it work, we need to create a file that will conditionally import mobile or web packages depending on the platform it’s run on. It can look like this:

What happens here is the first redirectToCheckout method tries to import stripe_checkout_stub.dart but if it’s run on mobile, it will use stripe_checkout_mobile.dart instead and on the web, it will use stripe_checkout_web.dart instead. Therefore the stub method should never be called. The mobile and web implementations are the ones created in this and previous post.

. . .

And that’s it!

Now we can accept payments on all platforms ?

As always, the whole code is on the Github [here].
The YouTube version is [here].
If you missed part 1, be sure to see Stripe Checkout on mobile.

And if you want to learn more about Stripe Checkout, the official docs are very well written.

If you have any questions or ideas for improvements, let me know in the comments!

Cheers! ?

Marcin Szałek

Founder of Fidev

Flutter enthusiast since Alpha release in 2017. Believes that sharing is caring, which lead him to start a technical blog dedicated fo Flutter in its early days. Loves to see beautiful designs become real apps and is willing to help make it happen. Enjoys sunny beaches far from home.

Join the newsletter!

Join the newsletter to keep track with latest posts and get my special Widget to animate views' entrances without any hassle for FREE!

Check out other posts!

Stripe Checkout in mobile Flutter app

Stripe Checkout in mobile Flutter app

Have you ever struggled to integrate card payments into your mobile Flutter app? If so, today is your lucky day! In this post, I present how to use Stripe Checkout in the Flutter app without any hassle!

Interacting with Widgets using Framy

Interacting with Widgets using Framy

Have you ever developed a widget or a page and you wanted to make sure it works correctly in different scenarios but then it turned out that you can’t just reproduce all the cases you want to cover? Framy may solve such problems!

Water Drop effect in Flutter

Water Drop effect in Flutter

In this post, I’d like to share with you how to achieve a water drop effect in Flutter. Why would you spend your time learning such skill? Well, I have no idea but it looks cool so let’s get started! ?

Share This

Share This

Share this post with your friends!