Headless Stripe Payments With Firebase

Payment integration for dummies

TL;DR — code here, along with detailed steps to get up and running: https://github.com/gordonnl/firebase-stripe


When it comes to coding back-end, I absolutely identify as a dummy. Things in that zone often seem confusing or overly complex to me.

On that note, I have been seriously impressed with both Firebase and Stripe’s ease of use, and the plethora of documentation.

Even so! I still struggled to understand what I imagined was a really simple process — receiving a basic payment with Stripe from a static website. I just couldn’t find any clear, perfect examples or relevant documentation.

I did find this great example from Firebase, however it still involves quite a lot to wrap your head around — front-end dependencies, user authentication, writing to a database, using a database trigger — all kind of excessive for the barebones example I was after.

So I wanted to make the simplest-possible Firebase-Stripe integration. For dummies like me.

What I came up with works like this:

  1. Use Stripe’s UI options to get a Token

What’s a Token? It’s a unique string that Stripe generates to refer to a user’s sensitive credit information.

2. Pass it to a Firebase function using an HTTP request

3. Communicate securely with Stripe

Find the code for the entire implementation here.

In the rest of the article, I’ll outline what’s involved in each of these steps, starting from the most important.

Signing Up

First things first, you’ll need to create an account with both Firebase and Stripe.

Once that’s done, in the Firebase console, create a new empty project. Then, if you install the Firebase CLI tools on your machine, follow the instructions so that you can link a local directory to your firebase project and deploy when ready.

In the Stripe Dashboard, either create a new account or use an existing one. Then locate the API keys and keep them handy for when you need to implement them into the project.

Firebase Function Code

This is the part that lives on the Firebase cloud. We’ll set this up first so that out front-end has something to communicate with.

The only reason we need server code at all is so that we can let it use our Secret Stripe API Key to communicate securely with Stripe.

See the functions/index.js file for the full code.

Put simply, it receives a Stipe Token from an HTTP request, and then passes that on to Stripe. Then it handles the response from Stripe.

It’s important to note that you should never hardcode your Stripe Secret Key anywhere that it can be found by others (like Github). To get around this, we need to set up an Environment Variable inside the Firebase Function. This is done by running the following command-line script from a directory linked to your Firebase project.

$ firebase functions:config:set stripe.token="SECRET_STRIPE_KEY"

We then recover this inside the function using the following variable:

firebase.config().stripe.token

HTTP Request

In order to make this HTTP request from our front-end, I’ve created a function called charge using the Fetch API. It’s just a simple POST request with the Token and charge details attached.

This, along with all of the front-end code, can be found in the public/index.html file.

And that’s where the custom code ends! The rest of the article is going to explain the different methods Stripe provides to create this Token.

Now Stripe has really good documentation, so I’d recommend going there for all of the juicy details. However, I’m still going to brush over them lightly, for the article’s sake.

Generating A Stripe Token

How many ways can you skin a cat? (gross, should probably just let that saying die…)

3 ways, according to Stripe. You can receive credit details from a user and generate a Stripe Token using either:

  1. Stripe Elements,
  2. Payment Request API, or
  3. Stripe Checkout.

To demonstrate each of these methods, I’ve mashed them together into the example repo, but you definitely don’t need to (and shouldn’t) do that. They each have their uses, so let’s have a look at each.

Stripe Elements

These are a group of pre-built UI input elements that you can style to your heart’s content. You style, and they deal with the annoying stuff like validation and formatting — sweet deal.

You kick it off by providing your Stripe Publishable Key to the library, and then creating an elements object.

I separated this part as I wanted to note that this is also needed for the Payment Request method, but not the Checkout method.

Then, we create a ‘card’ element, and mount it into our pre-defined HTML.

The ‘card’ element contains inputs for card number, expiry data, CVC and post-code. They’ve really done a great job at making it as simple as possible.

The element also comes with a handy validation handler, which lets you very simply notify the user about any errors or missing fields.

And then there’s the big one — the form submit handler.

It’s actually not that big… Stripe creates a token, and then you pass it to the charge function that we mentioned earlier.

Happy days! How could it get simpler than that!

Oh, but it can…

Payment Request Button

Stripe’s Payment Request Button supports Apple Pay, Google Pay and the Payment Request API. It’s basically where the relevant platform has already stored your credit card details, and you can pay for stuff in one click.

For example, on Chrome for Android, it looks like this once you’ve clicked:

To set it up, we need to generate a Payment Request object, so that the platform can display all of the data to the user in their own format. Then we create the button element.

We need to check if the browser supports the API, and only mount the element if it does.

Then we simply listen to the ‘token’ event, and pass it to our charge function.

In order to test the Payment Request Button locally, you’ll need to set up an SSH tunnel using Ngrok or equivalent because it requires HTTPS.

As it’s not always supported, it’s a pretty good idea to implement the ‘card’ element as well, as a fallback.

Stripe Checkout

The third and easiest of methods.

Checkout opens as a popup with a pre-made form with all of the bits and bobs included. You don’t get to style it, but get plenty of options to change what information and inputs are displayed.

To implement, you just need to configure a handler, in which we use a callback to send the Token to our good-old, trusty charge function once again.

Then we need to trigger the Checkout modal to appear. Here I’ve attached it to the ‘click’ event of a button.

And there you have it! Headless payment integration, cooked three ways.

Hopefully this simple walkthrough helps some fellow back-end dummies that are looking to add monetisation to their developer tool-belt. It’s honestly pretty fun now that I’ve grasped it. So now you too can put donate buttons on all of your websites and feel like a smarty-pants.

Thanks for reading! Remember to check out the repo for detailed steps on how to get the demo up and running.

Further reading: