使用 Google Pay 在網路上打造快速結帳體驗

Google Pay API 會運用使用者儲存在 Google 帳戶中的付款資訊,方便他們隨時隨地輕鬆付款。在本實驗室中,您將利用網頁專用的 Google Pay 用戶端程式庫,建立更快速、便利及安全的結帳程序,讓經過簡化的範例線上商店可提供更優質的結帳體驗,同時還能促成更多轉換並提高顧客滿意度。

「Auto T-Shirt Shop」是創新的商店,他們採用人工智慧的最新先進技術,並運用偏好風格、天氣、一年中的不同時節以及時尚趨勢等資訊,為使用者提供最適合購買的商品建議。

這間商店的參與度指標表現優異,但遺憾的是,這些指標也反映出結帳過程中的高放棄率。為解決這個問題,其中一位專案擁有者想到曾經觀看一部影片,內容展示 Google Pay 為類似網站帶來的出色成果,因此他們決定試試看,並且相信您能處理這項整合作業。

建構目標

本程式碼研究室會逐步說明如何將 Google Pay 整合至現有網站,包括判斷使用者能否使用 Google Pay 支援的付款方式付款、放置及設計付款按鈕,以及執行交易。

課程內容

  • 如何將 Google Pay 整合至現有結帳頁面
  • 如何選擇偏好的付款方式
  • 如何判斷使用者能否透過 Google Pay 付款

軟硬體需求

  • 可連上網際網路的電腦
  • JavaScript 的基本知識

在 glitch.com 上執行範例網站

為盡快協助您開始使用,本程式碼研究室已在 glitch.com 上提供。Glitch 是免費的網路環境,提供程式碼編輯器,以及主機和部署功能,可用於建構及提供網頁應用程式。

如要開始使用,請按一下下方按鈕,在 Glitch 上佈建新的開發環境,當中已設定好這個程式碼研究室的副本。

在 Glitch.com 上啟動開發環境

從現在起,您可以使用 Glitch 上的程式碼編輯器修改檔案。使用頂端的「Show」選單,選擇「In a New Window」,開始放送應用程式。

重點瀏覽範例網站

如您所見,存放區的檔案結構並不複雜。本程式碼研究室的主要目標是讓您能配合現有和未來的應用程式調整這項整合程序,不受您選擇使用的架構、程式庫或工具限制。

探索網站

這個示範市集在建立時,已忠實呈現現有或可能的應用程式外觀樣式,但尚未加入購買程序。事實上,即使我們建議您使用這個示範應用程式進行操作,您仍可以放心運用這個程式碼研究室,將 Google Pay 整合至自己現有的應用程式。

如果您尚未開啟示範網站以顯示其目前狀態,請立即開啟。如要這麼做,請點選「Show」(顯示) 按鈕 (如果您使用 Glitch),或開啟本機網路伺服器執行的網址。

示範網站的內容應該不令人意外,對吧?產品詳細資料頁面,提供相片、說明、一些選取器,以及會將您帶往虛構一般付款表單的按鈕。

本實驗室的目標是將這套流程,替換成由 Google Pay 技術輔助、只要按兩下滑鼠就能完成的使用體驗。

我們來規劃這項程序!

為了深入瞭解這項整合作業,我們將程序分成下列基本步驟:

  1. 載入程式庫
  2. 判斷能否透過 Google Pay 付款
  3. 顯示透過 Google Pay 付款的按鈕
  4. 建立及傳送付款要求
  5. 收集結果

新增 script 標記

如要開始使用 Google Pay API,首先需要載入 JavaScript 程式庫。如要這麼做,請在打算呼叫 API 的 HTML 檔案中加入 script 標記,並加入指向外部 JavaScript 程式庫的 src 屬性。

在本程式碼研究室中,請開啟 index.html 檔案。您應該會看到系統已為您加入指令碼標記:

<script async
  src="https://pay.google.com/gp/p/js/pay.js"
  onload="onGooglePayLoaded()">
</script>

除了 src 以外,您還新增了兩個其他屬性。

  • async 可讓指令碼與網頁其餘部分一起非同步載入及執行,因此不會影響文件的首次載入時間。
  • onload 可協助您延後執行依附於這個程式庫的程式碼,直到指令碼載入完成為止。完成後,系統會執行這個屬性中指定的函式。在本例中,函式為 onGooglePayLoaded

建立 API 用戶端例項

載入指令碼後,您就可以開始使用這個程式庫。首先,請為用於呼叫 Google Pay API 的用戶端物件建立例項。

編輯 index.js 檔案,這個檔案已是專案檔案結構的一部分。將 onGooglePayLoaded 函式替換為下列程式碼。

let googlePayClient;
function onGooglePayLoaded() {
  googlePayClient = new google.payments.api.PaymentsClient({
    environment: 'TEST'
  });
}

付款用戶端會透過 PaymentOptions 物件完成初始化。只要將 environment 設為 TEST,即可在整個整合過程中使用虛構付款資訊進行實驗。當您準備好建立支援實際交易的作業時,請將 environment 屬性更新為 PRODUCTION

Overview

我們現在已載入 Google Pay API JavaScript 用戶端程式庫。現在,請設定該函式,以便為我們發出 API 呼叫。

在本程式碼研究室的其餘部分,您將對 index.js 檔案進行下列所有程式碼變更。

架構

每次與 Google Pay API 通訊時,您都需要在要求中加入多個設定參數,例如指定的 API 版本。以本程式碼研究室為例,這個物件還會包含應用程式接受的付款方式相關資訊。最終結構如下所示:

{
  apiVersion: number,
  apiVersionMinor: number,
  allowedPaymentMethods: Array
}

allowedPaymentMethods 屬性採用一份付款方式清單。您必須為每種付款方式加入下列屬性:

{
  type: 'CARD',
  parameters: {
    allowedCardNetworks: Array.<string>,
    allowedAuthMethods: Array.<string>
  }
}

如要判斷使用者能否透過 Google Pay 付款,只需要 typeparameters 屬性。

設定付款方式

在本範例中,您只會接受一種設定,允許以權杖化和主要帳號 (PAN) 形式的 Mastercard 和 Visa 卡片付款。

您應在 index.js 中設定的配置如下:

const baseCardPaymentMethod = {
  type: 'CARD',
  parameters: {
    allowedCardNetworks: ['VISA','MASTERCARD'],
    allowedAuthMethods: ['PAN_ONLY','CRYPTOGRAM_3DS']
  }
};

總結

複習時間。

您已定義網站可接受的一種付款方式,且即將搭配 2.0 版的 API 運作。產生的設定應如下所示:

const baseCardPaymentMethod = {
  type: 'CARD',
  parameters: {
    allowedCardNetworks: ['VISA','MASTERCARD'],
    allowedAuthMethods: ['PAN_ONLY','CRYPTOGRAM_3DS']
  }
};

const googlePayBaseConfiguration = {
  apiVersion: 2,
  apiVersionMinor: 0,
  allowedPaymentMethods: [baseCardPaymentMethod]
};

現在您已完成基礎設定,接下來進行有趣的部分。

Google Pay 的其中一個主要目標是為使用者提供更快速便利的結帳體驗。這不僅適用於使用者能夠利用 Google Pay 結帳的情況,也適用於無法使用 Google Pay 的情況。您可以使用 isReadyToPay 要求,判斷透過 Google Pay 付款的完備性,並據以修改網站提供的體驗。

使用者能否透過 Google Pay 付款?

首先,您需要確認即將在網站上付款的特定使用者,能否透過 Google Pay 付款。您必須在這項要求中指定 Google Pay API 的版本和網站接受的付款方式。這正是先前步驟所定義基本設定物件包含的內容。

onGooglePayLoaded() 函式內的 index.js 中,貼上下列內容:

googlePayClient.isReadyToPay(googlePayBaseConfiguration)
  .then(function(response) {
    if(response.result) {
      createAndAddButton();
    } else {
      alert("Unable to pay using Google Pay");
    }
  }).catch(function(err) {
    console.error("Error determining readiness to use Google Pay: ", err);
  });

如果呼叫失敗或傳回不成功的回應,就不會採取與 Google Pay 相關的進一步動作。在此情況下,最適合採取的下一個步驟是,另外顯示支援其他付款方式的 UI。

另一方面,如果回應為成功,表示使用者可以透過 Google Pay 付款,享有其快速便利的優點。因此,您可以接著新增按鈕,在使用者啟用 (例如點選按鈕) 時啟動付款處理程序。

新增透過 Google Pay 付款的按鈕

雖然您可以使用任何符合 Google Pay 品牌宣傳指南的按鈕啟動付款程序,但我們建議您使用 Google Pay API 產生按鈕。這樣一來,您不僅能確保正確使用品牌宣傳指南,還能享有按鈕內建的其他改良功能,例如本地化。

如要產生按鈕,請使用 PaymentsClient 物件中的 createButton 方法,包括 ButtonOptions 來設定按鈕。

createAndAddButton() 函式內的 index.js 中,貼上下列內容:

function createAndAddButton() {

  const googlePayButton = googlePayClient.createButton({

    // currently defaults to black if default or omitted
    buttonColor: 'default',

    // defaults to long if omitted
    buttonType: 'long',

    onClick: onGooglePaymentsButtonClicked
  });

  document.getElementById('buy-now').appendChild(googlePayButton);
}

function onGooglePaymentsButtonClicked() {
  // TODO: Perform transaction
}

使用 createButton 時,唯一必要的屬性是 onClick,這項屬性可決定每次使用者啟動按鈕時要觸發的回呼物件或函式。buttonColorbuttonType 可讓您自訂按鈕外觀。請根據應用程式的主題和 UI 需求,相應調整這些值。

建立按鈕後,您只需將其新增至 DOM 內的適當節點即可。在本範例中,會使用以 buy-now 識別的 div 節點。

請留意,您同時定義了一個函式,用來處理按鈕點擊事件。在下一節中,您會使用這個函式要求付款方式。

準備付款要求

此時,您已載入 Google Pay API,並判定網站使用者可以透過 Google Pay 付款。因此,您已在 UI 中顯示 Google Pay 付款按鈕,使用者隨時可以啟動交易程序。現在應該載入最終付款畫面,其中包含不同已登入使用者的可用付款方式。

就像您先前定義 isReadyToPay 要求時執行的操作,這項呼叫也需要使用稍早定義的基本設定物件相關屬性 (apiVersionapiVersionMinorallowedPaymentMethods),以及幾個新屬性。這次有一個新屬性 tokenizationSpecification,以及僅供此要求使用的相關付款方式額外 parameters,此外,還需加入 transactionInfomerchantInfo

加入付款方式的額外必要資訊

首先,建立之前使用過的基本卡片付款方式副本。這個卡片付款方式現在需要 tokenizationSpecification 屬性,定義如何處理所選付款方式相關資料,以及實際交易所需的進一步資料需求:在本範例中,需要完整的帳單地址和電話號碼。

tokenizationSpecification 屬性

權杖化規格決定如何處理消費者所選付款方式,並用於完成交易。

系統支援兩種不同類型的處理策略。如果要在符合 PCI DSS 規範的伺服器內處理付款交易,請使用 DIRECT 規格類型。在本範例中,您使用支付閘道來處理付款,因此要設定 PAYMENT_GATEWAY 規格類型。

onGooglePaymentsButtonClicked() 函式內的 index.js 中,貼上下列內容:

const tokenizationSpecification = {
  type: 'PAYMENT_GATEWAY',
  parameters: {
    gateway: 'example',
    gatewayMerchantId: 'gatewayMerchantId'
  }
};

parameters 區段中,您可以從 Google Pay API 支援的供應商清單中指定閘道,以及個別閘道的其他必要設定。就本實驗室而言,使用 example 閘道便足以取得執行交易的測試結果。

其他參數

同樣地,為了成功執行交易,您現在可以提供更多詳細資料,補足要求所需相關資訊。請留意在本範例中,您需要新增 billingAddressRequiredbillingAddressParameters 屬性,表示本次交易需要使用者的完整帳單地址,加上電話號碼。

onGooglePaymentsButtonClicked() 函式內的 index.js 中,貼上下列內容:

const cardPaymentMethod = {
  type: 'CARD',
  tokenizationSpecification: tokenizationSpecification,
  parameters: {
    allowedCardNetworks: ['VISA','MASTERCARD'],
    allowedAuthMethods: ['PAN_ONLY','CRYPTOGRAM_3DS'],
    billingAddressRequired: true,
    billingAddressParameters: {
      format: 'FULL',
      phoneNumberRequired: true
    }
  }
};

加入交易相關資訊

transactionInfo 屬性包含交易的財務詳細資料物件,也就是價格貨幣代碼(ISO 4217 alpha 格式),以及價格狀態,視交易性質而定,可能是「最終」或「預估」 (例如,價格可能會因指定的運送地址而異)。

onGooglePaymentsButtonClicked() 函式內的 index.js 中,貼上下列內容:

const transactionInfo = {
  totalPriceStatus: 'FINAL',
  totalPrice: '123.45',
  currencyCode: 'USD'
};

加入商家相關資訊

付款要求會採用 merchantInfo 屬性底下,執行該要求的商家相關資訊。在本程式碼研究室中,您將著重於其中兩項資訊:

  • merchantId 是指網站獲得 Google 核准以正式版運作後,與您帳戶相關聯的 ID。請注意,使用 TEST 環境時,系統不會評估這項資訊。
  • merchantName 是網站或機構組織的使用者可見名稱,可以顯示在 Google Pay 付款畫面內,讓使用者瞭解是誰在要求這項操作。

onGooglePaymentsButtonClicked() 函式內的 index.js 中,貼上下列內容:

const merchantInfo = {
  // merchantId: '01234567890123456789', Only in PRODUCTION
  merchantName: 'Example Merchant Name'
};

要求付款資訊並處理結果

現在,將先前定義的設定合併至最終 paymentDataRequest 物件。

onGooglePaymentsButtonClicked() 函式內的 index.js 中,貼上下列內容:

const paymentDataRequest = Object.assign({}, googlePayBaseConfiguration, {
  allowedPaymentMethods: [cardPaymentMethod],
  transactionInfo: transactionInfo,
  merchantInfo: merchantInfo   
});

這時,您已萬事俱備,可向 Google Pay API 詢問有效的付款方式。要執行此操作,請使用 PaymentsClient 物件中的 loadPaymentData 方法,傳入您剛剛定義的設定。

onGooglePaymentsButtonClicked() 函式內的 index.js 中,貼上下列內容:

googlePayClient
  .loadPaymentData(paymentDataRequest)
  .then(function(paymentData) {
    processPayment(paymentData);
  }).catch(function(err) {
    // Log error: { statusCode: CANCELED || DEVELOPER_ERROR }
  });

呼叫 loadPaymentData 方法可觸發顯示 Google Pay 付款畫面的程序。如果沒有任何設定錯誤,您可以看到與目前登入帳戶相關聯的有效付款方式清單。

選取後,系統會關閉畫面,並使用 PaymentData 物件填入 Promise,當中包含所選付款方式的相關資訊:

{
  "apiVersionMinor": 0,
  "apiVersion": 2,
  "paymentMethodData": {
    "description": "Visa •••• 1234",
    "tokenizationData": {
      "type": "PAYMENT_GATEWAY",
      "token": "examplePaymentMethodToken"
    },
    "type": "CARD",
    "info": {
      "cardNetwork": "VISA",
      "cardDetails": "1234",
      "billingAddress": {
        "phoneNumber": ...,
        ...
      }
    }
  }
}

這項付款方式資訊現在可以用來執行實際交易。

function processPayment(paymentData) {
  // TODO: Send a POST request to your processor with the payload
  // https://us-central1-devrel-payments.cloudfunctions.net/google-pay-server 
  // Sorry, this is out-of-scope for this codelab.
  return new Promise(function(resolve, reject) {
    // @todo pass payment token to your gateway to process payment
    const paymentToken = paymentData.paymentMethodData.tokenizationData.token;
    console.log('mock send token ' + paymentToken + ' to payment processor');
    setTimeout(function() {
      console.log('mock response from processor');
      alert('done');
      resolve({});
    }, 800);
  });
}

到目前為止,我們探討的交易都是固定付款金額。但假設您想根據交易的特定屬性 (例如運送詳細資料) 更新價格,如要這麼做,請在建構用戶端時提供 paymentDataCallback 參數。您可以使用這個回呼處理交易變更,並據此套用修改內容。你可以監聽所選運送地址、運送選項和付款方式的變更。在本範例中,您將監聽所選運送選項的變更。首先,請定義包含所有運送資訊的變數,並修改 paymentDataRequest 以納入這些變數:

const shippingOptionParameters = {
  shippingOptions: [
    {
      id: 'shipping-001',
      label: '$1.99: Standard shipping',
      description: 'Delivered on May 15.'
    },
    {
      id: 'shipping-002',
      label: '$3.99: Expedited shipping',
      description: 'Delivered on May 12.'
    },
    {
      id: 'shipping-003',
      label: '$10: Express shipping',
      description: 'Delivered tomorrow.'
    }
  ]
};

// Shipping surcharges mapped to the IDs above.
const shippingSurcharges = {
  'shipping-001': 1.99,
  'shipping-002': 3.99,
  'shipping-003': 10
};

...

// Place inside of onGooglePaymentsButtonClicked()
paymentDataRequest.shippingAddressRequired = true;
paymentDataRequest.shippingOptionRequired = true;
paymentDataRequest.callbackIntents = ['SHIPPING_OPTION'];
paymentDataRequest.shippingOptionParameters =  shippingOptionParameters;

接著,您要修改 googlePayClient 的建立作業,加入 paymentDataCallback,每當付款作業中包含 callbackIntents 的修改內容時,系統就會呼叫這個函式。這個回呼包含屬性已變更的物件。您可以使用這些變更建構更新後的付款交易:

function onGooglePayLoaded() {
  googlePayClient = new google.payments.api.PaymentsClient({
    paymentDataCallbacks: { onPaymentDataChanged: paymentDataCallback },
    environment: 'TEST'
  });
  ...
}

function paymentDataCallback(callbackPayload) {

  const selectedShippingOptionId = callbackPayload.shippingOptionData.id;
  const shippingSurcharge = shippingSurcharges[selectedShippingOptionId];
  const priceWithSurcharges = 123.45 + shippingSurcharge;

  return {
    newTransactionInfo: {
      totalPriceStatus: 'FINAL',
      totalPrice: priceWithSurcharges.toFixed(2),
      totalPriceLabel: 'Total',
      currencyCode: 'USD',
      displayItems: [
        {
          label: 'Subtotal',
          type: 'SUBTOTAL',
          price: priceWithSurcharges.toFixed(2),
        },
        {
          label: 'Shipping',
          type: 'LINE_ITEM',
          price: shippingSurcharge.toFixed(2),
          status: 'FINAL'
        }]
    }
  }
};

在回呼中傳回這個新物件後,付款畫面中顯示的資訊就會更新,反映交易的修改內容。

測試整合功能是否正常運作後,您可以進一步預先擷取付款設定,前提是您已確定可以使用 Google Pay。使用者啟用 (點選) Google Pay 付款按鈕前,系統會執行這項操作。

預先擷取付款資料後,當使用者決定付款時,工作表載入所需的資訊就已備妥,可大幅縮短載入時間,進而提升整體體驗。

這個方法預期會收到與 loadPaymentData 相同的輸入內容。也就是說,您可以使用先前定義的相同 paymentDataRequest 物件。現在,只要在 isReadyToPay 成功傳回後,判斷使用者可以透過 Google Pay 付款,即可加入對預先擷取方法的呼叫:

googlePayClient.isReadyToPay(googlePayBaseConfiguration)
  .then(function(response) {
    if(response.result) {
      createAndAddButton();
      googlePayClient.prefetchPaymentData(paymentDataRequest);
    }
  });

就這樣,您在使用者點選按鈕前預先擷取付款資料,縮短了載入時間。網站的回應速度提升後,轉換率應該也會提高。

您已將 Google Pay API 順利整合至本程式碼研究室的範例網站或自己的應用程式。

要正式發布應用程式前,別忘了先查看整合作業檢查清單。完成檢查清單並經過審查後,您會收到商家 ID,用於加進用戶端設定。同樣地,如果您打算使用 (或已經使用) 第三方付款處理方或閘道,請參考 Google Pay 支援的供應商清單並自行完成設定。如要直接整合 Google Pay,請參閱本主題的說明文件部分

涵蓋內容

  • 在網站中匯入及設定 Google API。
  • 判斷 API 的支援情形,並據以採取因應措施。
  • 新增按鈕,讓使用者可透過 Google Pay 付款。
  • 載入及處理先前儲存的使用者付款資訊。
  • 預先擷取付款資訊,縮短載入時間。

後續步驟

  • 進一步瞭解 Google Pay
  • 查看整合檢查清單,並取得商家識別碼。
  • 瞭解兩種不同類型的整合方式,決定哪種方式最適合您的應用程式:直接整合,或者使用支付閘道或處理方。
  • 設定「授權付款」,啟動付款程序並確認付款的授權狀態。(授權或拒絕)

瞭解詳情

您覺得這實用嗎?

非常實用! 還算符合預期。 不太實用。

您想參考其他程式碼研究室,瞭解其他類型的整合方式 (Android、直接整合、會員 API) 嗎?

當然,那就再好不過了! 我只需要目前的說明。