Google Pay with Firebase extension and Adyen
Tags: firebase, react, googlepay
Published: 2022-08-09 14:40:10

## "Payments made simpler" tutorial

[Google Pay](https://www.adyen.com/payment-methods/google-pay) with Adyen enables shoppers to securely pay online and in-person using the cards stored in the Google account. The integration is secure (supporting [3DS](https://docs.adyen.com/online-payments/3d-secure)), ubiquitous (multiple currencies across many countries) and effortless: Adyen has partnered with Google for quite some time to make sure developers can easily plugin Google Pay in their applications, being a web site, a native Android application or a third-party system using APIs.

> In this article we explore a new way to use GooglePay with Adyen: the Google Pay Firebase extension.

## Firebase And Firestore
[Firebase](https://firebase.google.com/) is a “backend as a service” platform that enables developers to create web and mobile applications without worrying about configuring and managing backend databases or storage, but instead plugging in each service via its own dedicated APIs.

The available services include databases, cloud storage, serverless functions, authentication and messaging, all supported by a comprehensive toolset (FireBase console, Command-line interface, Testlab).

[Cloud Firestore](https://firebase.google.com/products/firestore/) is a NoSQL database part of the Firebase platform: it is designed to support complex JSON-based data structure, advanced querying and multiple languages (NodeJS, Python and Java SDKs). Firestore really stands out when used together with [Cloud Functions](https://firebase.google.com/docs/functions) that allow executing server-side code in response to events like changes in the database or other types of notifications.

## Make Payments with Google Pay
The “Make payments with Google Pay” Firebase [extension](https://github.com/google-pay/firebase-extension) is a plugin designed to enable the integration with your preferred Payment Service Provider (Adyen of course): this integration takes place via Firestore where payment requests are created and processed. Once a request is saved in a predefined path (collection of documents), the very same document is updated with the payment outcome (authorisation or an error maybe).

The communication with Adyen is, once properly configured, transparent to the application which only interacts with the Firebase platform.

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/4ba246pelhme0x7fvvkv.jpg)

## Plant a Tree sample application on Firebase with Adyen

The [sample application](https://github.com/gcatanese/adyen-googlepay-firebase-extension) created for this article shows how GooglePay can be used to purchase and plant a tree. The Google Pay button provides the well-known shopper experience while the backend works with the Google Pay Firebase extension. Let’s have a look.

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/upx3kkseniyel7d4k4ca.jpg)

## Pre-requisites and tech stack
The following is required to setup the sample application:

- A Firebase account
- Enable the “Blaze (pay as you go)” plan

The sample application is built using React and the [React GooglePay button](https://github.com/google-pay/google-pay-button) with a Python backend, but you can use your preferred stack given the various options available in Firebase (Web, Android, iOS, Flutter with Java, Python, Go, PHP, C# and more).

## Extension setup
The first step is the creation of a new Firebase project using the [Firebase Console](https://console.firebase.google.com/)

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/2hhs0f9s5sl1qsepa5j6.jpg)

This is a simple operation but behind the scenes it creates a sandbox and provisions the cloud resources. Next in the Project home navigate to “Extensions” and install the “Make Payments with Google Pay”.

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/ee4dt3j29muw2gvsr1yc.jpg)

During the setup it is requested to enable Secret Manager necessary to manage the secrets (i.e Adyen API key) used by the extension.

The most important part of the setup comes when the Adyen configuration must be defined. To complete this step make sure you have already an **Adyen API Key and Merchant Account** at the ready (those are managed in the Customer Area) and configure the Cloud Firestore path (where the documents are going to be saved).

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/eh6h7axvuqhwbe7xrlok.jpg)

## Prepare the Firebase project

The first step is to add an application to the Firebase project. In our case it is a Web application using NPM (package manager for Javascript). Conveniently the Firebase Console provides us with the necessary install script and any initialization code.

## Install Firebase JS SDK

```
$ npm install firebase
```

Initialize Firebase with the following code (note I have adapted the Firebase generated snippet to use `env` variables instead of hardcoding the secrets):

```
// Firestore.js
import { initializeApp } from "firebase/app"
import { getFirestore } from "firebase/firestore"

export const firebaseConfig = {
  apiKey: 
    process.env.REACT_APP_API_KEY,
  authDomain: 
    process.env.REACT_APP_AUTH_DOMAIN,
  projectId: 
    process.env.REACT_APP_PROJECT_ID,
  storageBucket: 
    process.env.REACT_APP_STORAGE_BUCKET,
  messagingSenderId: 
    process.env.REACT_APP_MESSAGING_SENDER_ID,
  appId: 
    process.env.REACT_APP_APP_ID
};

// Initialize Firebase
const app = initializeApp(firebaseConfig)
const db = getFirestore(app)

export {db}
```

## Add the Google Pay button

The React Google Pay component simplifies the integration of Google Pay in React applications (taking care of the component lifecycle and bindings). Similarly, as working with the [Google Pay API](https://developers.google.com/pay/api/web/guides/tutorial), the React component must define the necessary configuration like the Google Pay API version, which payments are allowed, supported card networks, etc…

A very important attribute is the `tokenizationSpecification`: it defines how the card details of the shopper are encrypted. In this case Adyen is set as the Payment Gateway and will take care of the payment execution and the tokenization.

```
<GooglePayButton
    environment="TEST"
    paymentRequest={{
        apiVersion: 2,
        apiVersionMinor: 0,
        allowedPaymentMethods: [
            {
                type: 'CARD',
                parameters: {
                    allowedAuthMethods: 
                        ['PAN_ONLY', 'CRYPTOGRAM_3DS'],
                    allowedCardNetworks: 
                        ['MASTERCARD', 'VISA'],
                },
                tokenizationSpecification: {
                type: 'PAYMENT_GATEWAY',
                parameters: {
                    gateway: 'adyen',
                    gatewayMerchantId: 'TestMerchantAccount',
                    },
                },
            }
        ],
        merchantInfo: {
            merchantId: 'TestMerchantAccount',
            merchantName: 'Demo',
        },
        transactionInfo: {
            totalPriceStatus: 'FINAL',
            totalPriceLabel: 'Total',
            totalPrice: order.amount,
            currencyCode: order.currency,
            countryCode: 'NL',
        }
    }}
```

The React Google Pay button supports several [callbacks](https://github.com/google-pay/google-pay-button/tree/main/src/button-react#callbacks) to handle the interaction with Google Pay:

- **onCancel**: when the shopper closes the Google Pay widget
- **onLoad**: when the shopper has chosen the card from the Google Pay wallet
- **onError**: when an error occurs during the payment workflow

The `onLoad` callback is where the payment process is initiated: at this stage the shopper has already confirmed which card to use and the React component has received the PaymentData object (this includes the token required by the tokenization process).

```
onLoadPaymentData={ paymentRequest => {
 var token = 
  paymentRequest.paymentMethodData.tokenizationData.token;
 /* add payment to Firecloud */
   this.addPaymentRequest(order.amount, 
   order.currency, token);
 }
}
/* canceled by shopper */
onCancel={() => console.log('action canceled by shopper')}
```

## Process the payment with Firebase

The way the payment is executed is the key difference between the standard [Google Pay integration](https://developers.google.com/pay/api/web/guides/tutorial) and when using the Firebase extension: instead of coding and managing the creation of the PaymentDataRequest the Firebase extension listens for requests created in a specific path (i.e. ‘payment’) in Firestore, submits the requests to the Adyen platform and finally writes back the response **updating the existing record**.

```
// payment request
{
  psp: adyen,
  total: 10.00,
  currency: EUR,
  paymentToken: ***********
}

// payment request updated
{
  psp: adyen,
  total: 10.00,
  currency: EUR,
  paymentToken: ***********,
  success: {
      additionalData: { …. }    
   }
}
```

## Create the payment request

The payment request is created by adding a new record in the `payment` path on the Firecloud database. This is accomplished using the [Firebase Javascript API](https://firebase.google.com/docs/reference/js) addDoc method:

```
const ref = await addDoc(collection(db, 'payments'), {
    psp: 'adyen',
    total: amount,
    currency: currency,
    paymentToken: token
})
```

## Get real time updates

The application must now wait for an update (either successful or with an error message) of the existing record. This can be conveniently implemented using the onSnapshot method that listens for changes in a document, a collection or a query.

```
// query finding the existing request by id
const q = query(collection(db, "payments"), 
  where("__name__", "==", ref.id));

const observer = onSnapshot(q, docSnapshot => {
  docSnapshot.docChanges().forEach(change => {
    if (change.type === "modified") {
      console.log("record updated ", change.doc.data());
      // i.e. display message to shopper
    }
  });
}, err => { console.log(`Encountered error: ${err}`); });
```

In the snippet above updates of the payment requests are notified in realtime to the application, which can then continue the workflow and notify the user. The `onSnapshot` method also triggers when a request is first created, but using the `change.type` information the developer can distinguish what happens (creation, update or delete) and what needs to be done.

## Testing the extension
You can test the integration with the “Make Payments with Google Pay” extension on the [Adyen Testing environment](https://ca-test.adyen.com/). In the Customer Area create an API Key within a Test merchant account: you can then view all payment transactions and API logs, including inspecting the JSON requests and responses.

Google Pay also makes a [Test Card suite](https://developers.google.com/pay/api/android/guides/resources/test-card-suite) available with several (testing) credit cards that can be used to validate the integration and the payment workflow. Join the “[Google Pay API Test Cards Allowlist](https://groups.google.com/g/googlepay-test-mode-stub-data)” Group to instantly view those cards in the Google Pay TEST environment.

## Conclusion
The “Make Payments with Google Pay” extension can significantly simplify the integration with the Adyen platform for applications and services running on Firebase.

Firebase serverless architecture, its multi-platform SDKs and vast documentation make it suitable for both small and large projects. The communication with Adyen is provided by the extension without the need for the developers to develop, test or integrate the interaction with the Adyen backend.

In this initial version the standard payment workflow (Google Pay with cards and other payment methods) is offered, but in the future we will look at more advanced use cases like recurring payments or reversals.

---

Interested in finding out more about Adyen features, benefits and integrations? Check out the [Google Pay page](https://www.adyen.com/payment-methods/google-pay) and get in touch if you have any questions.