Stripe payment system in Flutter

In this article, I’ll show you how to implement card payment with Stripe in Flutter. We’ll be using the “stripe_payment” package.

Jaka Rizmal
4 min readJul 31, 2020
Photo by Avery Evans on Unsplash

What you need

Here are some things you’ll need first.

A Stripe account

You’ll need to create a Stripe account. It’s super simple. We’ll be using their testing environment for now.

A server

You’ll need to create some kind of a web server. In this article I’ve used Node.js. We’ll only be creating a single endpoint. You could also use a cloud function or something similar.

You also need a corresponding Stripe library.

Getting started

We’ll be roughly following Stripe’s payment intent flow as seen on the image below. As you can see, there are 4 entities involved in this flow.

The customer is the user of your app,
the client is your Flutter app,
the server is your backend
and Stripe is Stripe (their backend).

https://stripe.com/docs/payments/accept-a-payment

And this is how that flow looks in Flutter code. Don’t worry, I’ll explain it later on.

Flutter Stripe package

We need to add the “stripe_payment” package to the pubspec.yaml file. Before we start using the library, we need to initialize it, as seen below.

We need to provide the publishable key, which is found on the Stripe dashboard.

Payment intent

First, we need to create a payment intent. In the above code you can see that I’ve created a function called “_createIntent” which is used to do just that.

The intent is created on our backend server. I’ve created an endpoint used to do just that. In Flutter, we call this endpoint and save the response. I am using Dart’s http package to issue a POST request to that endpoint. The response is then converted to a Map with “json.decode” and then, a “PaymentIntent” object is created using the “client_secret” from the response. “client_secret” is actually the only information we need from the server, so you could optimize the process by only sending back this field.

Here’s how that endpoint looks like. I am using Node.js as it’s quite quick to set up but Stripe library supports many languages so use which ever one you like.

You’ll usually send some extra information in the request, so you can identify why the payment is coming (order_id, user_id or something similar). You can also send the charge amount, but I would not recommend that, as clients should not really be trusted. Instead, calculate the price in this endpoint. In this example I’ve used a fixed amount of $14.95 (the prices are in cents).

Collecting card details

Now we need to ask user for payment info. Luckily the process is very simple as the library provides the card input form.

This code first shows the card input form. The user then inputs the card details and clicks save. That info is then sent to Stripe and a “PaymentMethod” object is created.

We must then associate this payment method with previously created intent. You can see that in the 7th line. The only thing we must do now, is to confirm the payment.

Confirm payment

We now have all the data we need to confirm the payment.

When the payment is confirmed, we get back a “PaymentIntentResult” object. We need to check its’ “status” property to see if everything went ok. If the status is “succeeded” we know that the payment went through. Feel free to check for other statuses as well.

Error catching

This flow may throw multiple exceptions so I suggest wrapping it in a try/catch block. In my code I also handled “PlatformException” separately. This exception is thrown for example if the user exits the card input form. Feel free to experiment with this as it can bring valuable information for user experience.

Demo

I’ve created a simple page that shows this in real world. Here’s the UI code (it’s a stateful widget).

When the button is pressed, the flow gets triggered which then changes the background color. But because a picture is worth a thousand words (a gif even more I believe), here’s a preview.

I’m using the “test card” number. This card will always be accepted. You can put in any expiration date and CVC you want.

That’s it

You should now be able to accept payments in your app. Feel free to write a response :)

--

--

Jaka Rizmal

I'm a computer engineer that does a lot of web development. I love creating stuff.