在开放网络上,点击"支付"会唤起浏览器的支付面板——Safari 上的 Apple Pay、Chrome 上的 Google Pay,或跨浏览器的 Payment Request API。但在 WebView 内部,这些按钮会悄然消失。Apple Pay 在 WKWebView 中根本不可用,而 Android 默认会禁用 Payment Request API,除非宿主显式重新开启。宿主自有 runtime 桥接原生支付 SDK——一次统一的结账调用,在每个引擎上都能解析到 Apple Pay、Google Pay 或平台钱包。
Apple Pay:仅限 Safari 与 SFSafariViewController
苹果自己的文档以及更广泛的支付生态都说得很清楚:网络版 Apple Pay 仅在 Safari 和 SFSafariViewController 中受支持。苹果明确要求把在 WKWebView 中加载的结账流程改为走原生代码。Apple Pay JS(window.ApplePaySession)在嵌入式 WebView 中基本不可用——Safari 里原生弹出的面板没有了,页面拿不到可用的支付方式,选项就是不会出现。
iOS 13 为 WKWebView 内的 Apple Pay 开了一条窄路,但附带硬性限制:如果 App 在页面使用 Apple Pay 之前调用了 WKUserScript 或 evaluateJavaScript,该交易就会被禁用。随着分级 WebKit 的引入,更多 WKWebView 被系统完全限制脚本注入。对混合式 App 来说,实际结果一样:你不能依赖网页支付面板,必须通过 PKPaymentAuthorizationController 用原生代码桥接 Apple Pay。
Android:Payment Request 默认关闭
谷歌自己的 Google Pay 文档说得很直白:"默认情况下,WebView 会禁用 Payment Request API。"当网页结账被嵌入 Android WebView 时,Google Pay 网页流程赖以唤起支付面板的 Payment Request API 是关闭的。要重新启用,宿主必须添加 AndroidX WebKit 依赖、声明 android.webkit.WebView.enablePaymentRequest 元数据标志,并在运行时调用 WebSettingsCompat.setPaymentRequestEnabled(settings, true)。
而且要求很严格:WebView 内的 Google Pay 需要 Google Play 服务 25.18.30+ 以及 Android WebView(Chrome)137+,不满足时 isReadyToPay 会返回 false。Stripe 已经弃用其 Payment Request Button,各服务商也一致建议走原生 SDK,正是因为这条嵌入式网页路径不可靠。
支付失效时会怎样
- 钱包按钮根本不出现。 在浏览器里显示 Apple Pay 或 Google Pay 的结账页,在 WebView 里两者都不显示——没有报错,只是选项消失。
- 转化率崩塌。 只使用钱包支付的用户被迫手填卡号,或直接放弃。
- 联合登录随之失效。 同一个嵌入式 WebView 也会丢掉 Google 登录(
disallowed_useragent),于是登录和支付双双卡住。 - 社交 App 内置浏览器同样隐藏它。 微信、抖音、Instagram、Facebook 的 WebView 各有各的限制,所以桌面 QA 阶段根本发现不了这个问题。
runtime 解法
宿主自有 runtime 桥接支付层。页面调用统一的 API——runtime.requestPayment(methods, details)——宿主通过平台原生支付 SDK 完成解析:iOS 走 PKPaymentAuthorizationController 的 Apple Pay,Android 走 Google Pay / 原生支付面板。商户会话、面板展示与令牌回传都由原生一致处理。一次集成,每个引擎,一次完成的结账。
| 维度 | WebView | 宿主自有 runtime |
|---|---|---|
| Apple Pay(iOS) | WKWebView 不支持 | 原生 PKPaymentAuthorizationController |
| Google Pay(Android) | Payment Request 默认禁用 | 原生 Google Pay SDK |
| 启用方式 | 宿主标志 + AndroidX WebKit | 一次 runtime.requestPayment() |
| 面板展示 | 浏览器所有、缺失 | 宿主所有、可靠 |
| 兜底 | 仅手动输卡 | 钱包或卡,均已接通 |
| 一致性 | 因引擎而异 | 统一 |
原生 App 能在每台设备上完成钱包结账;裸 WebView 几乎在每台设备上都不行。runtime 给页面一个支付动作——以及最终一次真实的授权。
参考来源
- Apple Developer — Password AutoFill / 网络版 Apple Pay 指引 — 苹果要求把 WKWebView 的支付请求改为原生代码;网络版 Apple Pay 是 Safari / SFSafariViewController 特性。
- Google Pay API for Android — 使用 Android WebView — "默认情况下 WebView 会禁用 Payment Request API";需要 AndroidX WebKit +
setPaymentRequestEnabled。 - openpwa — Payments 生态 — "WKWebView 无法使用 Apple Pay,苹果建议改为原生代码";Payment Request 层级与行为矩阵。
- MoonPay — 移动支付 FAQ — Apple Pay 不支持于 WKWebView;Google Pay 官方不支持于 WebView,应使用 Chrome Custom Tabs。
- Breeze — 嵌入式移动应用指南 — 裸 WebView 是唯一会同时丢失 Google Pay 与联合登录的容器;剩余可用方式为卡、Apple Pay、crypto。