Google Pay API for Web 101:基本概念

1. 簡介

建構項目

完成本程式碼研究室後,您將擁有可運作且整合 Google Pay 的最低可行網站。這個專案會擷取付款權杖,並傳送給付款服務供應商進行處理。

課程內容

  • 如何載入及設定 Google Pay API
  • 如何顯示 Google Pay 按鈕及處理點擊
  • 如何向 Google Pay 索取付款權杖

軟硬體需求

  • 您選擇的文字編輯器,用於編輯 HTML 和 JavaScript 檔案。
  • Google Chrome 網路瀏覽器,或其他測試本機網站的方法。
  • 如要進行正式發布,您需要使用 Google Pay merchantId。註冊 Google Pay 和錢包主控台只需要一分鐘,建議您現在就完成註冊。

使用 Project IDX 進行操作

在 IDX 中開啟這個程式碼研究室

2. 建立 HTML 網頁

建立專案檔案

  1. 在電腦上建立名為 gpay-web-101 的資料夾,並在該資料夾中建立兩個名為 index.htmlmain.js 的空白文字檔案。目錄結構應如下所示:
    gpay-web-101/
      index.html
      main.js
    
  2. 在您選擇的 IDE 中開啟 index.html,然後新增下列程式碼:
    <!doctype html>
    <html lang="en">
    
    <head>
      <meta charset="UTF-8" />
      <meta name="viewport" content="width=device-width, initial-scale=1.0" />
      <title>Google Pay API for Web 101</title>
    </head>
    
    <body>
      <div id="gpay-container"></div>
      <p>Transaction info and errors will be logged to the console.</p>
      <script type="text/javascript" src="main.js"></script>
      <script
        async src="https://pay.google.com/gp/p/js/pay.js"
        onload="onGooglePayLoaded()">
      </script>
    </body>
    
    </html>
    

程式碼說明

  1. 系統會在頁面中新增 ID 為 gpay-container 的空白 DIV。這個 DOM 元素將是新增 Google Pay 按鈕的父項元素。您可以在適當位置將這個元素放置在網站版面配置中。
  2. main.js 指令碼標記會放在 DOM 中的 gpay-container 元素之後。這項操作有助於確保容器 DIV 在 main.js 查詢前出現在 DOM 中。此外,指令碼是同步的,可確保在 pay.js 載入前載入,因為 onGooglePayLoaded() 方法必須在載入完成前存在。還有其他方法可以達到相同效果,但這裡不會討論這些方法。
  3. 最後,pay.js 會以非同步方式載入,並將 onGooglePayLoaded() 設為 onload 處理常式。這個方法會在 main.js 中定義。

3. 設定 Google Pay

Google Pay 付款要求需要要求物件。此處定義為 baseGooglePayRequest 的物件包含所有要求的最低共同設定。我們會在這個程式碼研究室中,根據提出的要求加入其他設定。

將 Google Pay 設定常數新增至空白的 main.js 檔案:

//=============================================================================
// Configuration
//=============================================================================

// The DOM element that the Google Pay button will be rendered into
const GPAY_BUTTON_CONTAINER_ID = 'gpay-container';

// Update the `merchantId` and `merchantName` properties with your own values.
// Your real info is required when the environment is `PRODUCTION`.
const merchantInfo = {
  merchantId: '12345678901234567890',
  merchantName: 'Example Merchant'
};

// This is the base configuration for all Google Pay payment data requests.
const baseGooglePayRequest = {
  apiVersion: 2,
  apiVersionMinor: 0,
  allowedPaymentMethods: [
    {
      type: 'CARD',
      parameters: {
        allowedAuthMethods: [
          "PAN_ONLY", "CRYPTOGRAM_3DS"
        ],
        allowedCardNetworks: [
          "AMEX", "DISCOVER", "INTERAC", "JCB", "MASTERCARD", "VISA"
        ]
      },
      tokenizationSpecification: {
        type: 'PAYMENT_GATEWAY',
        parameters: {
          gateway: 'example',
          gatewayMerchantId: 'exampleGatewayMerchantId'
        }
      }
    }
  ],
  merchantInfo
};

// Prevent accidental edits to the base configuration. Mutations will be
// handled by cloning the config using deepCopy() and modifying the copy.
Object.freeze(baseGooglePayRequest);

程式碼說明

  1. 將常數變數 GPAY_BUTTON_CONTAINER_ID 設為 HTML 頁面中用於 Google Pay 按鈕的父項容器 DOM 元素 ID。
  2. 建立設定物件 baseGooglePayRequest,並為應用程式設定相關設定。您可以在參考說明文件中找到每個屬性和值。這個範例中顯示的值不一定完全符合您的需求,請仔細檢查。
  3. 請使用您自己的值更新 merchantIdmerchantName 屬性。在 TEST 環境中,這些欄位為選用。

資源

4. 新增付款客戶

付款用戶端用於提出付款要求和註冊回呼。在本程式碼研究室中,我們只會提出付款要求。此外,您可以設定 PaymentDataCallbacks,以便在付款資料或授權變更時處理。不過,本程式碼研究室不會涵蓋這些進階主題。

將以下用戶端程式碼附加至 main.js 底部:

//=============================================================================
// Google Payments client singleton
//=============================================================================

let paymentsClient = null;

function getGooglePaymentsClient() {
  if (paymentsClient === null) {
    paymentsClient = new google.payments.api.PaymentsClient({
      environment: 'TEST',
      merchantInfo,
      // todo: paymentDataCallbacks (codelab pay-web-201)
    });
  }

  return paymentsClient;
}

程式碼說明

  1. paymentsClient 變數會在建立後保留用戶端的例項。程式碼不會直接存取變數,而是一律透過 getGooglePaymentsClient() 方法存取。
  2. getGooglePaymentsClient() 方法會檢查用戶端是否已例項化,並傳回該例項。如果先前未對其進行例項化,系統會建立、儲存及傳回一個。這個方法可確保在整個指令碼生命週期中,只建立及使用一個例項。
  3. 如要將用戶端例項化,請叫用 PaymentsClient() 方法。在這個範例中,我們會告訴用戶端我們處於 TEST 環境。替代做法是 PRODUCTION。不過,TEST 是預設值,可以省略。

5. 新增輔助程式

以下輔助函式會在稍後的指令碼中使用,我們加入這些函式只是為了改善程式碼的可讀性和可維護性。

將輔助函式附加至 main.js 的底部:

//=============================================================================
// Helpers
//=============================================================================

const deepCopy = (obj) => JSON.parse(JSON.stringify(obj));

function renderGooglePayButton() {
  const button = getGooglePaymentsClient().createButton({
    onClick: onGooglePaymentButtonClicked
  });

  document.getElementById(GPAY_BUTTON_CONTAINER_ID).appendChild(button);
}

程式碼說明

  1. deepCopy() 是一種公用程式,可使用 JSON 序列化和反序列化功能,為提供的物件建立深層複本。這是複製物件的便利方法,不必擔心共用參照。
  2. renderGooglePayButton() 是一種公用程式,可叫用 createButton() 程式庫方法來顯示 Google Pay 按鈕。傳遞的引數是一組選項,可定義按鈕的行為方式,例如註冊 onGooglePaymentButtonClicked() 函式來處理按鈕點擊。

6. 新增事件處理常式

在這個指令碼中,我們會設定兩個事件處理常式。第一個會在 pay.js 程式庫載入完成時呼叫,另一個則會在使用者點選 Google Pay 按鈕時呼叫。

將事件處理常式附加至 main.js 底部:

//=============================================================================
// Event Handlers
//=============================================================================

function onGooglePayLoaded() {
  const req = deepCopy(baseGooglePayRequest);

  getGooglePaymentsClient()
    .isReadyToPay(req)
    .then(function(res) {
      if (res.result) {
        renderGooglePayButton();
      } else {
        console.log("Google Pay is not ready for this user.");
      }
    })
    .catch(console.error);
}

function onGooglePaymentButtonClicked() {
  // Create a new request data object for this request
  const req = {
    ...deepCopy(baseGooglePayRequest),
    transactionInfo: {
      countryCode: 'US',
      currencyCode: 'USD',
      totalPriceStatus: 'FINAL',
      totalPrice: (Math.random() * 999 + 1).toFixed(2),
    },
    // todo: callbackIntents (codelab gpay-web-201)
  };

  // Write request object to console for debugging
  console.log(req);

  getGooglePaymentsClient()
    .loadPaymentData(req)
    .then(function (res) {
      // Write response object to console for debugging
      console.log(res);
      // @todo pass payment token to your gateway to process payment
      // @note DO NOT save the payment credentials for future transactions
      paymentToken = res.paymentMethodData.tokenizationData.token;
    })
    .catch(console.error);
}

程式碼說明

  1. pay.js 指令碼已完成 HTML 檔案中定義的載入作業時,系統就會叫用 onGooglePayLoaded()。系統會叫用 isReadyToPay() 方法,判斷是否要顯示 Google Pay 按鈕。如果消費者已準備好付款 (也就是已在 Google 錢包中新增付款方式),系統就會顯示 Google Pay 按鈕。
  2. 點選 Google Pay 按鈕時會叫用 onGooglePaymentButtonClicked()。這個方法會叫用用來擷取付款權杖的 loadPaymentData() 程式庫方法。取得付款權杖後,請將權杖傳送至付款閘道,以便處理交易。transactionInfo 會說明應透過此按鈕點擊來處理的交易。

7. 結語

恭喜您完成本程式碼研究室!您已瞭解如何將 Google Pay API 整合至網站。

執行專案

使用 Google Chrome 進行測試

使用 Google Chrome 網路瀏覽器,透過 Chrome 主選單中的「檔案」>「開啟檔案...」開啟 index.html。以這種方式開啟專案時,Chrome 會執行 main.js。其他網路瀏覽器可能不允許執行 JavaScript。

– 或 –

使用本機網路伺服器進行測試

如果您已安裝 Python,請在根目錄 pay-web-101 資料夾中的終端機提示中執行 python3 -m http.server

$ cd /your/path/to/pay-web-101
$ python3 -m http.server
Serving HTTP on :: port 8000 (http://[::]:8000/) ...

然後前往 http://localhost:8000 造訪您的網站。

下一步該做什麼?

其他資源