在移动互联网时代,PWA(Progressive Web Apps)成为了越来越多企业的选择,因为它结合了网页和原生应用的优点,同时兼具快速响应和离线浏览的体验。为了提高用户的购物体验,许多 PWA 应用都集成了支付系统,下面将详细介绍 PWA 集成支付系统的技术实现。
1. PWA 的基础知识
PWA 是一种全新的应用程序形态,它能够在浏览器中运行,无需下载安装,用户只需通过浏览器访问 PWA 应用即可使用,具有“即插即用”的特点。
PWA 实现了 App Shell、Service Worker 和 Manifest 等特性,其中 Service Worker 是 PWA 的重要组成部分,它负责充当一个独立的中间层,使得 PWA 应用能够脱离网络状态进行离线访问和缓存处理。
2. PWA 集成支付系统的技术实现
2.1 引入支付系统 SDK
PWA 应用集成支付系统的第一步,就是要引入第三方支付系统的 SDK,常用的支付服务商有 PayPal、Stripe 等。
以 Stripe 为例,我们可以在代码中引入 Stripe 的 JavaScript SDK,示例代码如下:
<script src="https://js.stripe.com/v3/"></script>
2.2 客户端生成支付信息
在客户端生成支付信息的方式有两种,一种是前端使用 Stripe 提供的 SDK 创建支付信息,另一种是通过服务端生成支付信息。
2.2.1 前端使用 Stripe SDK 创建支付信息
前端使用 Stripe SDK 创建支付信息的流程如下:
创建一个 Stripe 实例
const stripe = Stripe('pk_test_xxx') // pk_test_xxx 为 Stripe 的公钥
调用
stripe.createPaymentMethod
方法创建支付对象。// javascriptcn.com 代码示例 stripe.createPaymentMethod({ type: 'card', card: cardElement, // 其中 cardElement 是一个 CardElement 实例 billing_details: { name: 'user-name', email: 'user-email', phone: 'user-phone', address: { line1: 'address-line1', line2: 'address-line2', city: 'city', state: 'state', country: 'country', postal_code: 'zip-code' } } })
获取支付信息
stripe.confirmCardPayment(clientSecret, { payment_method: { card: cardElement, billing_details: /* ... */ } })
2.2.2 服务端生成支付信息
服务端生成支付信息的流程如下:
获取支付信息
// javascriptcn.com 代码示例 const paymentInfo = { amount: 1000, // 支付金额 currency: 'usd', // 货币类型 payment_mode: 'card', // 支付方式 description: 'payment description', // 订单描述 customer_email: 'customer-email', // 用户邮箱 customer_phone: 'customer-phone', // 用户电话 customer_address: 'customer-address', // 用户地址 client_reference_id: 'client-reference-id', // 客户端参考 ID statement_descriptor: 'statement-descriptor', // 订单描述 metadata: { /* 其他自定义信息 */ } }
使用 Stripe 的 API 请求创建支付对象并获取 client_secret
const paymentIntent = await stripe.paymentIntents.create(paymentInfo) const { client_secret } = paymentIntent
2.3 处理支付结果
客户端在支付成功后,可以直接跳转到支付成功页面,也可以通过 Service Worker 缓存支付结果,并在支付成功后通过前端版本的 Server-Sent Events(SSE)实现将支付结果发送到客户端。
服务端则需要监听支付结果,一般来说,可以在接收到支付结果后,将支付成功的信息写入数据库,向用户展示支付成功界面,或者异步处理业务逻辑。
2.4 在 PWA 应用中集成支付系统
将以上提到的支付系统 SDK、支付信息的生成和支付结果处理集成到 PWA 应用中的方法如下:
在 PWA 应用的页面中引入支付系统 SDK。
<script src="https://js.stripe.com/v3/"></script>
使用 Promise 或 async/await 等方式,调用客户端生成支付信息方法或者服务端生成支付信息方法,通过 fetch 或者 WebSocket 获取支付结果。
// javascriptcn.com 代码示例 // 客户端生成支付信息 async function createPayment() { const paymentMethod = await stripe.createPaymentMethod({ type: 'card', card: cardElement, billing_details: billingDetails, }) const paymentIntent = await stripe.confirmCardPayment(clientSecret, { payment_method: paymentMethod.paymentMethod.id, }) return paymentIntent } // 服务端生成支付信息 async function createPayment() { const response = await fetch('/create-payment-intent', { method: 'POST', headers: { 'Content-Type': 'application/json', }, body: JSON.stringify({ amount: '10000' }), }) const { client_secret } = await response.json() return client_secret } // 获取支付结果 async function watchPaymentStatus() { const paymentStatusChannel = new EventSource('/payment-status') paymentStatusChannel.onmessage = (message) => { /* 处理支付结果 */ } } }
- 在 Service Worker 中监听支付信息请求,在支付成功后缓存支付结果,并通过 SSE 发送到客户端。
// javascriptcn.com 代码示例 // Service Worker 中监听支付信息请求 self.addEventListener('fetch', (event) => { if (event.request.url.match(/\/payment-intent$/)) { event.respondWith(async function() { const paymentIntent = await createPayment() cache.put(event.request, paymentIntent.clone()) return paymentIntent }()) } }) // Service Worker 中处理 SSE 请求 self.addEventListener('fetch', (event) => { if (event.request.url.match(/\/payment-status$/)) { let lastPaymentStatus = '' const onSuccess = (result) => { if (result.status === 'succeeded' && lastPaymentStatus !== result.id) { lastPaymentStatus = result.id const paymentResult = { id: result.id, amount: result.amount, currency: result.currency, payment_method_types: result.payment_method_types, status: result.status, } const payload = JSON.stringify(paymentResult) clients.matchAll().then((clients) => { clients.forEach((client) => { client.postMessage({ type: 'payment_success', payload }) }) }) } } /* Stripe 或其他支付服务商提供的 API */ const paymentStatusChannel = new Stripe.PaymentMethodSucceededEvent(event.request, onSuccess) paymentStatusChannel.addEventListener('message', (message) => { message.source.postMessage({ data: message.data }, event.request.headers.get('client') || '*') }) } })
3. 总结
PWA 现在是一个炙手可热的技术,基于 PWA 的应用程序可以让您更好地服务用户,而结合支付系统则可以让用户更好地消费。此文简要介绍了 PWA 集成支付系统的实现方法及示例代码,未来 PWA 和支付系统的相互配合更能带来更丰富的互联网生态。
来源:JavaScript中文网 ,转载请注明来源 本文地址:https://www.javascriptcn.com/post/6538d2537d4982a6eb1ec746