原文:Bring your payment method to the web with the Payment Handler API(需越墙)
做者:Eiji Kitamura
译者:西楼听雨
原文是谷歌开发者网站发布的关于基于 Web 的标准化支付 API 系列文章之一。(转载请注明出处)javascript
支付请求 API 为浏览器带来了一个开放的、标准化的用于处理支付请求的方式。经过一个简单、快捷的用户界面,便可采集到付款人的寄送信息、联系方式和支付凭据。html
而支付处理器 API 则为支付方式提供商(译注:即支付类的应用)打开了一个全新的生态。它可让那些基于 Web 的支付类应用(采用 service worker 支撑)经过支付请求 API 将本身做为一种支付方式整合到商家的网站中。java
从用户角度看,它带来的用户体验是这样子的:git
视频演示:v.youku.com/v_show/id_X…github
(译注:下面是操做流程)web
你能够用 Chrome 68 beta 版本在这里尝试下。api
注意,整个流程涉及到的三方有:终端用户,商家网站,支付方式提供商。promise
对于商家的网站来讲,要将一个支付应用整合进来,只需在支付请求 API 的第一个参数中的 supportedMethods
中将其添加进去(支付方法 ID)便可,同时能够有选择性地携带一个 data
数据。例如,要添加一个名叫 BobPay,支付方式 ID 为https://bobpay.xyz/pay
的支付应用,其实现以下:浏览器
const request = new PaymentRequest([{
supportedMethods: 'https://bobpay.xyz/pay'
}], {
total: {
label: ‘总额’,
amount: { value: '10', currency: 'USD' }
}
});
复制代码
若是能够处理 BobPay 支付方式的 service worker 已经安装,那么这个支付应用就会出如今支付请求的界面中供用户选择。在某些状况下,Chrome 还会跳过跳转到支付处理商一块的操做步骤,以此带来一种轻快的支付体验。app
Chrome 支持一个非标准的特性,咱们称之为 just-in-time (JIT) 安装(译注:即时安装)。在咱们的这个例子中,这个特性可让 BobPay 信任的支付处理器进行即时安装,不须要用户在事先有对 BobPay 网站进行过访问。不过只有用户在支付请求界面中明确选择了 BobPay 做为支付方式时才会开始安装;并且一种支付方式只能够指定最多一个信任的支付处理方。
要开发一个支付请求处理器,咱们须要在除了实现支付处理器 API 以外再作一点额外的工做。
支付处理器 API 的关键点就是 Service Worker。你须要在你的支付应用网站上注册一个 Service Worker 并在 ServiceWorkerRegistration
对象下的 paymentManger
中将支付指令添加进去。
if ('serviceWorker' in navigator) {
// 注册一个 service worker
const registratoin = await navigator.serviceWorker.register(
// service worker 是一个单独的 js 文件
'service-worker.js'
);
// 检查支付处理器 API 是否可用
if (!registration.paymentManager) return;
registration.paymentManager.instruments.set(
// 支付指令的 key 但是任意字符串
"https://bobpay.xyz",
// 支付指令的详情
{
name: '支付处理器示例',
method: 'https://bobpay.xyz/pay'
}
)
}
复制代码
要处理支付请求,须要对在 service worker 中对 paymentrequest
进行监听;而后当咱们收到这样一个事件时,打开一个窗口并等待其在用户受权进行支付以后返回一个支付凭据。
const origin = 'https://bobpay.xyz';
const methodName = `${origin}/pay`;
const checkoutURL = `${origin}/checkout`;
let resolver;
let payment_request_event;
self.addEventListener('paymentrequest', e => {
// 保存这个事件,以便以后使用
payment_request_event = e;
// 另外你还须要提供一个 `PromiseResolver` 垫片,
// 由于目前 Chrome 还未实现
resolver = new PromiseResolver();
e.respondWith(resolver.promise);
e.openWindow(checkoutURL).then(client => {
if (client === null) {
resolver.reject('Failed to open window');
}
}).catch(err => {
resolver.reject(err);
});
});
self.addEventListener('message', e => {
console.log('A message received:', e);
if (e.data === "payment_app_window_ready") {
sendPaymentRequest();
return;
}
if (e.data.methodName === methodName) {
resolver.resolve(e.data);
} else {
resolver.reject(e.data);
}
});
const sendPaymentRequest = () => {
if (!payment_request_event) return;
clients.matchAll({
includeUncontrolled: false,
type: 'window'
}).then(clientList => {
for (let client of clientList) {
client.postMessage(payment_request_event.total);
}
});
}
复制代码
由于支付处理器 API 的设计理念就是保持最大的灵活性,以支持任意类型的支付方式,因此它所支持的包含了:
(译注:如下连接均需越墙)