各位老铁,晚上好!我是你们的老朋友,今天咱们来聊聊 JavaScript 里一个有点意思,但可能平时接触不多的东西:Payment Request API。这玩意儿,说白了,就是让你的网站支付流程更顺滑,用户体验更上一层楼的秘密武器。
一、啥是 Payment Request API?为啥要用它?
Payment Request API (支付请求 API),简称 PRA,它允许网站以一种标准、安全的方式向用户请求支付信息。想象一下,过去用户在你的网站上买东西,要填一大堆表格,姓名、地址、信用卡号,一不小心还填错了,那体验简直糟糕透了。PRA 的出现就是为了解决这个问题,它把这些信息交给浏览器或者支付应用(比如 Apple Pay、Google Pay),用户只需要点一下,就能完成支付。
为啥要用 PRA?
- 用户体验提升: 减少填写表单的痛苦,一键支付,用户更爽。
- 安全性更高: 网站不用直接接触用户的敏感支付信息,降低了被黑客攻击的风险。
- 更快的支付流程: 缩短支付时间,提高转化率,老板更高兴。
- 标准化: 统一的 API,方便开发者接入各种支付方式。
二、Payment Request API 的基本流程
PRA 的流程大概是这样的:
- 创建 PaymentRequest 对象: 告诉浏览器你要卖什么,价格多少,支持哪些支付方式。
- 显示支付界面: 浏览器弹出支付对话框,用户选择支付方式并授权。
- 处理支付结果: 验证支付信息,完成交易。
- 告诉用户结果: 交易成功还是失败,给用户一个明确的反馈。
三、代码实战:一步步接入 Payment Request API
咱们来撸一段代码,一步步演示如何接入 PRA。
1. 创建 PaymentRequest 对象
// 商品信息
const details = {
total: {
label: '总计',
amount: { currency: 'CNY', value: '10.00' }
}
};
// 支持的支付方式
const supportedInstruments = [
{
supportedMethods: 'basic-card',
data: {
supportedNetworks: ['visa', 'mastercard', 'amex'], // 支持的银行卡
supportedTypes: ['credit', 'debit'] // 支持的卡类型
}
},
{
supportedMethods: 'https://android.com/pay',
data: {
"allowedCardNetworks": ["VISA", "MASTERCARD"]
}
},
{
supportedMethods: 'apple-pay',
data: {
version: 3,
countryCode: 'CN',
supportedNetworks: ['visa', 'mastercard', 'amex'],
merchantCapabilities: ['supports3DS', 'supportsDebit', 'supportsCredit']
}
}
];
// 支付选项
const options = {
requestShipping: false, // 是否需要收货地址
requestPayerEmail: true, // 是否需要用户邮箱
requestPayerPhone: false // 是否需要用户电话
};
try {
const request = new PaymentRequest(supportedInstruments, details, options);
// 检查是否支持 PRA
request.canMakePayment().then(result => {
if (result) {
console.log('支持 Payment Request API');
} else {
console.log('不支持 Payment Request API');
}
}).catch(error => {
console.error('检查支付支持失败:', error);
});
//监听支付方式更改事件
request.addEventListener('paymentmethodchange', (evt) => {
console.log('支付方式更改:', evt.methodDetails);
//这里可以根据选择的支付方式更新商品价格
evt.updateWith({
total: {
label: '总计',
amount: { currency: 'CNY', value: '10.00' }
}
});
});
// 显示支付界面
request.show()
.then(paymentResponse => {
// 处理支付结果
console.log('支付信息:', paymentResponse);
// 模拟后端验证支付信息
setTimeout(() => {
const paymentStatus = 'success'; // 假设支付成功
if (paymentStatus === 'success') {
paymentResponse.complete('success'); // 告诉浏览器支付成功
alert('支付成功!');
} else {
paymentResponse.complete('fail'); // 告诉浏览器支付失败
alert('支付失败!');
}
}, 2000); // 模拟 2 秒的后端处理时间
})
.catch(error => {
console.error('支付失败:', error);
alert('支付失败:' + error);
});
} catch (error) {
console.error('创建 PaymentRequest 对象失败:', error);
alert('创建支付请求失败:' + error);
}
代码解释:
details
: 定义了商品的总价。currency
是货币单位,value
是价格。supportedInstruments
: 定义了支持的支付方式。这里我们支持basic-card
(信用卡/借记卡),https://android.com/pay
(Google Pay) 和apple-pay
。basic-card
:supportedNetworks
指定了支持的银行卡类型,supportedTypes
指定了支持的卡类型(信用卡/借记卡)。https://android.com/pay
: 需要配置allowedCardNetworks
,指定支持的银行卡网络。apple-pay
: 需要配置version
,countryCode
,supportedNetworks
,merchantCapabilities
。
options
: 定义了是否需要收货地址、邮箱、电话等信息。request.show()
: 显示支付界面,用户选择支付方式并授权。paymentResponse
: 包含了用户的支付信息,你需要把这些信息发送到后端进行验证。paymentResponse.complete()
: 告诉浏览器支付结果,'success'
表示成功,'fail'
表示失败。paymentmethodchange
: 事件监听,当用户更改支付方式时触发,可以根据选择的支付方式动态更新订单信息。
2. HTML 结构
<!DOCTYPE html>
<html>
<head>
<title>Payment Request API 示例</title>
</head>
<body>
<h1>Payment Request API 示例</h1>
<button id="paymentButton">立即支付</button>
<script>
// 上面的 JavaScript 代码放在这里
document.getElementById('paymentButton').addEventListener('click', function() {
// 将上面的Payment Request API 代码放在这里
// 商品信息
const details = {
total: {
label: '总计',
amount: { currency: 'CNY', value: '10.00' }
}
};
// 支持的支付方式
const supportedInstruments = [
{
supportedMethods: 'basic-card',
data: {
supportedNetworks: ['visa', 'mastercard', 'amex'], // 支持的银行卡
supportedTypes: ['credit', 'debit'] // 支持的卡类型
}
},
{
supportedMethods: 'https://android.com/pay',
data: {
"allowedCardNetworks": ["VISA", "MASTERCARD"]
}
},
{
supportedMethods: 'apple-pay',
data: {
version: 3,
countryCode: 'CN',
supportedNetworks: ['visa', 'mastercard', 'amex'],
merchantCapabilities: ['supports3DS', 'supportsDebit', 'supportsCredit']
}
}
];
// 支付选项
const options = {
requestShipping: false, // 是否需要收货地址
requestPayerEmail: true, // 是否需要用户邮箱
requestPayerPhone: false // 是否需要用户电话
};
try {
const request = new PaymentRequest(supportedInstruments, details, options);
// 检查是否支持 PRA
request.canMakePayment().then(result => {
if (result) {
console.log('支持 Payment Request API');
} else {
console.log('不支持 Payment Request API');
}
}).catch(error => {
console.error('检查支付支持失败:', error);
});
//监听支付方式更改事件
request.addEventListener('paymentmethodchange', (evt) => {
console.log('支付方式更改:', evt.methodDetails);
//这里可以根据选择的支付方式更新商品价格
evt.updateWith({
total: {
label: '总计',
amount: { currency: 'CNY', value: '10.00' }
}
});
});
// 显示支付界面
request.show()
.then(paymentResponse => {
// 处理支付结果
console.log('支付信息:', paymentResponse);
// 模拟后端验证支付信息
setTimeout(() => {
const paymentStatus = 'success'; // 假设支付成功
if (paymentStatus === 'success') {
paymentResponse.complete('success'); // 告诉浏览器支付成功
alert('支付成功!');
} else {
paymentResponse.complete('fail'); // 告诉浏览器支付失败
alert('支付失败!');
}
}, 2000); // 模拟 2 秒的后端处理时间
})
.catch(error => {
console.error('支付失败:', error);
alert('支付失败:' + error);
});
} catch (error) {
console.error('创建 PaymentRequest 对象失败:', error);
alert('创建支付请求失败:' + error);
}
});
</script>
</body>
</html>
3. 注意事项
- HTTPS: 必须在 HTTPS 环境下使用,因为 PRA 涉及到用户的敏感支付信息。
- 用户授权: 用户必须授权才能使用 PRA,浏览器会弹出授权对话框。
- 后端验证: 支付信息必须在后端进行验证,防止恶意攻击。
- 错误处理: 要处理各种可能出现的错误,比如用户取消支付、支付方式不支持等等。
四、Payment Request API 的高级用法
除了基本用法,PRA 还有一些高级用法,可以让你更好地控制支付流程。
1. Shipping Options (收货地址选项)
如果你的商品需要邮寄,你可以使用 requestShipping
选项来请求用户的收货地址。
const options = {
requestShipping: true, // 需要收货地址
requestPayerEmail: true,
requestPayerPhone: false
};
// 监听 shippingaddresschange 事件
request.addEventListener('shippingaddresschange', (evt) => {
console.log('收货地址更改:', evt.shippingAddress);
// 根据收货地址计算运费
const shippingOptions = [
{
id: 'standard',
label: '标准快递',
amount: { currency: 'CNY', value: '5.00' },
selected: true
},
{
id: 'express',
label: '加急快递',
amount: { currency: 'CNY', value: '10.00' }
}
];
const details = {
total: {
label: '总计',
amount: { currency: 'CNY', value: (10 + 5).toFixed(2) } // 商品价格 + 运费
},
displayItems: [
{
label: '商品',
amount: { currency: 'CNY', value: '10.00' }
},
{
label: '运费',
amount: { currency: 'CNY', value: '5.00' }
}
],
shippingOptions: shippingOptions
};
evt.updateWith({
status: 'success',
shippingOptions: shippingOptions,
details: details
});
});
// 监听 shippingoptionchange 事件
request.addEventListener('shippingoptionchange', (evt) => {
console.log('收货选项更改:', evt.shippingOption);
// 根据收货选项更新总价
let shippingCost = 0;
if (evt.shippingOption === 'express') {
shippingCost = 10;
} else {
shippingCost = 5;
}
const details = {
total: {
label: '总计',
amount: { currency: 'CNY', value: (10 + shippingCost).toFixed(2) } // 商品价格 + 运费
},
displayItems: [
{
label: '商品',
amount: { currency: 'CNY', value: '10.00' }
},
{
label: '运费',
amount: { currency: 'CNY', value: shippingCost.toFixed(2) }
}
]
};
evt.updateWith({
status: 'success',
details: details
});
});
代码解释:
requestShipping: true
: 开启收货地址请求。shippingaddresschange
事件:当用户修改收货地址时触发,你可以在这里根据收货地址计算运费。shippingoptionchange
事件:当用户修改收货选项(比如选择标准快递还是加急快递)时触发,你可以在这里根据收货选项更新总价。evt.updateWith()
: 更新支付界面的信息,比如总价、运费等。
2. Payment Method Change (支付方式更改)
当用户选择不同的支付方式时,你可能需要更新订单信息,比如手续费、折扣等等。
// 监听 paymentmethodchange 事件
request.addEventListener('paymentmethodchange', (evt) => {
console.log('支付方式更改:', evt.methodDetails);
// 根据支付方式更新订单信息
let discount = 0;
if (evt.methodName === 'basic-card' && evt.methodDetails.cardNetwork === 'visa') {
discount = 2; // Visa 卡有 2 元折扣
}
const details = {
total: {
label: '总计',
amount: { currency: 'CNY', value: (10 - discount).toFixed(2) } // 商品价格 - 折扣
},
displayItems: [
{
label: '商品',
amount: { currency: 'CNY', value: '10.00' }
},
{
label: '折扣',
amount: { currency: 'CNY', value: (-discount).toFixed(2) }
}
]
};
evt.updateWith({
status: 'success',
details: details
});
});
代码解释:
paymentmethodchange
事件:当用户修改支付方式时触发,你可以在这里根据支付方式更新订单信息。evt.methodName
: 支付方式的名称,比如'basic-card'
。evt.methodDetails
: 支付方式的详细信息,比如银行卡类型、卡号等等。evt.updateWith()
: 更新支付界面的信息,比如总价、折扣等。
五、Payment Request API 的兼容性
虽然 PRA 很好用,但并不是所有浏览器都支持它。
浏览器 | 支持情况 |
---|---|
Chrome | 支持 |
Firefox | 支持 |
Safari | 支持 |
Edge | 支持 |
iOS Safari | 支持 |
Android Chrome | 支持 |
在不支持 PRA 的浏览器中,你需要提供其他的支付方式,比如传统的表单支付。
if (window.PaymentRequest) {
// 支持 Payment Request API
// 使用 PRA 进行支付
} else {
// 不支持 Payment Request API
// 使用传统的表单支付
alert('您的浏览器不支持 Payment Request API,请使用其他支付方式。');
}
六、Payment Request API 的安全性
PRA 的安全性主要体现在以下几个方面:
- HTTPS: 必须在 HTTPS 环境下使用,保证数据传输的安全性。
- 用户授权: 用户必须授权才能使用 PRA,防止恶意网站盗用用户的支付信息。
- 后端验证: 支付信息必须在后端进行验证,防止恶意攻击。
- 令牌化: 支付信息通常会被令牌化,网站不会直接接触用户的敏感支付信息。
七、Payment Request API 的未来
PRA 的未来一片光明,随着越来越多的浏览器和支付方式的支持,它将成为 Web 支付的主流方式。
- 更多的支付方式: 将支持更多的支付方式,比如银行转账、数字货币等等。
- 更强大的功能: 将提供更强大的功能,比如分期付款、订阅支付等等。
- 更好的用户体验: 将提供更好的用户体验,比如更快的支付速度、更简单的支付流程等等。
八、总结
Payment Request API 是一个非常有用的 API,它可以让你的网站支付流程更顺滑,用户体验更上一层楼。虽然它有一些兼容性问题,但随着越来越多的浏览器和支付方式的支持,它将成为 Web 支付的主流方式。
今天就先聊到这里,希望大家有所收获!如果有什么问题,欢迎随时提问。
下课!