# Mobile WebView Integration

You can use Inline Checkout inside a mobile app by loading a checkout web page in a WebView. The native app owns navigation, loading states, and lifecycle recovery, while xMoney's web SDK owns card collection, wallet orchestration, 3DS, and payment submission.

Use this guide when your mobile app already has a web checkout page or when you want one shared checkout implementation for web, iOS, and Android.

For hosted checkout WebView flows, see [Accepting Payments in Your Mobile App](/guides/mobile-apps/accepting-payments).

## Recommended architecture

```mermaid
sequenceDiagram
  participant mobileApp as MobileApp
  participant checkoutPage as CheckoutWebPage
  participant merchantBackend as MerchantBackend
  participant xMoneySdk as XMoneySDK
  participant xMoneyApi as XMoneyAPI

  mobileApp->>checkoutPage: Open WebView checkout URL
  checkoutPage->>merchantBackend: Create inline checkout order
  merchantBackend-->>checkoutPage: publicKey, orderPayload, orderChecksum
  checkoutPage->>xMoneySdk: Mount paymentForm or custom widgets
  xMoneySdk->>xMoneyApi: Process card, wallet, or saved card payment
  alt Requires3DS
    xMoneySdk-->>mobileApp: WebView opens authentication flow
  end
  xMoneySdk-->>checkoutPage: onPaymentComplete or onError
  checkoutPage-->>mobileApp: Notify native shell of result state
```

## Web checkout page

The WebView should load a normal HTTPS checkout page that includes the SDK script and mounts one of the inline checkout widgets.

```html
<script src="https://secure.xmoney.com/sdk/v2/xmoney.js"></script>
<div id="xmoney-payment-form"></div>
```

```javascript
const paymentForm = await window.XMoney.paymentForm({
  container: 'xmoney-payment-form',
  publicKey,
  orderPayload,
  orderChecksum,
  paymentMethods: {
    applePay: { enabled: true },
    googlePay: { enabled: true },
  },
  options: {
    locale: 'en-US',
    enableBackgroundRefresh: true,
  },
  onPaymentProcessing(isProcessing) {
    notifyNativeApp({ type: 'payment-processing', isProcessing })
  },
  onPaymentComplete(transaction) {
    notifyNativeApp({ type: 'payment-complete', transaction })
  },
  onError(error) {
    notifyNativeApp({ type: 'payment-error', error })
  },
})

function notifyNativeApp(message) {
  window.webkit?.messageHandlers?.xmoneyCheckout?.postMessage(message)
  window.XMoneyAndroid?.postMessage?.(JSON.stringify(message))
}
```

The native bridge is optional. You can also show result states entirely inside the WebView.

## Native shell responsibilities

Keep native code focused on WebView lifecycle, not payment business logic.

The native app should:

1. Open the checkout URL in a secure WebView or browser tab.
2. Show native loading, cancel, and retry states around the WebView.
3. Preserve the checkout page when the app is backgrounded.
4. Allow 3DS and wallet flows to open required external contexts.
5. Wait for the web checkout result before closing the WebView.
6. Ask your backend for final order status before showing fulfillment states.


The native app should not collect PAN or duplicate the payment form in native UI.

## iOS guidance

For `WKWebView`:

- Use HTTPS for the checkout page.
- Allow JavaScript and window opening behavior needed by wallet and 3DS flows.
- Preserve the `WKWebView` instance during backgrounding when possible.
- Handle universal links or callback URLs that may return from a bank authentication app.
- Do not clear cookies or website data during an active checkout.


If you use Apple Pay, validate the complete flow on real devices. Apple Pay availability depends on the device, browser/WebView capabilities, wallet setup, merchant activation, and domain verification.

## Android guidance

For Android WebView:

- Enable JavaScript for the checkout page.
- Use a `WebChromeClient` and `WebViewClient` configuration that supports popups or external URL handling required by 3DS.
- Persist the checkout URL and any invocation context across activity recreation.
- Handle app links or return URLs that may resume the checkout after bank authentication.
- Prefer Custom Tabs if your WebView policy blocks wallet or 3DS requirements.


Google Pay availability depends on device support, Google Play services, wallet setup, merchant activation, and browser/WebView support.

## 3DS lifecycle rules

3DS may temporarily move the shopper away from your checkout view. To avoid losing the payment state:

1. Keep `enableBackgroundRefresh: true`.
2. Do not close or recreate the checkout WebView during authentication.
3. Persist enough state to reopen the same checkout page if the OS kills the app.
4. Treat `onPaymentComplete` as a client signal and confirm final status server-side.


See [3DS and payment results](/guides/checkout/inline-checkout/3ds-results) for callback behavior.

## Shared web and mobile code

A practical pattern is to keep one checkout page that works in both a browser and WebView:

```javascript
const isNativeWebView =
  Boolean(window.webkit?.messageHandlers?.xmoneyCheckout) ||
  Boolean(window.XMoneyAndroid)

function finishCheckout(transaction) {
  if (isNativeWebView) {
    notifyNativeApp({ type: 'payment-complete', transaction })
    return
  }

  window.location.href = `/checkout/result?orderId=${transaction.externalOrderId}`
}
```

This keeps payment behavior consistent while still letting the native app control the surrounding experience.

## Related guides

- [Website integration](/guides/checkout/inline-checkout/web-integration)
- [3DS and payment results](/guides/checkout/inline-checkout/3ds-results)