Stripe payment integration in React Native apps using Firebase
In this post, you’ll learn how to integrate Stripe Payment Gateway in React Native apps. We’ll implement this functionality using a Firebase cloud function, acting as our server side logic.
Stripe is one of the most widely used and fastest growing payment gateway you can integrate in your website or app. It supports a wide variety of payment options, including Apple Pay and Google Pay, and is quickly spreading across the globe. Stripe can take care of almost all your payment requirements in apps and website. Stripe’s ease of integration has made it a popular developer choice over PayPal and other payment gateways. A good comparison between Stripe and PayPal can be studied here (spoiler — Stripe wins)
What is React-Native ?
TLDR; — React Native (RN) creates cross-platform apps, more “native” than web-view apps made by Cordova / Ionic. But React Native is yet to release a stable (1.0.0_) version of the framework.
React Native is a JavaScript framework for writing natively rendering mobile applications. It’ is based on React, Facebook’s JavaScript library for building user interfaces, but instead of targeting the browser, it targets mobile platforms. Because most of the code you write can be shared between platforms, React Native makes it easy to simultaneously develop for both Android and iOS.
React Native applications render using real mobile UI components, not web-views, and will look and feel like any other native mobile application. React Native also exposes JavaScript interfaces for platform APIs, so your React Native apps can access platform features like the phone camera, or the user’s location. Facebook, Palantir, TaskRabbit etc are already using it in production for user-facing applications.
React Native and Stripe
React Native can create a wide variety of apps, and hence a wide variety of payment gateways can be implemented in React Native apps. The popular ones are PayPal, Stripe, RazorPay, Braintree, in-app purchase etc.
There are two options for front-end implementation of Stripe in React Native apps
- Use the iOS / Android SDKs provided by Stripe
- Use a 3rd party library for React Native:
tipsi-stripe
There are pros and cons to each path, mainly revolving around the fact that the React Native library from Tipsi has not been “publicly” approved by Stripe. If you want maximum compliance in production environment, go for Stripe’s fully vetted SDKs. In the rest of this tutorial I will use the tipsi-stripe
library, as it works perfectly and is very easy to implement.
How does Stripe work ?
To simplify the understanding, let us understand the complete flow pictorially
Essentially, in front-end (App side) we initiate a payment. This requests for a token from Stripe server. Once this token is received on front-end, you need to send it to your server (back-end). Only your server can communicate to Stripe server for actual payment. Once actual payment is done, Stripe server sends success message to your server, and your server can send it to your app. Pretty easy, right ! 😅
Steps to implement
I will break it down into steps to keep the post organized
Step 1 — Stripe Developer account and API keys
Step 2 — Create a basic React Native app for Stripe integration
Step 3— Integrate Stripe library tipsi-stripe for token generation
Step 4— Create Firebase function (or any back-end function to accept API calls) to accept tokens from app, and make payment requests to Stripe server
Step 5— Connect app to our Firebase server. Complete Stripe payment requests from Firebase server.
Let’s start step-by-step
Complete source code of this tutorial is available in the RNStripe Github repository
Step 1 — Stripe Developer Account
Visit Stripe.com and create an account. Stripe payment services are currently available in limited countries as shown on this page.
Once you are inside Stripe Dashboard, look for the Developer Tab -> API keys. Make sure you do all development tasks with Test Data
Publishable key is what you use for connecting the Strive Native SDK or tipsi-stripe in front-end — to generate token. Secret key is used in the back-end, where your server connects with Stripe’s server for actual payment.
That’s all you need from Stripe account, for now. You can toggle to Live keys and use them instead once you have tested the process.
Let’s look into the React Native integration of Stripe now.
Step 2— Create a basic React Native app
First, make sure you have all pre-requisites to create a react-native app as per the official documentation.
At the time of this post, I have React-Native version 0.60
Create a blank react-native app (Replace RNStripe
with your own app name)
$ react-native init RNStripe
This will create a basic React-native app which you can run in a device or simulator. Let’s run the app in iOS using
$ react-native run-ios
You’ll see the default start screen on device / simulator. For sample purpose, I will be using the UI provided by tipsi-stripe library. It has options for all kinds of payments — including Apple Pay, Google Pay etc. I’ll be using the default card payment form for this post’s purpose
There are three major files used for this example
index.js
— Parent file of the appRoot.js
— Drawer layout parent fileCardFormScreen.js
— File containing the logic for Card payment via Stripe
You can find these files in the Github repo attached to this post.
Step 3 — Integrate Stripe library tipsi-stripe for token generation
To include Stripe functionality in your React Native app, you need to install tipsi-stripe package. Install the package with following commands
$ npm install --save tipsi-stripe
Setup pods
To integrate appropriate pods for iOS app, setup your Podfile
like the following then run pod install
. My Podfile
looks like this
Setup XCode project
- Open your project in Xcode workspace.
- Drag the following folder into your project:
node_modules/tipsi-stripe/ios/TPSStripe/
Link the package
Run react-native link tipsi-stripe
to link the package against your Xcode project and so that all CocoaPods dependencies are installed.
Note: Linking on Windows system currently isn’t working, sadly. Check here for updates
Generate Token on App
To generate token, import the library in your page using
$ import stripe from 'tipsi-stripe'
And initialize it with your Stripe credentials that you can get from dashboard.
stripe.setOptions({
publishableKey: 'PUBLISHABLE_KEY'
})
Remember, PUBLISHABLE_KEY
only helps in generating token. Replace this with your own PUBLISHABLE_KEY
We will use the paymentRequestWithCardForm
method of the library to get the Token (Check CardFormScreen.js
file for full details)
The method will open the “Default card details form” for Stripe. Enter your card details here (or use a sample cards from Stripe), and enter your address and submit.
Once you submit the details, you will receive a token from Stripe. I have the token displayed in the UI like this, for confirmation
Step 4 — Create Firebase function to complete Payments
Please note that steps mentioned above only help you to create a payment token from Stripe server. It DOES NOT complete a payment. To complete the payment, you can use the generated token, send it to your server, and complete the payment request via your server
To complete the payment via server, let us create a firebase cloud function. Firebase is a BaaS platform, which provides you ready-made back-end, database and a ton of other services — all free of cost and ready to integrate in an app.
Firebase Cloud Functions are a way to write custom server functions. You can execute these functions using REST calls from your React Native app. This Firebase Cloud Function can interact with Stripe server to complete your payment.
Setup Firebase Cloud Function
Assumption — You already know how to create a Firebase Project, and deploy Firebase function on it. You can follow my blogs on how to create a Firebase project (first few steps) and how to create Firebase Cloud functions.
To interact with Firebase functions in development, you need Firebase-tools
in your system. Install firebase tools with
$ npm install -g firebase-tools
Connect Firebase to your Firebase project
You can create a Firebase Project in Firebase console webpage, and invoke it in development environment (your system)
Once you have your project ready, connect it to your dev environment using
$ firebase init
then choosing the project, and choosing functions
option from the choices.
With Firebase Functions, you can essentially right back-end (node.js) functions in same environment, test locally with firebase serve
and can then deploy these to your Firebase project, so it can be connected to your app / website.
Once you have Firebase project connected, you will see a functions
folder in your project root, as shown below
Create a firebase function to make payment requests
After this, you can create your back-end function in functions/index.js
file. This function will accept a request object from your app / website, send the payment request to Stripe server, and return the response to your app / website again.
Remember to replace YOUR_SECRET_KEY
with your own.
Notice that the payment request from your app should contain
- amount — in number (Notice: this number is in cents when you use “usd”. So use 100 if the payment is for $1. Using less than 50 will give an error.)
- currency — currency code string e.g. “usd”
- token — the one we received in Step 1 and Step 2
This data should be sent in an object in POST API request, shown in next step.
Test Firebase functions locally
To test whether your Firebase function is correctly written, run the function locally by running command
$ firebase serve
This will start your firebase local server, and the url will be displayed in the terminal , something like
http://localhost:5000/shoppr-c97a7/us-central1/payWithStripe
(where shoppr-c97a7
is my Firebase project ID)
Now, you can make an API call to this URL using your React Native app. We’ll use the simple fetch
API for this, and show “Payment Success” in the app UI itself — in next step
Deploy Firebase Function to live site
Once your local testing is successful, deploy the firebase functions to live server using
$ firebase deploy --only functions
This will deploy the functions on your live Firebase server, which you can make API calls to. The url of the function will again be shown in the terminal after deployment, something like
https://us-central1-shoppr-c97a7.cloudfunctions.net/payWithStripe
Note
- Make sure you change your API call url to the new function URL
- Firebase allows external API calls only in paid accounts. If you are using free account, it won’t allow an external API call. You can, however, test the functionality locally using
firebase serve
Step 5— Connect the app to live Firebase server and complete payment requests
In the same CardFormScreen.js
file, we’ll make a HTTP call to Firebase function to complete the payment using the generated token. HTTP call can be simply made using fetch
like this
A successful response from the server will look like following. It’s a long response, but you get the idea that everything you need is in there, right ?
Overall, the process looks like following on my iOS simulator
Conclusion
In this blog we learnt how to implement Stripe Payment in a React Native app. I know it is a long post with a lot to understand. Let me repeat the gist of the post —
Stripe payment consists of two parts — front-end (tokenization) and back-end (actual payment request). The Stripe payment integration will follow this pictorial flow
- Front-end part can be done using React Native app with tipsi-stripe package (or Stripe native SDK)
- Back-end part can be done using any server you have. For example purpose, we used a Firebase server.
Complete source code of this tutorial is available in the RNStripe Github repository.
Stay tuned for more React Native blogs !