跳转到内容

Payment Request API:浏览器托管的结账流程

一句话: Payment Request API 让浏览器托管结账流程——浏览器使用用户已注册的存储卡片、 数字钱包或其他支付方式呈现原生支付面板——使你无需构建自定义支付 UI 或在页面上处理原始 卡片数据,即可获得流畅的结账体验。

PaymentRequest支付方式标识符数组为第一个参数构造,描述可接受的支付方式。有两类:

  • 标准化方式:基于 URL 的标识符,如 "basic-card"(已废弃,推荐使用处理器专用方式) 以及平台专用方式,如 "https://apple.com/apple-pay""https://google.com/pay"
  • 处理器专用方式:目前最常用的方式。传入支付处理器自己的方式标识符(如 Stripe 的 "https://stripe.com/pay")。处理器的 Payment Handler 负责协商细节。

第二个构造参数描述用户要支付什么:

const details = {
total: { label: '合计', amount: { currency: 'CNY', value: '199.00' } },
displayItems: [
{ label: '专业版订阅', amount: { currency: 'CNY', value: '199.00' } },
],
};
// 1. 构造——此时不显示任何 UI
const request = new PaymentRequest(
[{ supportedMethods: 'https://google.com/pay', data: { /* 处理器配置 */ } }],
details,
{ requestPayerName: true, requestPayerEmail: true }
);
// 2. 检查是否至少有一种方式可用(可选但推荐)
const canMakePayment = await request.canMakePayment();
// 3. 显示浏览器原生支付面板(必须在用户手势内)
try {
const response = await request.show(); // PaymentResponse
// 4. 在服务端处理,再完成
await processOnServer(response.toJSON());
await response.complete('success');
} catch (err) {
if (err.name === 'AbortError') {
// 用户关闭了面板——不是错误
} else {
throw err;
}
}

Payment Request API 仅在安全上下文中可用——HTTPS 或 localhost。在普通 HTTP 下, PaymentRequest 构造函数为 undefined。

request.show() 必须在用户激活(点击、轻触或类似瞬时事件)时调用。从定时器或非交互 异步链中调用,某些浏览器会抛出 SecurityError 或以 NotAllowedError 拒绝。

canMakePayment() 在不显示任何 UI 的情况下检查用户设备上至少一种请求的支付方式是否可用。 用它决定是显示支付请求按钮还是回退到重定向结账:

const available = await request.canMakePayment();
if (!available) {
// 重定向到托管结账页
}

注意:部分浏览器会对 canMakePayment() 的调用频率进行节流以防滥用。

在第三个构造参数 PaymentOptions 中传入可选标志,向用户请求额外信息:

  • requestShipping: true — 显示配送地址选择器;需要在 details 中至少提供一个 shippingOption
  • requestPayerNamerequestPayerEmailrequestPayerPhone — 从存储的配置文件中 请求联系人字段。

收到 PaymentResponse 后,始终调用 response.complete() 并传入 'success''fail',以告知浏览器处理已完成、面板可以关闭。不调用 complete() 会让面板停留在 挂起状态。

Browser / PlatformSupportSinceConfidenceSourceNotes
Chrome (Android)✅ yes61highref
Chrome (Desktop)✅ yes61highref
Edge (Desktop)✅ yes79highref
Safari (iOS)✅ yes11.1highrefBacked by Apple Pay as the payment method.
Safari (macOS)✅ yes11.1highrefBacked by Apple Pay.
Firefox (Desktop)❌ nomediumrefImplementation shipped then disabled; not available by default.
Samsung Internet✅ yes7.0mediumref

Ecosystem & commercial policy

EntityTypeContextStatusSponsoredNotes
Apple Paypayment_sdkSafari / iOS✅ supportedNoWorks in Safari via Payment Request; merchant-domain verification required.
Stripepayment_sdkCross-browser✅ supportedNoStripe wraps Payment Request as the Payment Request Button / Payment Element.
Google Play billingstore_policyGoogle Play TWA❌ unsupportedNoTWAs distributing digital goods must use Play Billing, not Payment Request, per Play policy.

Source: spec · MDN · Last verified 2026-06-24 · Confidence: high

当前各浏览器数据请参见 /compatibility/

决策问题 建议行为 理由
想提供原生钱包结账? 使用 PaymentRequest 并配合处理器的支付方式标识符。 避免构建自定义卡片输入 UI;使用已存储的凭据。
想在显示按钮前确认原生方式是否可用? 调用 canMakePayment() 并以结果门控按钮。 防止显示打开空面板或不支持面板的按钮。
用户需要选择配送地址? 设置 requestShipping: true 并填充 shippingOptions 浏览器收集地址;shippingaddresschange 监听器更新总价。
面向不支持 Payment Request 的浏览器? 提供标准重定向到托管结账页的回退。 iOS Safari 和 Android Chrome 均支持,但桌面端覆盖不一。
  • 仅在 HTTPS 下构造 PaymentRequest 并调用 show()
  • 在用户手势事件处理器内调用 show()
  • 服务端处理后调用 response.complete('success' | 'fail')
  • 静默捕获 show()AbortError——用户关闭了面板。
  • canMakePayment() 决定显示原生支付按钮还是回退 UI。
  • 切勿记录或存储原始 PaymentResponse 数据——立即传给后端处理。