En la web abierta, tocar «Pagar» abre el panel de pago del navegador: Apple Pay en Safari, Google Pay en Chrome o la Payment Request API en todos los navegadores. Dentro de un WebView, esos botones desaparecen en silencio. Apple Pay simplemente no está disponible en WKWebView, y Android desactiva la Payment Request API salvo que el host la reactive explícitamente. Un runtime propio del host conecta los SDK de pago nativos: una llamada de pago uniforme que resuelve Apple Pay, Google Pay o la billetera de la plataforma en cada motor.
Apple Pay: solo Safari y SFSafariViewController
La documentación de Apple y todo el ecosistema de pagos son claros: Apple Pay en la web solo se admite en Safari y SFSafariViewController. Apple indica a las apps que cargan el checkout en un WKWebView que muevan la solicitud de pago al código nativo. Apple Pay JS (window.ApplePaySession) es efectivamente inexistente en un WebView integrado; el panel que se abre de forma nativa en Safari desaparece y la página no obtiene ningún método de pago utilizable: la opción simplemente no se ofrece.
iOS 13 abrió un camino estrecho para Apple Pay dentro de WKWebView, pero con una trampa dura: si la app llama a WKUserScript o evaluateJavaScript antes de que la página use Apple Pay, la transacción se desactiva. Con el WebKit por niveles, más WKWebViews ahora están restringidas totalmente a la inyección de scripts. Para una app híbrida, el resultado práctico es el mismo: no se puede confiar en el panel de pago web y hay que conectar Apple Pay mediante PKPaymentAuthorizationController en código nativo.
Android: Payment Request desactivada por defecto
La propia documentación de Google Pay lo dice sin rodeos: «Por defecto, WebView desactiva la Payment Request API». Cuando un checkout web se incrusta en un Android WebView, la Payment Request API —que el flujo web de Google Pay usa para abrir el panel de pago— está apagada. Para reactivarla, el host debe añadir la dependencia AndroidX WebKit, declarar la bandera de metadatos android.webkit.WebView.enablePaymentRequest y llamar a WebSettingsCompat.setPaymentRequestEnabled(settings, true) en tiempo de ejecución.
Y los requisitos son estrictos: Google Pay dentro del WebView necesita Google Play services 25.18.30+ y Android WebView (Chrome) 137+, y isReadyToPay devuelve false cuando no se cumplen. Stripe ha dejado obsoleto su Payment Request Button, y los proveedores empujan sistemáticamente hacia SDK nativos precisamente porque la ruta web integrada es poco fiable.
Qué se rompe cuando el pago muere
- El botón de la billetera nunca aparece. Un checkout que muestra Apple Pay o Google Pay en el navegador no muestra ninguno en el WebView: sin error, solo una opción ausente.
- La conversión se desploma. Los usuarios que pagaban solo con una billetera quedan obligados a teclear los datos de la tarjeta o abandonan.
- El inicio de sesión federado también falla. El mismo WebView integrado pierde el inicio de sesión con Google (
disallowed_useragent), así que login y pago se bloquean a la vez. - Los navegadores de apps sociales también lo ocultan. Los WebViews de WeChat, Douyin, Instagram y Facebook imponen sus propias restricciones, por lo que la rotura no aparece en el QA de escritorio.
La solución del runtime
Un runtime propio del host conecta la capa de pago. La página llama a una API uniforme —runtime.requestPayment(methods, details)— y el host la resuelve mediante el SDK de pago nativo de la plataforma: Apple Pay vía PKPaymentAuthorizationController en iOS, Google Pay / el panel de pago nativo en Android. La sesión del comerciante, la presentación del panel y la devolución del token se gestionan de forma nativa y coherente. Una integración, cada motor, un checkout completado.
| Dimensión | WebView | Runtime propio del host |
|---|---|---|
| Apple Pay (iOS) | No soportado en WKWebView | PKPaymentAuthorizationController nativo |
| Google Pay (Android) | Payment Request desactivada por defecto | SDK de Google Pay nativo |
| Activación | Banderas del host + AndroidX WebKit | Un runtime.requestPayment() |
| Presentación del panel | Del navegador, ausente | Del host, fiable |
| Respaldo | Solo tarjeta manual | Billetera o tarjeta, ambas conectadas |
| Consistencia | Según el motor | Uniforme |
Una app nativa completa un pago con billetera en todos los dispositivos. Un WebView estándar lo completa en casi ninguno. Un runtime da a la página una acción de pago —y una autorización real al final.
Fuentes
- Apple Developer — Password AutoFill / guía de Apple Pay en la web — Apple lleva las solicitudes de pago del WKWebView al código nativo; Apple Pay en la web es función de Safari / SFSafariViewController.
- Google Pay API for Android — Usar Android WebView — «Por defecto, WebView desactiva la Payment Request API»; requiere AndroidX WebKit +
setPaymentRequestEnabled. - openpwa — Ecosistema de pagos — «un WKWebView no puede [usar Apple Pay] y Apple dirige esas apps al código nativo»; matriz de capas y comportamiento de Payment Request.
- MoonPay — FAQ de pagos móviles — Apple Pay no soportado en WKWebView; Google Pay no soportado oficialmente en WebViews, usar Chrome Custom Tabs.
- Breeze — Guía de apps móviles embebidas — el WebView estándar es el único contenedor que pierde tanto Google Pay como el inicio de sesión federado; los métodos restantes son tarjeta, Apple Pay y crypto.