支付交易的生命周期

了解商家如何集成支付应用,以及支付交易如何与 Payment Request API 协同工作。

Web Payments API 是首次内置于浏览器的专用支付功能。借助 Web Payments,商家与支付应用的集成变得更加简单,同时客户体验也更加精简和安全。

要了解有关使用 Web Payments 的好处的更多信息,请查看使用 Web Payments 增强支付应用的功能

本文将引导您完成商家网站上的支付交易,并帮助您了解支付应用集成的工作原理。

该过程包括 6 个步骤

  1. 商家发起支付交易。
  2. 商家显示支付按钮。
  3. 客户按下支付按钮。

    A diagram of a cheese shop website with a BobPay (payment app) button.

  4. 浏览器启动支付应用。

    A diagram of the cheese shop website with BobPay app launched in a modal. The modal shows shipping options and total cost.

  5. 如果客户更改任何详细信息(例如送货选项或他们的地址),商家会更新交易详细信息以反映更改。

    A diagram showing the customer choosing a different shipping option in BobPay app modal. A second diagram showing the merchant updating the total cost displayed in BobPay.

  6. 在客户确认购买后,商家验证付款并完成交易。

    A diagram showing the customer pressing the

步骤 1:商家发起支付交易

当客户决定购买时,商家通过构建 PaymentRequest 对象来发起支付交易。此对象包含有关交易的重要信息

  • 可接受的支付方式及其处理交易的数据。
  • 详细信息,例如总价(必需)和有关商品的信息。
  • 商家可以在其中请求送货信息的选项,例如送货地址和送货选项。
  • 商家还可以请求账单地址、付款人的姓名、电子邮件和电话号码。
  • 商家还可以包含可选的 送货类型shippingdeliverypickup)在 PaymentRequest 中。支付应用可以使用它作为提示,在其 UI 中显示正确的标签。
const request = new PaymentRequest([{
  supportedMethods: 'https://bobpay.xyz/pay',
  data: {
    transactionId: '****'
  }
}], {
  displayItems: [{
    label: 'Anvil L/S Crew Neck - Grey M x1',
    amount: { currency: 'USD', value: '22.15' }
  }],
  total: {
    label: 'Total due',
    amount: { currency: 'USD', value : '22.15' }
  }
}, {
  requestShipping: true,
  requestBillingAddress: true,
  requestPayerEmail: true,
  requestPayerPhone: true,
  requestPayerName: true,
  shippingType: 'delivery'
});
包含交易 ID

某些支付处理程序可能要求商家提供他们预先发布的交易 ID 作为交易信息的一部分。典型的集成包括商家和支付处理程序的服务器之间的通信,以保留总价。这可以防止恶意客户操纵价格并在交易结束时通过验证欺骗商家。

商家可以将交易 ID 作为 PaymentMethodData 对象的 data 属性的一部分传递。

提供交易信息后,浏览器会根据支付方式标识符,遍历 PaymentRequest 中指定的支付应用的发现过程。这样,浏览器可以在商家准备好继续交易后立即确定要启动的支付应用。

要详细了解发现过程的工作原理,请查看设置支付方式

步骤 2:商家显示支付按钮

商家可以支持多种支付方式,但应仅显示客户实际可以使用的支付方式的按钮。显示无法使用的支付按钮会带来糟糕的用户体验。如果商家可以预测 PaymentRequest 对象中指定的支付方式对客户不起作用,他们可以提供备用解决方案,或者根本不显示该按钮。

使用 PaymentRequest 实例,商家可以查询客户是否可以使用支付应用。

客户是否可以使用支付应用?

canMakePayment() 方法 PaymentRequest 如果客户的设备上可以使用支付应用,则返回 true。“可用”表示已发现支持该支付方式的支付应用,并且已安装特定于平台的支付应用,或者基于 Web 的支付应用已准备好注册

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

步骤 3:客户按下支付按钮

当客户按下支付按钮时,商家调用 PaymentRequest 实例的 show() 方法,该方法会立即触发支付 UI 的启动。

如果最终总价是动态设置的(例如,从服务器检索),则商家可以延迟支付 UI 的启动,直到总价已知。

延迟支付 UI 的启动

查看 延迟支付 UI 直到确定最终总价的演示。

要延迟支付 UI,商家将 Promise 传递给 show() 方法。浏览器将显示加载指示器,直到 Promise 解析并且交易准备好开始。

const getTotalAmount = async () => {
  // Fetch the total amount from the server, etc.
};

try {
  const result = await request.show(getTotalAmount());
  // Process the result…
} catch(e) {
  handleError(e);
}

如果未指定 Promise 作为 show() 的参数,浏览器将立即启动支付 UI。

步骤 4:浏览器启动支付应用

浏览器可以启动特定于平台的或基于 Web 的支付应用。(您可以了解更多关于Chrome 如何确定要启动哪个支付应用的信息。)

支付应用的构建方式在很大程度上取决于开发者,但从商家发出和发往商家的事件,以及与这些事件一起传递的数据结构都是标准化的。

当支付应用启动时,它会收到在步骤 1 中传递给 PaymentRequest 对象的交易信息,其中包括以下内容

  • 支付方式数据
  • 总价
  • 支付选项

支付应用使用交易信息来标记其 UI。

步骤 5:商家如何根据客户的操作更新交易详细信息

客户可以选择在支付应用中更改交易详细信息,例如支付方式和送货选项。当客户进行更改时,商家会收到更改事件并更新交易详细信息。

商家可以接收四种类型的事件

  • 支付方式更改事件
  • 送货地址更改事件
  • 送货选项更改事件
  • 商家验证事件

支付方式更改事件

支付应用可以支持多种支付方式,并且商家可能会根据客户的选择提供特别折扣。为了涵盖此用例,支付方式更改事件可以通知商家新的支付方式,以便他们可以使用折扣更新总价并将其返回到支付应用。

request.addEventListener('paymentmethodchange', e => {
  e.updateWith({
    // Add discount etc.
  });
});

送货地址更改事件

支付应用可以选择性地提供客户的送货地址。这对于客户来说很方便,因为他们不必手动将任何详细信息输入到表单中,并且可以将他们的送货地址存储在他们首选的支付应用中,而不是在多个不同的商家网站上。

如果客户在交易发起后在支付应用中更新他们的送货地址,则会向商家发送 'shippingaddresschange' 事件。此事件帮助商家根据新地址确定运费、更新总价并将其返回到支付应用。

request.addEventListener('shippingaddresschange', e => {
  e.updateWith({
    // Update the details
  });
});

如果商家无法运送到更新后的地址,他们可以通过向返回给支付应用的交易详细信息添加错误参数来提供错误消息。

送货选项更改事件

商家可以向客户提供多个送货选项,并将该选择委托给支付应用。送货选项显示为客户可以从中选择的价格和服务名称列表。例如

  • 标准送货 - 免费
  • 快递送货 - 5 美元

当客户在支付应用中更新送货选项时,将向商家发送 'shippingoptionchange' 事件。然后,商家可以确定运费、更新总价并将其返回到支付应用。

request.addEventListener('shippingoptionchange', e => {
  e.updateWith({
    // Update the details
  });
});

商家还可以根据客户的送货地址动态修改送货选项。当商家想要为国内和国际客户提供不同的送货选项集时,这很有用。

商家验证事件

为了提高安全性,支付应用可以在继续支付流程之前执行商家验证。验证机制的设计取决于支付应用,但商家验证事件用于通知商家他们可以用来验证自己的 URL。

request.addEventListener('merchantvalidation', e => {
  e.updateWith({
    // Use `e.validateURL` to validate
  });
});

步骤 6:商家验证付款并完成交易

当客户成功授权付款时,show() 方法会返回一个 Promise,该 Promise 解析为 PaymentResponsePaymentResponse 对象包括以下信息

  • 付款结果详细信息
  • 送货地址
  • 送货选项
  • 联系信息

此时,浏览器 UI 可能仍会显示加载指示器,这意味着交易尚未完成。

如果支付应用因付款失败或错误而终止,则从 show() 返回的 Promise 将拒绝,并且浏览器将终止支付交易。

处理和验证付款

PaymentResponse 中的 details 是从支付应用返回的支付凭据对象。商家可以使用凭据来处理或验证付款。这个关键过程的工作方式取决于支付处理程序。

完成或重试交易

在商家确定交易是成功还是失败后,他们可以

  • 调用 .complete() 方法来完成交易并关闭加载指示器。
  • 让客户通过调用 retry() 方法重试。
async function doPaymentRequest() {
  try {
    const request = new PaymentRequest(methodData, details, options);
    const response = await request.show();
    await validateResponse(response);
  } catch (err) {
    // AbortError, SecurityError
    console.error(err);
  }
}

async function validateResponse(response) {
  try {
    const errors = await checkAllValuesAreGood(response);
    if (errors.length) {
      await response.retry(errors);
      return validateResponse(response);
    }
    await response.complete("success");
  } catch (err) {
    // Something went wrong…
    await response.complete("fail");
  }
}
// Must be called as a result of a click
// or some explicit user action.
doPaymentRequest();

下一步