Integrating your reactjs web app with stripe and cloud functions on Firebase part 1 of 2

Xavier Tan
6 min readAug 2, 2021

Alright so you have finished your frontend work for your newly made e-commerce website and you need to integrate some sort of payment gateway now. How do you go about it?

Well if you are using Google’s firebase service to launch host your web app, then you could follow this simplified guide to easily and quickly integrate Stripe into your system.

Do check the latest stripe’s documentation here https://stripe.com/docs/payments for the latest instructions and features.

Please note that this guide has no affiliation to Stripe or any other payment gateway and or provider. It also does not reflect the views and or opinions of my employer or any organisation I represent. I do not hold any responsibility to workings, security issues, vulnerabilities or any consequences arised from implementing the system with regards to the mentioned payment gateway provider(s) directly and or indirectly. You get what I mean. xD. This is simply a guide to help fellow starters in the coding journey, don’t make it difficult to share knowledge : ).

Front End

On the front-end you would need a button to link the user from your website to the stripe’s API webpage which would handle all the credit details collection etc.

Payment button.

Upon clicking the button, the callback function will trigger the cloud function to create a session to use stripe’s API to create a stripe checkout page.View https://stripe.com/en-gb-sg/payments/checkout to see the Checkout page.

This is done using a POST method. Do take note that a POST method is asynchronous, which means front-end will continue rendering even while the POST method is still processing on the back-end side of things.

paymentBtn.addEventListener("click", () => {//pass in cart details
// cloudFunction is created in the Functions > index.js file. More details explain in the backend part.
fetch("https://<serverwebsite>.cloudfunctions.net/<cloudFunction> Name", {method: "POST",// Adding the order data to payload//encrypt the payload body: encryptedBodyStr,}).then(response => {return response.json();}).then(data => {// Getting the session id from firebase functionvar body = JSON.parse(data.body);return sessionId = body.sessionId;}).then(sessionId => {// Redirecting to payment form pagestripe.redirectToCheckout({sessionId: sessionId}).then(function (result) {return result.error.message});});});

Within a POST method you could pass whatever information that you might need to the checkout session, such as the items in the cart or shipping address. The session object has a bunch of attributes and for more information look up to https://stripe.com/docs/api/checkout/sessions/object.

Attributes simply means the information that you need to pass over.

For added security, to prevent man in middle attack or any other cyber attacks. Minimally, I would suggest that you encrypt the information first before sending over the POST method. This could easily be done using the ‘cryptr’ package. Remember to save the key in the environment variables otherwise it defeats the purpose of encrypting your payload.

const Cryptr = require('cryptr');var key = process.env.REACT_APP_SECRET_KEYconst crypto = new Cryptr(key);// Body is your payload that needs to be sent using POST method
const encryptedBodyStr = crypto.encrypt(JSON.stringify(body));

Once the session object is successfully created from the cloud function, The POST method should return a session ID which is used to create the check-out page. Which is actually a page hosted by Stripe to collect payment information securely from your user. In other words, the security part of storing or processing one’s sensitive information like credit card details is handled by stripe. (A sign of relief here, wew). Once this is done the user has to be redirected back to your website. This is done using the checkout session api. The code should be written in the index.js in the functions folder (refer to backend part)

Backend

The backend magic is done with “server-less” functions or cloud functions. Basically, it means that you don’t have to host a traditional server like flask or node server but rather, you simply create and upload your functions to google firebase <functions>. Thereafter, you could trigger these functions through a HTTP REQUEST whenever you need it.

Firebase function. Activate it before use.

There are 2 things you need to take caution.

  1. You have to store your STRIPE secret key, end point secret key, as well as the cryptr key securely.
  2. Also take note that whichever region you choose for the firebase hosting, storage, functions would affect the processing time in the magnitude of seconds.

Serveless Functions to be created:

  1. Create a session, send the sessionID to front end, and the webpage to be directed to after payment. The sessionID is needed to create the stripe checkout page to collect user’s credit card details etc. This is the<cloudFunction> I was mentioning in the front end code.
  2. A function to process an order(such as sending email to your sales team or saving it on the firebase’s database), This function will get triggered by a web-hooks from Stripe once Stripe recognises that the payment is good to go.

Create sessionID cloud function

These function has to be written in the functions folder (a folder would be created when you init firebase functions to your project). If this folder is not created. Run(in your terminal):

firebase init functions

Then the folder should be created for you. Within that folder create a file called index.js. View https://firebase.google.com/docs/functions/get-started for more details.

Below would be the code needed in index.js to create the function.

//Remember to npm install these packages that are required.'use strict';
const functions = require('firebase-functions');
const cors = require('cors')({origin: true});
const express = require('express');
const stripe = require('stripe')(functions.config().stripe.key);
// The function for sending responses. need this function to send sessionID to clientfunction send(res, code, body) {res.send({statusCode: code,headers: {'Access-Control-Allow-Origin': '*'},body: JSON.stringify(body),});}function createSessionFunc(req, res) {//body is cart details from front End js file//body should be encrypted, decrypt itconst bodyDecryptedStr = crypto.decrypt(req.body);const body = JSON.parse(bodyDecryptedStr);const cart = body.cart;var items = [];// Process your cart details here and put it into a data structure i.e. items is an array.// Creating session using the data abovestripe.checkout.sessions.create({payment_method_types: ['card'],// Refer to documentation on what this items could be
// Also note that the unit of measure for money in stripe is in cents.
line_items: items,mode: 'payment',success_url: '<The page you want your users to be directed to once successful payment>',cancel_url: '<The error payment page to be redirected to>',}).then(session => {const sessionId = session.id;// Sending the session id to front-end// Add the order data in firebase database (optional)// Note this data is added regardless payment successful or notlet data = {sid: sessionId,items : items,delivery : deliveryDetails}console.log(sessionId);let setDoc = db.collection(`${param}`).doc(`${param}`).set(data).then(ref => {console.log('Added document with ID: ', ref.id);return;}).catch(error => {console.log(error);return;});send(res, 200, {sessionId: sessionId});return;}).catch(error => {console.log(error);return;});}// Create a routesessionApp.post('/', (req, res) => {try {createSessionFunc(req, res);} catch(e) {console.log(e);send(res, 500, {error: `Some error message here`,});}});// Region has to be the same as the one you activated at firebase
exports.createSessionFunc = functions.region('asia-east2').https.onRequest(sessionApp);

Once you deploy this function you should see the function being created in the firebase function dashboard. So basically whenever you call the cloud function, this function that you created with the code above would trigger.

To deploy run (in your terminal):

npm run build
firebase deploy

or

npm run build
firebase deploy --only functions
Function created in functions dashboard

Stay tune to part 2 for the other important cloud function! Do feedback on what could be improved in the article. Thank you for reading and hope this helps.

--

--