Google Pay API for Web 101:基础知识

1. 简介

构建内容

完成此 Codelab 后,您将获得一个最低可行性网站,其中包含可正常运行的 Google Pay 集成。此项目会检索付款令牌,该令牌可能会发送给支付服务提供商进行处理。

学习内容

  • 如何加载和配置 Google Pay API
  • 如何显示 Google Pay 按钮并处理点击事件
  • 如何从 Google Pay 请求支付令牌

所需条件

  • 您选择的文本编辑器,用于修改 HTML 和 JavaScript 文件。
  • Google Chrome 网络浏览器,或用于测试本地网站的其他方法。
  • 对于生产环境,您需要 Google Pay merchantId。在 Google Pay & Wallet Console 中注册只需一分钟,不妨现在就完成注册。

使用 Firebase Studio 逐步操作

在 Firebase Studio 中打开

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 元素之后。这是必需的,可确保在 main.js 查询容器 DIV 之前,该 DIV 已存在于 DOM 中。此外,该脚本是同步的,可确保在 pay.js 加载之前加载,因为 onGooglePayLoaded() 方法必须在加载完成之前存在。还有其他方法可以实现相同的效果,但这里不作讨论。
  3. 最后,pay.js 会异步加载,并将 onGooglePayLoaded() 配置为 onload 处理程序。此方法将在 main.js 中定义。

3. 配置 Google Pay

Google Pay 付款请求需要提供请求对象。此处定义为 baseGooglePayRequest 的对象包含所有请求的最低通用设置。系统会根据所提出的请求添加其他设置,我们将在本 Codelab 中对此进行回顾。

将 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. 添加支付客户端

支付客户端用于发出付款请求和注册回调。在此 Codelab 中,我们将仅发出付款请求。此外,您还可以配置 PaymentDataCallbacks,以处理付款数据或授权发生变化的情况。不过,本 Codelab 不会介绍这些高级主题。

将此客户端代码附加到 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. 总结

恭喜您完成此 Codelab!您已了解如何将 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

后续步骤

其他资源