资讯专栏INFORMATION COLUMN

FE.B-浏览器支付接口概览-PaymentRequest

channg / 672人阅读

摘要:用户代理例如,浏览器促进商家和用户之间的支付流程。布尔值,指示用户代理是否应收集付款人的电话号码并使用付款请求提交。表明用户已经改变了某个指定的支付处理程序中的付款方式。在用户选择付款方式并批准付款请求后的返回。

概要

PaymentRequest API 允许商家(即销售物理或数字商品的网站)以最小的集成使用一种或多种支付方法。用户代理(例如,浏览器)促进商家和用户之间的支付流程。
github链接 https://github.com/w3c/paymen...
w3c规范链接 https://www.w3.org/TR/payment...

出于安全考虑,支付接口必须在https环境下使用。

使用 PaymentRequest

PaymentRequest()构造函数创建一个新的PaymentRequest对象,该对象将用于处理生成、验证和提交支付请求的过程。

var paymentRequest = new PaymentRequest(methodData, details, [options]);
参数

methodData
包含商家网站接受的付款方式的标识符数组以及任何相关的付款方式特定数据。数组中的每个项都包含以下字段:

supportedMethods
商家网站接受的支付方法的一系列标识符

data
提供受支持的付款方式可能需要的可选信息。

details
提供有关所请求事务的信息。此参数包含以下字段:

total
付款请求的总金额。

id (可选)
标识。如果未提供值,则浏览器将构造一个值。

displayItems
可选订单项数组,例如产品详细信息,税金和运费。

shippingOptions
用户可以选择的送货方式

modifiers
特定付款方式的修饰符,包含以下字段:

additionalDisplayItems
要附加到details.displayItems属性的项数组。此属性通常用于添加折扣或附加订单项,表示details.modifiers.total中的金额不同。

data
JSON可序列化对象,提供受支持的付款方式可能需要的可选信息。这必须符合BasicCardRequest字典中定义的结构。

total
支付请求的总金额,覆盖details.total中的值。这通常在details.modifiers.additionalItems向请求添加折扣或购买时使用。

options (可选)
允许您设置控制用户代理行为的选项。此参数包含以下字段:

requestPayerName
布尔值,指示用户代理是否应收集付款人的姓名并使用付款请求提交。默认是false

requestPayerEmail
布尔值,指示用户代理是否应收集付款人的电子邮件地址并使用付款请求提交。默认是false

requestPayerPhone
布尔值,指示用户代理是否应收集付款人的电话号码并使用付款请求提交。默认是false

requestShipping
布尔值,指示用户代理是否应收集付款人的送货地址并使用付款请求提交。如果将此类型设置为true,则应选择适当的shippingType。默认是false

shippingType
允许您指定当“运送”一词不适合您的用例时,用户界面如何引用运送。例如,在英语国家,你会说 "pizza delivery" 而不是 "pizza shipping" 。有效值是"shipping""delivery""pickup"。必须包括引号。默认值为"shipping"

示例
var supportedInstruments = [{
 supportedMethods: "basic-card",
 data: {
   supportedNetworks: ["visa", "mastercard", "amex", "jcb",
                       "diners", "discover", "mir", "unionpay"],
   supportedTypes: ["credit", "debit"]
 }
}];

var details = {
  total: {label: "Donation", amount: {currency: "USD", value: "65.00"}},
  displayItems: [
    {
      label: "Original donation amount",
      amount: {currency: "USD", value: "65.00"}
    }
  ],
  shippingOptions: [
    {
      id: "standard",
      label: "Standard shipping",
      amount: {currency: "USD", value: "0.00"},
      selected: true
    }
  ]
};

var options = {requestShipping: true};

try {
  var request = new PaymentRequest(supportedInstruments, details, options);
  // Add event listeners here.
  // Call show() to trigger the browser"s payment flow.
  request.show().then(function(instrumentResponse) {
    // Do something with the response from the UI.
  })
  .catch(function(err) {
    // Do something with the error from request.show().
  });
} catch (e) {
  // Catch any other errors.
}

onmerchantvalidation

支付处理程序(例如,苹果公司支付)需要商家来验证自己。在此之前,用户将无法继续付款。

request.onmerchantvalidation = ev => {
    ev.complete(async () => {
        // get validation data, and complete validation;
        return await fetch(ev.validationURL).then(r => r.text());
    })
};
const response = await request.show();
onpaymentmethodchange

表明用户已经改变了某个指定的支付处理程序中的付款方式。例如,使用Apple Pay时,用户可以滑动以选择不同的信用卡,借记卡等。每次用户这样做时,都会触发此事件。

request.onpaymentmethodchange = ev => {
  const { type: cardType } = ev.methodDetails;
  const newStuff = {};
  if (ev.methodName === "https://apple.com/apple-pay") {
    switch (cardType) {
      case "store":
        // do Apple Pay specific handling for store card...
        // methodDetails contains the store card information
        const result = calculateDiscount(ev.methodDetails);
        Object.assign(newStuff, result);
        break;
    }
  }
  // finally...
  ev.updateWith(newStuff);
};
const response = await request.show();
onshippingaddresschange

如果用户代理存储的地址在付款过程中随时更改,则会触发该事件。

// Initialization of PaymentRequest arguments are excerpted for clarity.
var payment = new PaymentRequest(supportedInstruments, details, options);

request.addEventListener("shippingaddresschange", function(evt) {
  evt.updateWith(new Promise(function(resolve) {
    updateDetails(details, request.shippingAddress, resolve);
  }));
});

payment.show().then(function(paymentResponse) {
  // Processing of paymentResponse exerpted for the same of clarity.
}).catch(function(err) {
  console.error("Uh oh, something bad happened", err.message);
});
PaymentResponse

在用户选择付款方式并批准付款请求后的返回。
属性:details,methodName,payerEmail,payerName,payerPhone,requestId,shippingAddress,shippingOption
方法:retry(),comlete()

PaymentAddress

属性(都是只读)city,dependentLocality,organization,phone,postalCode,recipient,region,regionCode,sortingCode
方法toJSON()

const supportedInstruments = [
  {
    supportedMethods: "basic-card",
  },
];

const details = {
  total: { label: "Donation", amount: { currency: "USD", value: "65.00" } },
  displayItems: [
    {
      label: "Original donation amount",
      amount: { currency: "USD", value: "65.00" },
    },
  ],
  shippingOptions: [
    {
      id: "standard",
      label: "Standard shipping",
      amount: { currency: "USD", value: "0.00" },
      selected: true,
    },
  ],
};

const options = { requestShipping: true };

async function doPaymentRequest() {
  const request = new PaymentRequest(supportedInstruments, details, options);
  // Add event listeners here.
  // Call show() to trigger the browser"s payment flow.
  const response = await request.show();
  // Process payment.
  const json = response.toJSON();
  const httpResponse = await fetch("/pay/", { method: "POST", body: json });
  const result = httpResponse.ok ? "success" : "failure";

  await response.complete(result);
}
doPaymentRequest();

PaymentResponse.details包含响应详细信息的属性。这必须符合BasicCardResponse字典定义的结构,可能看起来像这样:

{
  "cardNumber" : "9999999999999999",
  "cardholderName" : "Mr Dick Straw",
  "cardSecurityCode" : "999",
  "expiryMonth" : "07",
  "expiryYear" : "2021",
  "billingAddress" : {
    "country" : "GB",
    // etc. billing address is a PaymentAddress object
  }
}
跨域安全

如果应该允许跨源的