使用 Service Worker 处理可选的付款信息

如何使您基于网络的付款应用适应网络付款,并为客户提供更好的用户体验。

基于网络的付款应用程序收到付款请求并进行付款后 事务,Service Worker 将执行操作 作为商家与付款应用之间的通信中心。这篇帖子 说明了付款应用如何传递有关付款方式的信息, 送货地址或联系信息。

使用 Service Worker 处理可选付款信息
使用 Service Worker 处理可选付款信息

将付款方式变更告知商家

付款应用可以支持多种付款方式及不同的付款方式。

客户 付款方式 付款方式
A 信用卡发卡机构 1 ****1234
信用卡发卡机构 1 ****4242
X 银行 ******123
B 信用卡发卡机构 2 ****5678
X 银行 ******456

例如,在上表中,客户 A 基于网络的电子钱包有两笔赠金 卡和一个银行账户。在此例中,应用会处理三个 付款方式(****1234****4242******123)和两笔付款 方式(信用卡发卡行 1 和银行 X)。在付款交易中, 应用可以让客户选择一种付款方式并使用该付款方式进行付款 。

付款方式选择器界面
付款方式选择器界面

付款应用可以告知商家客户客户的付款方式 。当 商家想要针对特定付款方式品牌投放折扣广告系列, 示例。

借助 Payment Handler API,付款应用可以发送“付款方式更改” 事件通过 Service Worker 发送给商家,以通知新付款方式 标识符。Service Worker 应调用 使用新付款方式PaymentRequestEvent.changePaymentMethod() 信息。

将付款方式变更告知商家
将付款方式变更告知商家

付款应用可以将 methodDetails 对象作为可选的第二个参数传递 价格为 PaymentRequestEvent.changePaymentMethod()。此对象可以包含 商家处理更改所需的任意付款方式详细信息 事件。

[付款处理程序] service-worker.js

…
// Received a message from the frontend
self.addEventListener('message', async e => {
  let details;
  try {
    switch (e.data.type) {
      …
      case 'PAYMENT_METHOD_CHANGED':
        const newMethod = e.data.paymentMethod;
        const newDetails = e.data.methodDetails;
        // Redact or check that no sensitive information is passed in
        // `newDetails`.
        // Notify the merchant of the payment method change
        details =
          await payment_request_event.changePaymentMethod(newMethod, newDetails);
      …

商家收到来自付款的 paymentmethodchange 事件时 请求 API,他们可以更新付款明细,并在响应中提供 PaymentDetailsUpdate 对象。

[商家]

request.addEventListener('paymentmethodchange', e => {
  if (e.methodName === 'another-pay') {
    // Apply $10 discount for example.
    const discount = {
      label: 'special discount',
      amount: {
        currency: 'USD',
        // The value being string complies the spec
        value: '-10.00'
      }
    };
    let total = 0;
    details.displayItems.push(discount);
    for (let item of details.displayItems) {
     total += parseFloat(item.amount.value);
    }
    // Convert the number back to string
    details.total.amount.value = total.toString();
  }
  // Pass a promise to `updateWith()` and send updated payment details
  e.updateWith(details);
});

商家响应后,承诺的 PaymentRequestEvent.changePaymentMethod() 将会解析为 PaymentRequestDetailsUpdate 对象。

[付款处理程序] service-worker.js

…
        // Notify the merchant of the payment method change
        details = await payment_request_event.changePaymentMethod(newMethod, newDetails);
        // Provided the new payment details,
        // send a message back to the frontend to update the UI
        postMessage('UPDATE_REQUEST', details);
        break;
…

使用该对象更新前端的界面。请参阅反映 付款信息

将送货地址更改告知商家

付款应用可向商家提供客户的送货地址 。

这对商家非常有用,因为他们可以将地址收集委托给 付款应用。而且,由于地址数据将在标准 数据格式时, 商家可以收到结构一致的送货地址。

此外,客户还可以向自己的 首选付款应用,并将其重复用于不同的商家。

送货地址选择器界面
送货地址选择器界面

付款应用可以提供一个界面,供用户修改送货地址或选择 客户在付款交易中的预注册地址信息。 在临时确定送货地址时,付款应用可以允许 被隐去的地址信息的商家会知晓。这为商家提供了 多项优势:

  • 商家可以确定客户是否符合地区限制 配送商品(例如,仅限国内)。
  • 商家可以根据配送所在地区更改配送选项列表。 送货地址(例如国际常规或快递)。
  • 商家可以根据地址应用新的运费,并更新 总价。

借助 Payment Handler API,付款应用可以发送“送货地址” 更改”事件传递给商家,以通知新配送 地址。Service Worker 应调用 PaymentRequestEvent.changeShippingAddress() 使用新地址 对象

将送货地址更改告知商家
将送货地址更改告知商家

[付款处理程序] service-worker.js

...
// Received a message from the frontend
self.addEventListener('message', async e => {
  let details;
  try {
    switch (e.data.type) {
      …
      case 'SHIPPING_ADDRESS_CHANGED':
        const newAddress = e.data.shippingAddress;
        details =
          await payment_request_event.changeShippingAddress(newAddress);
      …

商家将收到“付款”页面中的 shippingaddresschange 事件 请求 API,以便它们使用更新后的 PaymentDetailsUpdate 进行响应。

[商家]

request.addEventListener('shippingaddresschange', e => {
  // Read the updated shipping address and update the request.
  const addr = request.shippingAddress;
  const details = getPaymentDetailsFromShippingAddress(addr);
  // `updateWith()` sends back updated payment details
  e.updateWith(details);
});

商家响应后,promise PaymentRequestEvent.changeShippingAddress() 将会解析为 PaymentRequestDetailsUpdate 对象。

[付款处理程序] service-worker.js

…
        // Notify the merchant of the shipping address change
        details = await payment_request_event.changeShippingAddress(newAddress);
        // Provided the new payment details,
        // send a message back to the frontend to update the UI
        postMessage('UPDATE_REQUEST', details);
        break;
…

使用该对象更新前端的界面。请参阅反映 付款信息

通知商家送货方式的变化

配送选项是商家将购买的商品运送给客户的送货方式。典型的配送方式包括:

  • 免运费
  • 极速配送
  • 全球送货
  • 优质跨国送货服务

每种方案都有各自的费用。通常,更快的方法/选项开销更高。

使用 Payment Request API 的商家可以将此选择委托给付款 应用。付款应用可以使用这些信息来构建界面,并让 客户选择送货方式。

配送选项选择器界面
配送选项选择器界面

在商家的 Payment Request API 中指定的配送选项列表为 作为 PaymentRequestEvent

[商家]

const request = new PaymentRequest([{
  supportedMethods: 'https://bobbucks.dev/pay',
  data: { transactionId: '****' }
}], {
  displayItems: [{
    label: 'Anvil L/S Crew Neck - Grey M x1',
    amount: { currency: 'USD', value: '22.15' }
  }],
  shippingOptions: [{
    id: 'standard',
    label: 'Standard',
    amount: { value: '0.00', currency: 'USD' },
    selected: true
  }, {
    id: 'express',
    label: 'Express',
    amount: { value: '5.00', currency: 'USD' }
  }],
  total: {
    label: 'Total due',
    amount: { currency: 'USD', value : '22.15' }
  }
}, {  requestShipping: true });

付款应用可以告知商家客户客户哪种配送选项 。这对商家和客户都很重要,因为 更改运费选项也会更改总价商家需要 以了解稍后付款验证的最新价格,以及 客户也需要了解这项更改

借助 Payment Handler API,付款应用可以发送“配送选项” 更改”事件传递给商家。Service Worker 调用 PaymentRequestEvent.changeShippingOption() 新的运费选项 ID。

通知商家送货方式的变化
通知商家送货方式的变化

[付款处理程序] service-worker.js

…
// Received a message from the frontend
self.addEventListener('message', async e => {
  let details;
  try {
    switch (e.data.type) {
      …
      case 'SHIPPING_OPTION_CHANGED':
        const newOption = e.data.shippingOptionId;
        details =
          await payment_request_event.changeShippingOption(newOption);
      …

商家将收到“付款”页面中的 shippingoptionchange 事件 请求 API。商家应使用这些信息更新总价 然后以更新后的 PaymentDetailsUpdate

[商家]

request.addEventListener('shippingoptionchange', e => {
  // selected shipping option
  const shippingOption = request.shippingOption;
  const newTotal = {
    currency: 'USD',
    label: 'Total due',
    value: calculateNewTotal(shippingOption),
  };
  // `updateWith()` sends back updated payment details
  e.updateWith({ total: newTotal });
});

商家响应后,承诺的 PaymentRequestEvent.changeShippingOption() 将会解析为 PaymentRequestDetailsUpdate 对象。

[付款处理程序] service-worker.js

…
        // Notify the merchant of the shipping option change
        details = await payment_request_event.changeShippingOption(newOption);
        // Provided the new payment details,
        // send a message back to the frontend to update the UI
        postMessage('UPDATE_REQUEST', details);
        break;
…

使用该对象更新前端的界面。请参阅反映 付款信息

体现更新后的付款明细

商家完成付款明细更新后,promise 会返回 来自.changePaymentMethod().changeShippingAddress().changeShippingOption() 会通过常见错误进行解析 PaymentRequestDetailsUpdate 对象。付款处理程序可以使用结果来反映更新后的总价 和运费选项

商家可能会出于以下几种原因返回错误:

  • 付款方式不受支持。
  • 送货地址不在支持的地区范围。
  • 送货地址包含无效信息。
  • 无法为提供的送货地址选择此运费选项,或 一些其他原因。

使用以下属性来反映错误状态:

  • error:直观易懂的错误字符串。这是最适合显示的字符串 客户。
  • shippingAddressErrorsAddressErrors 对象,该对象包含每个地址属性的详细错误字符串。这是 如果您想打开一个表单来让客户修改地址,这会非常有用 您需要将其直接指向无效字段。
  • paymentMethodErrors:特定于付款方式的错误对象。您可以询问 但 Web Payments 规范作者可以 建议您尽量使用简单的字符串

示例代码

您在本文档中看到的大部分示例代码均摘自以下 运行中的示例应用:

https://paymenthandler-demo.glitch.me

[付款处理程序] Service Worker

[付款处理程序] 前端

如需试用,请执行以下操作:

  1. 前往 https://paymentrequest-demo.glitch.me/
  2. 转至页面底部。
  3. 添加付款按钮
  4. 付款方式标识符字段中输入 https://paymenthandler-demo.glitch.me
  5. 按字段旁边的付款按钮。