capacitorcapacitor-community/stripe

Logo Github GitHub

Google Pay

With Google Pay, you can make instant payments in a single flow. Please check settings:

https://stripe.com/docs/google-pay

And if you will work on the web, you should check "Payment Request Button" 's docs. Serve your application over HTTPS. This is a requirement both in development and in production. One way to get up and running is to use a service like ngrok.

https://stripe.com/docs/stripe-js/elements/payment-request-button?platform=html-js-testing-google-pay#html-js-prerequisites

🐾 Implements Guide

Prepare settings

For using Google Pay, you need some settings.

strings.xml

In file android/app/src/main/res/values/strings.xml add the these value.

  • publishable_key(Stripe's publoshable key)
  • enable_google_pay
  • country_code
  • merchant_display_name
  • google_pay_is_testing

These settings are used because Google Pay requires some processing to be done before initializing the plugin.

<string name="publishable_key">Your Publishable Key</string>
<bool name="enable_google_pay">true</bool>
<string name="country_code">US</string>
<string name="merchant_display_name">Widget Store</string>
<bool name="google_pay_is_testing">true</bool>

AndroidManifest.xml

In file android/app/src/main/AndroidManifest.xml, add the following XML elements under manifest > application. These call the values set in strings.xml.

<meta-data
  android:name="com.getcapacitor.community.stripe.publishable_key"
  android:value="@string/publishable_key"/>

<meta-data
  android:name="com.getcapacitor.community.stripe.enable_google_pay"
  android:value="@bool/enable_google_pay"/>

<meta-data
  android:name="com.google.android.gms.wallet.api.enabled"
  android:value="true" />

<meta-data
  android:name="com.getcapacitor.community.stripe.country_code"
  android:value="@string/country_code"/>

<meta-data
  android:name="com.getcapacitor.community.stripe.merchant_display_name"
  android:value="@string/merchant_display_name"/>

<meta-data
  android:name="com.getcapacitor.community.stripe.google_pay_is_testing"
  android:value="@bool/google_pay_is_testing"/>

1. isGooglePayAvailable

First, you should check to be able to use Google Pay on device.

import { Stripe, GooglePayEventsEnum } from '@capacitor-community/stripe';

(async () => {
  // Check to be able to use Google Pay on device
  const isAvailable = Stripe.isGooglePayAvailable().catch(() => undefined);
  if (isAvailable === undefined) {
    // disable to use Google Pay
    return;
  }
})();

This method return resolve(): void or reject('Not implemented on Device.').

method isGooglePayAvailable()

isGooglePayAvailable() => Promise<void>

2. createGooglePay

You should connect to your backend endpoint, and get every key. This is "not" function at this Plugin. So you can use HTTPClient , Axios , Ajax , and so on.

Stripe provide how to implement backend:

https://stripe.com/docs/payments/accept-a-payment?platform=ios#add-server-endpoint

After that, you set these key to createGooglePay method.

(async () => {
  // Connect to your backend endpoint, and get paymentIntent.
  const { paymentIntent } = await this.http.post<{
    paymentIntent: string;
  }>(environment.api + 'payment-sheet', {}).pipe(first()).toPromise(Promise);

  // Prepare Google Pay
  await Stripe.createGooglePay({
    paymentIntentClientSecret: paymentIntent,

    // Web only. Google Pay on Android App doesn't need
    paymentSummaryItems: [{
      label: 'Product Name',
      amount: 1099.00
    }],
    merchantIdentifier: 'merchant.com.getcapacitor.stripe',
    countryCode: 'US',
    currency: 'USD',
  });
})();

method createGooglePay(...)

createGooglePay(options: CreateGooglePayOption) => Promise<void>

You can use options of CreateGooglePayOption on createGooglePay.

interface CreateGooglePayOption

Prop Type Description
paymentIntentClientSecret string
paymentSummaryItems { label: string; amount: number; }[] Web only need @stripe-elements/stripe-elements > 1.1.0
merchantIdentifier string Web only need @stripe-elements/stripe-elements > 1.1.0
countryCode string Web only need @stripe-elements/stripe-elements > 1.1.0
currency string Web only need @stripe-elements/stripe-elements > 1.1.0

paymentSummaryItems, merchantIdentifier, countryCode, currency is needed on the web only. If you will implement Google Pay on Android App only, don't need.

3. presentGooglePay

present in createGooglePay is single flow. You don't need to confirm method.

(async () => {
  // Present Google Pay
  const result = await Stripe.presentGooglePay();
  if (result.paymentResult === GooglePayEventsEnum.Completed) {
    // Happy path
  }
})();

method presentGooglePay()

presentGooglePay() => Promise<{ paymentResult: GooglePayResultInterface; }>

GooglePayResultInterface is created from Enum of GooglePayEventsEnum. So you should import and check result.

type alias GooglePayResultInterface

GooglePayEventsEnum.Completed | GooglePayEventsEnum.Canceled | GooglePayEventsEnum.Failed

4. addListener

Method of Google Pay notify any listeners. If you want to get event of payment process is 'Completed', you should add GooglePayEventsEnum.Completed listener to Stripe object:

// be able to get event of Google Pay
Stripe.addListener(GooglePayEventsEnum.Completed, () => {
  console.log('GooglePayEventsEnum.Completed');
});

The event name you can use is GooglePayEventsEnum.

enum GooglePayEventsEnum

Members Value
Loaded "googlePayLoaded"
FailedToLoad "googlePayFailedToLoad"
Completed "googlePayCompleted"
Canceled "googlePayCanceled"
Failed "googlePayFailed"

📖 Reference

See the Stripe Documentation for more information. This plugin is wrapper, so there information seems useful for you.

Google Pay (Android)

This plugin use GooglePayLauncher on com.stripe:stripe-android:

https://stripe.com/docs/google-pay

Google Pay (Web)

This plugin use "Payment Request Button".

https://stripe.com/docs/stripe-js/elements/payment-request-button?platform=html-js-testing-google-pay#html-js-prerequisites

<?xml version='1.0' encoding='utf-8'?>
<resources>
    <string name="app_name">capacitor-stripe</string>
    <string name="title_activity_main">capacitor-stripe</string>
    <string name="package_name">io.ionic.starter</string>
    <string name="custom_url_scheme">io.ionic.starter</string>

    <string name="publishable_key">pk_test_YssveZBA1kucfaTfZbeDwauN</string>
    <bool name="enable_google_pay">true</bool>
    <string name="country_code">US</string>
    <string name="merchant_display_name">Widget Store</string>
    <bool name="google_pay_is_testing">true</bool>
</resources>
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="io.ionic.starter">

    <application
        android:allowBackup="true"
        android:icon="@mipmap/ic_launcher"
        android:label="@string/app_name"
        android:roundIcon="@mipmap/ic_launcher_round"
        android:supportsRtl="true"
        android:theme="@style/AppTheme">

        <activity
            android:configChanges="orientation|keyboardHidden|keyboard|screenSize|locale|smallestScreenSize|screenLayout|uiMode"
            android:name="io.ionic.starter.MainActivity"
            android:label="@string/title_activity_main"
            android:theme="@style/AppTheme.NoActionBarLaunch"
            android:launchMode="singleTask">

            <intent-filter>
                <action android:name="android.intent.action.MAIN" />
                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>

        </activity>

        <provider
            android:name="androidx.core.content.FileProvider"
            android:authorities="${applicationId}.fileprovider"
            android:exported="false"
            android:grantUriPermissions="true">
            <meta-data
                android:name="android.support.FILE_PROVIDER_PATHS"
                android:resource="@xml/file_paths"></meta-data>
        </provider>

        <meta-data
          android:name="com.google.android.gms.wallet.api.enabled"
          android:value="true" />

        <meta-data
          android:name="com.getcapacitor.community.stripe.enable_google_pay"
          android:value="@bool/enable_google_pay"/>

        <meta-data
          android:name="com.getcapacitor.community.stripe.publishable_key"
          android:value="@string/publishable_key"/>

        <meta-data
          android:name="com.getcapacitor.community.stripe.country_code"
          android:value="@string/country_code"/>

        <meta-data
          android:name="com.getcapacitor.community.stripe.merchant_display_name"
          android:value="@string/merchant_display_name"/>

        <meta-data
          android:name="com.getcapacitor.community.stripe.google_pay_is_testing"
          android:value="@bool/google_pay_is_testing"/>
    </application>

    <!-- Permissions -->

    <uses-permission android:name="android.permission.INTERNET" />
</manifest>

import { Stripe, GooglePayEventsEnum } from '@capacitor-community/stripe';

(async () => {
  // Check to be able to use Google Pay on device
  const isAvailable = Stripe.isGooglePayAvailable().catch(() => undefined);
  if (isAvailable === undefined) {
    // disable to use Google Pay
    return;
  }
  
  Stripe.addListener(GooglePayEventsEnum.Completed, () => {
    console.log('GooglePayEventsEnum.Completed');
  });
  
  // Connect to your backend endpoint, and get paymentIntent.
  const { paymentIntent } = await this.http.post<{
    paymentIntent: string;
  }>(environment.api + 'payment-sheet', {}).pipe(first()).toPromise(Promise);

  // Prepare Google Pay
  await Stripe.createGooglePay({
    paymentIntentClientSecret: paymentIntent,

    // Web only. Google Pay on Android App doesn't need
    paymentSummaryItems: [{
      label: 'Product Name',
      amount: 1099.00
    }],
    merchantIdentifier: 'merchant.com.getcapacitor.stripe',
    countryCode: 'US',
    currency: 'USD',
  });

  // Present Google Pay
  const result = await Stripe.presentGooglePay();
  if (result.paymentResult === GooglePayEventsEnum.Completed) {
    // Happy path
  }
})();