使用 Google Wallet API 在 Android 上建立票證

1. 簡介

總覽

透過 Google 錢包 API,您可以透過各種票證與使用者互動,例如會員卡、優惠、禮物卡、活動票券、大眾運輸票券、登機證等。每種票證類型 (或票證類別) 都提供特定用途的欄位和功能,可提升使用者體驗。

不過,這些方法可能不適合所有用途。如要打造更個人化的體驗,可以使用一般票證類型。以下是通用憑證類型的幾個範例用途:

  • 停車證
  • 圖書館會員卡
  • 儲值憑證
  • 健身房會員卡
  • 保留項目

一般票證可用於任何用途,只要能出示:

  • 最多三列資訊
  • (選用) 條碼圖片
  • (選用) 詳細資料專區

Android 裝置顯示「新增至 Google 錢包」的供應流程

如要進一步瞭解 Google Wallet API,或是在 Android 應用程式中新增「新增至 Google 錢包」按鈕,請參閱 Google 錢包開發人員說明文件

票證類別和物件

Google Wallet API 提供下列方法的存取權:

類型

說明

票證類別

個別票證物件的範本。其中包含屬於這個類別的所有票證物件的共通資訊。

傳遞物件

專屬於使用者 ID 的票證類別執行個體。

程式碼實驗室簡介

在本程式碼研究室中,您將完成下列工作。

  1. 在示範模式中建立新的核發機構帳戶
  2. 建立用於發放票證的服務帳戶
  3. 建立新的「一般票證」類別
  4. 建立新的票證物件
  5. 建立「新增至 Google 錢包」按鈕來儲存憑證
  6. 在 Android 應用程式中顯示按鈕
  7. 處理票證儲存結果

必要條件

目標

完成本程式碼研究室後,您將能夠:

  • 在 Android 應用程式中新增 Google 錢包 SDK
  • 確認 Android 裝置是否支援 Google Wallet API
  • 建立「新增至 Google 錢包」按鈕

支援

如果在程式碼研究室的任何階段遇到問題,可以參考 google-pay/wallet-android-codelab GitHub 存放區中的完整解決方案。

2. 設定

在這個步驟中,您將在示範模式下建立核發機構帳戶。這樣一來,您就能建立可新增至使用者錢包的票證類別和物件。接著,您將建立 Google Cloud 專案和服務帳戶。這些憑證會用於以程式輔助方式建立票證類別和物件,做法與後端伺服器相同。最後,您將授權 Google Cloud 服務帳戶,在 Google 錢包發卡機構帳戶中管理票證。

申請 Google 錢包 API 發卡機構帳戶

如要建立及發布 Google 錢包票證,必須擁有發行者帳戶。你可以透過 Google Pay 和錢包主控台註冊,一開始,您只能在展示模式中建立票證。也就是說,只有特定測試使用者可以新增您建立的票證。您可以在 Google Pay 和錢包主控台管理測試使用者。

如要進一步瞭解展示模式,請參閱一般票證先決條件

  1. 開啟 Google Pay 和錢包主控台
  2. 按照畫面上的指示建立發卡機構帳戶
  3. 選取「Google Wallet API」
  4. 確認您瞭解服務條款和隱私權政策
  5. 將「核發者 ID」值複製到文字編輯器或其他位置
  6. 在「管理」分頁中,選取「設定測試帳戶」
  7. 新增您要在本程式碼研究室中使用的電子郵件地址

啟用 Google Wallet API

  1. 登入 Google Cloud 控制台
  2. 如果您尚未建立 Google Cloud 專案,請立即建立 (詳情請參閱「建立及管理專案」)
  3. 為專案啟用 Google Wallet API (也稱為 Google Pay API for Passes)

建立服務帳戶和金鑰

如要呼叫 Google 錢包 API,必須使用服務帳戶和服務帳戶金鑰。服務帳戶是呼叫 Google 錢包 API 的身分。服務帳戶金鑰包含私密金鑰,可將應用程式識別為服務帳戶。這組金鑰屬於機密資訊,請務必妥善保管。

建立服務帳戶

  1. 在 Google Cloud 控制台中開啟「服務帳戶」
  2. 輸入服務帳戶的名稱、ID 和說明
  3. 選取「建立並繼續」
  4. 選取「完成」

建立服務帳戶金鑰

  1. 選取服務帳戶
  2. 選取「金鑰」選單
  3. 依序選取「新增金鑰」和「建立新的金鑰」
  4. 選取「JSON」金鑰類型
  5. 選取「建立」

系統會提示您將金鑰檔案儲存至本機工作站。請務必記住該位置。

設定 GOOGLE_APPLICATION_CREDENTIALS 環境變數

Google SDK 會使用 GOOGLE_APPLICATION_CREDENTIALS 環境變數,以服務帳戶的身分進行驗證,並存取 Google Cloud 專案的不同 API。

  1. 請按照 Google Cloud 服務帳戶金鑰說明文件中的操作說明,設定 GOOGLE_APPLICATION_CREDENTIALS 環境變數。
  2. 在新終端機 (MacOS/Linux) 或指令列 (Windows) 工作階段中,確認環境變數已設定 (如果已開啟工作階段,可能需要啟動新的工作階段)
    echo $GOOGLE_APPLICATION_CREDENTIALS
    

授權給服務帳戶

最後,您需要授權服務帳戶管理 Google 錢包票證。

  1. 開啟 Google Pay 和錢包主控台
  2. 選取「使用者」
  3. 選取「邀請使用者」
  4. 輸入服務帳戶的電子郵件地址 (例如 test-svc@myproject.iam.gserviceaccount.com)
  5. 從「存取層級」下拉式選單中選取「開發人員」或「管理員」
  6. 選取「邀請」

3. 建立一般票證類別

在這個步驟中,您將建立票證的基底類別。每當為使用者建立新票證時,系統都會沿用票證類別中定義的屬性。

在本程式碼研究室中建立的票證類別會運用通用票證的彈性,建立可做為身分證件和挑戰點數追蹤器的物件。從這個類別建立的票證物件會如下圖所示。

您可以在 Google Pay 和錢包主控台中直接建立票證類別,也可以使用 Google 錢包 API 建立。在本程式碼研究室中,您將使用 API 建立「一般票證」類別。這與私人後端伺服器建立票證類別的程序相同。

  1. google-pay/wallet-android-codelab GitHub 存放區複製到本機工作站
    git clone https://github.com/google-pay/wallet-android-codelab.git
    
  2. 在終端機或指令列提示中開啟複製的存放區
  3. 前往 backend 目錄 (這些指令碼會模擬後端伺服器動作)
    cd backend
    
  4. 安裝 Node.js 依附元件
    npm install .
    
  5. backend 目錄中,開啟 generic_class.js
  6. issuerId 的值改成 Google Pay 和錢包主控台中的核發機構 ID
    // TODO: Define Issuer ID
    let issuerId = 'ISSUER_ID';
    
  7. 在終端機或命令列提示字元中執行 generic_class.js 指令碼
    node generic_class.js
    

程式碼執行時,會建立新的票證類別並輸出類別 ID。類別 ID 由核發機構 ID 和開發人員定義的後置字元組成。在本例中,後置字串會設為 codelab_class (類別 ID 類似於 1234123412341234123.codelab_class)。輸出記錄也會包含 Google 錢包 API 的回應。

4. 在 Android Studio 中開啟專案

您複製的 GitHub 存放區包含一個含有空白活動的 Android 專案。在這個步驟中,您將編輯這項活動,在產品頁面中加入「新增至 Google 錢包」按鈕。

  1. 開啟 Android Studio
  2. 依序選取「檔案」和「開啟」
  3. 選取存放區中的 android 目錄
  4. 選取「開啟」

在應用程式中加入 Google 錢包 SDK

  1. 開啟模組層級的 Gradle 建構檔案 (android/app/build.gradle)
  2. dependencies 區段中新增 Google 錢包 SDK
    // TODO: Add the "com.google.android.gms:play-services-pay" dependency to
    //       use the Google Wallet API
    implementation "com.google.android.gms:play-services-pay:16.0.3"
    
  3. 儲存檔案
  4. 依序選取「File」和「Sync Project with Gradle Files」

5. 建立「新增至 Google 錢包」按鈕

在這個步驟中,您將建立「新增至 Google 錢包」按鈕,並將其新增至現有活動。按鈕的素材資源已納入專案。如要加入按鈕,請建立獨立的版面配置檔案。新增完成後,按鈕會如下所示。

「新增至 Google 錢包」按鈕

  1. 建立新的版面配置檔案:app/src/main/res/layout/add_to_google_wallet_button.xml
  2. 將下列內容新增至新的版面配置檔案
    <?xml version="1.0" encoding="utf-8"?>
    <FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
        android:layout_width="match_parent"
        android:layout_height="48sp"
        android:background="@drawable/add_to_google_wallet_button_background_shape"
        android:clickable="true"
        android:contentDescription="@string/add_to_google_wallet_button_content_description"
        android:focusable="true">
      <ImageView
          android:layout_width="227dp"
          android:layout_height="26dp"
          android:layout_gravity="center"
          android:duplicateParentState="true"
          android:src="@drawable/add_to_google_wallet_button_foreground" />
    </FrameLayout>
    
  3. 在結帳活動版面配置檔案 (app/src/main/res/layout/activity_checkout.xml) 中加入 add_to_google_wallet_button.xml 版面配置
    <!--
        TODO: Create the button under `add_to_google_wallet_button.xml`
              and include it in your UI
    -->
    <include
        android:id="@+id/addToGoogleWalletButton"
        layout="@layout/add_to_google_wallet_button"
        android:layout_width="match_parent"
        android:layout_height="48dp"
        android:layout_marginTop="10dp" />
    

6. 確認 Google Wallet API 是否可用

如果使用者在不支援 Google 錢包 API 的裝置上開啟應用程式,嘗試新增憑證時可能會遇到問題。如果使用者的裝置不支援 Google 錢包 API,隱藏「新增至 Google 錢包」按鈕可避免造成混淆。API 可能無法使用的原因有很多,例如 Android 或 Google Play 服務版本過舊,或是 Google 錢包未在使用者所在國家/地區推出。

在這個步驟中,您將在應用程式中加入邏輯,檢查裝置是否支援 Google Wallet API。如果符合條件,系統就會在活動中顯示按鈕。否則按鈕會隱藏。

  1. app/src/main/java/com/google/android/gms/samples/wallet/activity/ 中開啟 CheckoutActivity.kt 檔案
  2. PayClient 例項建立類別屬性
    // TODO: Create a client to interact with the Google Wallet API
    private lateinit var walletClient: PayClient
    
  3. onCreate 方法中例項化 PayClient 屬性
    // TODO: Instantiate the client
    walletClient = Pay.getClient(this)
    
  4. 建立方法,檢查裝置是否支援 Google 錢包 SDK 和 API,並處理結果
    // TODO: Create a method to check for the Google Wallet SDK and API
    private fun fetchCanUseGoogleWalletApi() {
      walletClient
        .getPayApiAvailabilityStatus(PayClient.RequestType.SAVE_PASSES)
        .addOnSuccessListener { status ->
          if (status == PayApiAvailabilityStatus.AVAILABLE)
            layout.passContainer.visibility = View.VISIBLE
        }
        .addOnFailureListener {
          // Hide the button and optionally show an error message
        }
    }
    
  5. onCreate 方法中呼叫 fetchCanUseGoogleWalletApi 方法,檢查 Google Wallet API 是否可用
    // TODO: Check if the Google Wallet API is available
    fetchCanUseGoogleWalletApi()
    

執行應用程式時,UI 中現在應該會顯示「新增至 Google 錢包」按鈕。

「新增至 Google 錢包」按鈕現在會顯示在應用程式活動中

7. 建立一般票證物件

確認 Google 錢包 API 可用後,您就可以建立憑證,並提示使用者將憑證新增至錢包。建立使用者票證物件的流程有兩種。

在後端伺服器上建立票證物件

採用這種做法時,憑證物件會在後端伺服器上建立,並以簽署的 JWT 形式傳回給用戶端應用程式。如果使用者採用率高,這個方法最為合適,因為可確保物件存在,使用者才能將物件新增至錢包。

在使用者將票證加入錢包時建立票證物件

採用這種方法時,後端伺服器會定義票證物件,並編碼為已簽署的 JWT。接著,系統會在參照 JWT 的用戶端應用程式中,算繪「新增至 Google 錢包」按鈕。使用者選取按鈕後,系統會使用 JWT 建立票證物件。如果使用者採用程度不一或不明,就非常適合使用這項功能,因為這樣可避免建立通行證物件卻未使用。本程式碼研究室會使用這種方法。

  1. 開啟 backend/generic_pass.js 檔案。
  2. issuerId 的值改成 Google Pay 和錢包主控台中的核發機構 ID
    // TODO: Define Issuer ID
    let issuerId = 'ISSUER_ID';
    
  3. 在終端機或命令列提示字元中執行 generic_pass.js 檔案
    node generic_pass.js
    
  4. 將輸出權杖複製到剪貼簿或文字編輯器

程式碼執行時,會定義新的票證物件並嵌入 JWT。然後以您先前建立的服務帳戶金鑰簽署 JWT。這樣一來,系統就會驗證對 Google 錢包 API 的要求,因此不必在用戶端應用程式中儲存憑證。

aside 在實際工作環境中,後端系統會負責建立 JWT,並將其傳回給用戶端。在本程式碼研究室中,generic_pass.js 指令碼會模擬這項行為,並「傳回」權杖供您在用戶端應用程式中使用。

8. 將憑證新增至 Google 錢包

確認 Google 錢包 API 可用並建立簽署的 JWT 後,您就可以提示使用者將票證新增至錢包。在這個步驟中,您將為「新增至 Google 錢包」按鈕新增監聽器,透過 Google 錢包 API 將票證儲存至使用者的錢包。

  1. 開啟 app/src/main/CheckoutActivity.kt 檔案。
  2. token 的值替換為先前建立的 JWT
    // TODO: Save the JWT from the backend "response"
    private val token = "TOKEN"
    
  3. 建立類別屬性來儲存要求代碼
    // TODO: Add a request code for the save operation
    private val addToGoogleWalletRequestCode = 1000
    
  4. 為「新增至 Google 錢包」按鈕設定監聽器
    // TODO: Set an on-click listener on the "Add to Google Wallet" button
    addToGoogleWalletButton = layout.addToGoogleWalletButton.root
    
    addToGoogleWalletButton.setOnClickListener {
      walletClient.savePassesJwt(token, this, addToGoogleWalletRequestCode)
    }
    

使用者選取「新增至 Google 錢包」按鈕時,系統會呼叫 walletClient.savePassesJwt 方法。這個方法會提示使用者將新憑證物件新增至 Google 錢包。

9. 處理 savePassesJwt 結果

在本程式碼研究室的最後一個步驟中,您將設定應用程式來處理 walletClient.savePassesJwt 作業的結果。

  1. 開啟 app/src/main/CheckoutActivity.kt 檔案。
  2. 覆寫 onActivityResult 方法,使其包含下列程式碼
    // TODO: Handle the result
    override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
      super.onActivityResult(requestCode, resultCode, data)
    
      if (requestCode == addToGoogleWalletRequestCode) {
        when (resultCode) {
          RESULT_OK -> {
            // Pass saved successfully. Consider informing the user.
          }
    
          RESULT_CANCELED -> {
            // Save canceled
          }
    
          PayClient.SavePassesResult.SAVE_ERROR ->
            data?.let { intentData ->
              val errorMessage = intentData.getStringExtra(PayClient.EXTRA_API_ERROR_MESSAGE)
              // Handle error. Consider informing the user.
              Log.e("SavePassesResult", errorMessage.toString())
            }
    
          else -> {
            // Handle unexpected (non-API) exception
          }
        }
      }
    }
    

現在,您的應用程式可以處理下列情境:

  • 成功新增憑證
  • 使用者取消
  • 發生非預期的錯誤

執行應用程式,確認您可以新增票證,並如預期處理結果。

10. 恭喜

Generic 通行證物件範例。

恭喜!您已成功在 Android 裝置上整合 Google Wallet API!

瞭解詳情

如要查看完整的整合方式,請前往 google-pay/wallet-android-codelab GitHub 存放區。

建立票證並申請正式版存取權

準備好在正式環境中發行自己的票證後,請前往 Google Pay 和錢包主控台申請正式版存取權,並授權您的 Android 應用程式。

詳情請參閱「Android SDK 先決條件」。