Skip to main content

X-Pays in a Webview

X-Pay buttons (Google Pay, Apple Pay) are rendered by the partner SDK, not by Purse. Those SDKs rely on platform payment APIs that a mobile app webview disables by default. When the host app does not enable them, the wallet deactivates itself and its button never appears — regardless of your checkout code.

These requirements are set by Google and Apple, so they apply to every Purse integration mode: Drop-in, Headless, Hosted Page and Widget v3 alike. Nothing on this page is specific to one SDK.

This is host-app configuration

Nothing on this page can be fixed from the web page or from your Purse dashboard. The switches live in the native app that hosts the webview.

How a webview failure shows up

Wallet compatibility is resolved at mount time, after the partner SDK loads — there is no reliable pre-mount check. A wallet that cannot run in the current client deactivates itself, so the symptom is a button that simply never renders, with no error shown to the customer.

With the Headless SDK, that self-deactivation is observable: the element receives a fatal error with internalEventCode: "pluginIsIncompatibleWithClient", then the method is removed from checkout.paymentMethods — see Handle Incompatible Methods. Drop-in, Hosted Page and Widget v3 drop the button from their own UI without any action on your side.

Android WebView — Google Pay

The Payment Request API that Google Pay depends on is disabled by default in WebView. The host app must:

  • Opt the WebView in to the Payment Request API (via the androidx.webkit support library).
  • Declare the Google Pay intents in its AndroidManifest.xml queries block, so the WebView can reach the Google Pay app.
  • Run on a recent enough Google Play services and system WebView — below those versions the readiness check returns false and the button is skipped.
  • Append the Google Pay marker to the user agent if the app sets a custom one.
  • Avoid routing webview traffic through a third-party HTTP client, which is not supported for this flow.

Version numbers and the exact API calls change; always follow Google's recipe as the source of truth.

Partner documentation

Using Google Pay in an Android WebView — Google's official requirements, with the current minimum versions and code samples.

iOS WKWebView — Apple Pay

Apple Pay on the web works inside WKWebView since iOS 13, but it is mutually exclusive with script injection:

In order to protect the security of Apple Pay transactions in WKWebView, Apple Pay cannot be used alongside of script injection APIs such as WKUserScript or evaluateJavaScript(_:completionHandler:).

Concretely:

  • If the app calls one of those APIs before the page uses Apple Pay, Apple Pay is disabled for that page.
  • If the page uses Apple Pay first, a later evaluateJavaScript(_:completionHandler:) call fails with an error.
  • Both restrictions reset on every top-frame navigation.
The usual cause

App-to-webview bridges are built on exactly those two APIs. An app that injects a script to pass the cart, the customer or a theme into the page has already disabled Apple Pay by the time checkout mounts. Pass that data through the page URL or a server-side call instead, and keep the checkout page free of injected scripts.

Apple Pay also keeps its usual web requirements inside a webview: HTTPS, and a domain validated with Apple.

Partner documentation

New WebKit features in Safari 13 — the WKWebView Apple Pay rules · Apple Pay JS API

Best practices

  • Test on a real device, in the real app. A wallet that renders in a desktop browser or in the platform simulator proves nothing about the host webview.
  • Let the checkout drive which wallets are shown. A wallet that self-disables disappears on its own; do not hard-code a wallet button or reserve a fixed slot for one.
  • Always keep a non-wallet method available. Wallet availability is decided by the client, so card or another method must remain reachable.
  • Prefer the system browser when the app cannot comply. Opening checkout in Chrome Custom Tabs (Android) or Safari (iOS) gives a full browser context, with no webview configuration to maintain.

See also