Payment Handler API

可用性有限

此特性不是基线特性,因为它在一些最广泛使用的浏览器中不起作用。

安全上下文: 此功能仅在安全上下文(HTTPS)中可用,且支持此功能的浏览器数量有限。

实验性: 这是一项实验性技术
在生产中使用此技术之前,请仔细检查浏览器兼容性表格

注意:此功能在 Web Workers 中可用。

Payment Handler API 提供了标准化的功能集,供 Web 应用程序直接处理支付,而无需重定向到单独的支付处理网站。

当商家网站通过 Payment Request API 发起支付时,Payment Handler API 会负责发现适用的支付应用程序,将它们作为选项呈现给用户,并在用户做出选择后打开一个支付处理窗口,以便用户输入其支付详细信息,并处理与支付应用程序的支付交易。

与支付应用程序的通信(授权、支付凭证传递)通过 Service Workers 进行处理。

概念与用法

在商家网站上,支付请求是通过构造一个新的 PaymentRequest 对象来发起的

js
const request = new PaymentRequest(
  [
    {
      supportedMethods: "https://bobbucks.dev/pay",
    },
  ],
  {
    total: {
      label: "total",
      amount: { value: "10", currency: "USD" },
    },
  },
);

supportedMethods 属性指定了一个 URL,代表商家支持的支付方式。要使用多种支付方式,您需要将它们指定在一个对象数组中,如下所示:

js
const request = new PaymentRequest(
  [
    {
      supportedMethods: "https://alicebucks.dev/pay",
    },
    {
      supportedMethods: "https://bobbucks.dev/pay",
    },
  ],
  {
    total: {
      label: "total",
      amount: { value: "10", currency: "USD" },
    },
  },
);

使支付应用程序可用

在支持的浏览器中,该过程首先从每个 URL 请求一个支付方式清单文件。支付方式清单文件通常命名为 payment-manifest.json(确切名称可以随意命名),并应具有以下结构:

json
{
  "default_applications": ["https://bobbucks.dev/manifest.json"],
  "supported_origins": ["https://alicepay.friendsofalice.example"]
}

给定一个支付方式标识符,例如 https://bobbucks.dev/pay,浏览器会

  1. 开始加载 https://bobbucks.dev/pay 并检查其 HTTP 标头。
    1. 如果找到一个带有 rel="payment-method-manifest"Link 标头,它将下载该位置的支付方式清单(有关详细信息,请参阅 Optionally route the browser to find the payment method manifest in another location)。
    2. 否则,将 https://bobbucks.dev/pay 的响应体解析为支付方式清单。
  2. 将下载的内容作为 JSON 进行解析,其中包含 default_applicationssupported_origins 成员。

这些成员具有以下用途:

  • default_applications 告诉浏览器,如果没有安装默认支付应用程序,可以在哪里找到可以使用 BobBucks 支付方式的默认支付应用程序。
  • supported_origins 告诉浏览器,在需要时,哪些其他支付应用程序被允许处理 BobBucks 支付。如果它们已安装在设备上,它们将与默认应用程序一起作为替代支付选项呈现给用户。

从支付方式清单中,浏览器获取默认支付应用程序的 Web App Manifest 文件的 URL,该文件可以随意命名,并具有以下类似结构:

json
{
  "name": "Pay with BobBucks",
  "short_name": "BobBucks",
  "description": "This is an example of the Payment Handler API.",
  "icons": [
    {
      "src": "images/manifest/icon-192x192.png",
      "sizes": "192x192",
      "type": "image/png"
    },
    {
      "src": "images/manifest/icon-512x512.png",
      "sizes": "512x512",
      "type": "image/png"
    }
  ],
  "serviceworker": {
    "src": "service-worker.js",
    "scope": "/",
    "use_cache": false
  },
  "start_url": "/",
  "display": "standalone",
  "theme_color": "#3f51b5",
  "background_color": "#3f51b5",
  "related_applications": [
    {
      "platform": "play",
      "id": "com.example.android.samplepay",
      "min_version": "1",
      "fingerprints": [
        {
          "type": "sha256_cert",
          "value": "4C:FC:14:C6:97:DE:66:4E:66:97:50:C0:24:CE:5F:27:00:92:EE:F3:7F:18:B3:DA:77:66:84:CD:9D:E9:D2:CB"
        }
      ]
    }
  ]
}

当商家应用程序响应用户手势调用 PaymentRequest.show() 方法时,浏览器会使用在每个清单中找到的 nameicons 信息,在浏览器提供的 Payment Request UI 中向用户展示支付应用程序。

  • 如果存在多个支付应用程序选项,将向用户展示一个选项列表供其选择。选择一个支付应用程序将启动支付流程,这会导致浏览器在需要时即时(JIT)安装 Web 应用程序,并注册 serviceworker 成员中指定的 Service Worker,以便其可以处理支付。
  • 如果只有一个支付应用程序选项,PaymentRequest.show() 方法将与此支付应用程序启动支付流程,并在必要时即时(JIT)安装它,如上所述。这是一种优化,以避免向用户展示只有一个支付应用程序选项的列表。

注意:如果支付应用程序清单中的 prefer_related_applications 设置为 true,浏览器将启动 related_applications 中指定的平台特定支付应用程序(如果可用)来处理支付,而不是 Web 支付应用程序。

有关更多详细信息,请参阅 Serve a web app manifest

检查支付应用程序是否准备好付款

Payment Request API 的 PaymentRequest.canMakePayment() 方法在支付应用程序在客户设备上可用时返回 true,这意味着已发现支持该支付方式的支付应用程序,并且平台特定的支付应用程序已安装,或者基于 Web 的支付应用程序已准备好注册。

js
async function checkCanMakePayment() {
  // …

  const canMakePayment = await request.canMakePayment();
  if (!canMakePayment) {
    // Fallback to other means of payment or hide the button.
  }
}

Payment Handler API 增加了一个额外的机制来准备处理支付。当商家网站调用 PaymentRequest() 构造函数时,会向支付应用程序的 Service Worker 触发 canmakepayment 事件,以检查它是否已准备好处理支付。然后,Service Worker 可以使用 CanMakePaymentEvent.respondWith() 方法进行适当响应。

js
self.addEventListener("canmakepayment", (e) => {
  e.respondWith(
    new Promise((resolve, reject) => {
      someAppSpecificLogic()
        .then((result) => {
          resolve(result);
        })
        .catch((error) => {
          reject(error);
        });
    }),
  );
});

respondWith() 返回的 Promise 会解析为一个布尔值,以指示它是否已准备好处理支付请求(true),或者未准备好(false)。

处理支付

在调用 PaymentRequest.show() 方法后,会向支付应用程序的 Service Worker 触发一个 paymentrequest 事件。此事件在支付应用程序的 Service Worker 中被监听,以开始支付过程的下一阶段。

js
let payment_request_event;
let resolver;
let client;

// `self` is the global object in service worker
self.addEventListener("paymentrequest", async (e) => {
  if (payment_request_event) {
    // If there's an ongoing payment transaction, reject it.
    resolver.reject();
  }
  // Preserve the event for future use
  payment_request_event = e;

  // …
});

当收到 paymentrequest 事件时,支付应用程序可以通过调用 PaymentRequestEvent.openWindow() 来打开一个支付处理窗口。支付处理窗口将向客户展示一个支付应用程序界面,他们可以在其中进行身份验证、选择配送地址和选项,以及授权支付。

支付处理完成后,使用 PaymentRequestEvent.respondWith() 将支付结果传回商家网站。

有关此阶段的更多详细信息,请参阅 Receive a payment request event from the merchant

管理支付应用程序功能

一旦支付应用程序的 Service Worker 注册成功,您就可以使用 Service Worker 的 PaymentManager 实例(通过 ServiceWorkerRegistration.paymentManager 访问)来管理支付应用程序功能的各个方面。

例如

js
navigator.serviceWorker.register("serviceworker.js").then((registration) => {
  registration.paymentManager.userHint = "Card number should be 16 digits";

  registration.paymentManager
    .enableDelegations(["shippingAddress", "payerName"])
    .then(() => {
      // …
    });

  // …
});
  • PaymentManager.userHint 用于为浏览器提供提示,以在 Payment Handler UI 中与支付应用程序的名称和图标一起显示。
  • PaymentManager.enableDelegations() 用于将提供各种必需支付信息部分的责任委托给支付应用程序,而不是从浏览器收集(例如,通过自动填充)。

接口

CanMakePaymentEvent

用于 canmakepayment 事件的事件对象,该事件在支付应用程序的 Service Worker 成功注册后触发,以表明它已准备好处理付款。

PaymentManager

用于管理支付应用程序功能的各个方面。通过 ServiceWorkerRegistration.paymentManager 属性访问。

PaymentRequestEvent Experimental

用于 paymentrequest 事件的事件对象,该事件在商家网站通过 PaymentRequest.show() 方法发起支付流程后,在支付应用程序的 Service Worker 上触发。

其他接口的扩展

canmakepayment 事件

当支付应用程序的 ServiceWorkerGlobalScope 成功注册后触发,以表明它已准备好处理付款。

paymentrequest 事件

当商家网站通过 PaymentRequest.show() 方法发起支付流程后,在支付应用程序的 ServiceWorkerGlobalScope 上触发。

ServiceWorkerRegistration.paymentManager

返回支付应用程序的 PaymentManager 实例,用于管理各种支付应用程序功能。

规范

规范
Payment Handler API
# the-paymentrequestevent

浏览器兼容性

另见