javascript支付请求如何处理_如何使用payment request api【教程】

21次阅读

Payment Request API 需严格满足浏览器兼容性、安全上下文、用户手势触发及后端协同等条件;仅标准化收银信息环节,不替代支付全流程。

javascript支付请求如何处理_如何使用payment request api【教程】

Payment Request API 不是“能用就行”的接口,它依赖浏览器环境、支付方法支持和商家后端配合;直接调用 new PaymentRequest() 却没配置好支付方式或没处理 onpaymentmethodchange,大概率会触发 AbortError 或静默失败。

浏览器兼容性与基础初始化必须检查

chrome 61+、edge 79+、safari 16.4+(仅 apple Pay)支持,firefox 未实现。ios Safari 仅支持 Apple Pay,且需 https + 域名已注册为合法支付域(通过 Apple Developer Portal 配置)。

初始化前务必确认:

  • navigator.canMakePayment 返回 true(注意:该方法在 Safari 中始终返回 undefined,不能依赖它做兜底判断)
  • 传入 new PaymentRequest() 的第一个参数中,methodData 至少包含一个浏览器实际支持的支付方式,例如:[{supportedMethods: 'basic-card'}][{supportedMethods: 'https://apple.com/apple-pay', data: {...}}]
  • 不要省略 details.total,且 total.amount.value 必须是字符串格式数字(如 "19.99"),不是 19.99值类型

basic-card 支付方式的常见报错与绕过限制

Chrome 对 basic-card 有严格限制:仅允许在安全上下文(HTTPS)、用户主动触发(如 click 事件内)、且页面已获得焦点时调用。否则会抛出 SecurityError 或直接拒绝弹窗。

立即学习Java免费学习笔记(深入)”;

典型错误现象:Uncaught DOMException: Failed to construct 'PaymentRequest': Must be in a secure context 或点击无响应。

  • 确保调用 show() 在用户手势(如 button.onclick)回调内,不能在异步加载完成、定时器或 fetch 回调中直接调用
  • basic-card 不返回卡号明文,只返回经过令牌化的 cardNumber(如 “4242…4242″)和有效期,敏感字段需由后端对接支付网关解密
  • 若需获取完整卡信息(如测试环境调试),可临时启用 Chrome 标志 chrome://flags/#enable-basic-card-payment 并重启,但生产环境不可依赖

如何正确处理 paymentmethodchange 和 validateMerchant(Apple Pay)

onpaymentmethodchange 是动态更新价格/运费的关键钩子,但它不会自动触发;必须在初始化时显式绑定,并在回调里手动调用 Event.updateWith(),否则 ui 不会刷新。

Apple Pay 场景下,validateMerchant 是必经步骤:前端需向你的后端发起请求,换取 Apple 要求的 session,再用该 session 初始化 Apple Pay 实例。漏掉这步会卡在 “Processing…” 状态。

  • event.updateWith() 必须返回 promise,且 resolve 的对象结构必须含 total 和可选的 displayItems,不能只改 shippingoptions
  • Apple Pay 的 merchantIdentifier 必须与你在 Apple Developer Portal 注册的一致,且域名已添加到 Merchant IDs 的 Associated Domains 列表中
  • validateMerchant 接口返回的 session 必须是 Apple Pay SDK 可解析的 jsON(含 epochTimestamp, expiresAt, merchantSessionIdentifier 等字段),不是任意 Token

后端必须验证 paymentRequest.show() 后的 response

前端拿到的 response(来自 show().then())只是用户授权凭证,不是支付成功信号。其中 response.details 包含加密的支付数据(如 basic-cardtoken 或 Apple Pay 的 paymentToken),必须转发给后端由支付网关(Stripe / Adyen / 支付宝国际版等)验签并发起真实扣款。

  • 切勿在前端解析或尝试解密 response.details —— 它是加密 blob,且密钥由支付服务商控制
  • response.complete('success') 只是关闭 UI 弹窗,不代表钱已到账;必须等后端调用支付网关 API 返回 success 后,再调用它
  • 如果后端验签失败或扣款超时,应调用 response.complete('fail'),否则用户看到“支付成功”但订单未创建

最常被忽略的一点:Payment Request API 不提供退款、查询、重复支付控制能力,所有业务状态流转仍要靠你自己的订单系统和支付网关 API 对齐。它只是把“收银行卡信息”这个环节标准化了,而不是替代整个支付流程。

text=ZqhQzanResources