Part 10 · 1 chapters · ~10 min

Hybrid, WebView and Real Devices

Web money flows embedded in native and Flutter apps: why teams embed, a typed and versioned bridge that degrades gracefully, the features WebViews handle differently, auth across the boundary with one-time codes, low-tier performance budgets, and testing in real WebViews on cheap phones.

13

The bridge, the gaps and the cheap phone

web code in someone else's app
  1. Why embed: one flow for every platform, with no store release for each change.
  2. The bridge is typed, versioned, answered or timed out, and the page still works when it is absent.
  3. The gaps: uploads, new windows, downloads, storage, back navigation, redirects.
  4. Auth: one-time codes, HttpOnly cookies through the BFF, step-up requested over the bridge.
  5. Real devices: budgets set by the low tier, RUM tagged by host.
  6. Test in real WebViews on cheap phones.
code
// a typed bridge that degrades in a plain browser
type ToNative = { type: 'requestStepUp'; reason: 'withdrawal' } | { type: 'saveFile'; name: string; url: string } | { type: 'close' };
type FromNative = { type: 'stepUpResult'; ok: boolean } | { type: 'saved' } | { type: 'error'; message: string };

const host = (window as any).NativeBridge ?? (window as any).flutter_inappwebview;   // whichever the app injects
export async function callNative(msg: ToNative, timeoutMs = 15_000): Promise<FromNative | null> {
  if (!host) return null;                                    // plain browser: caller uses the web fallback
  return Promise.race([
    host.callHandler?.('bridge', { v: 1, ...msg }) ?? new Promise(res => host.postMessage(JSON.stringify({ v: 1, ...msg }), res)),
    new Promise<null>(res => setTimeout(() => res(null), timeoutMs)),   // never hang a money flow on the bridge
  ]);
}

// statement download: native save inside the app, a normal link in the browser
const r = await callNative({ type: 'saveFile', name: 'statement-2026-09.pdf', url });
if (!r) window.location.assign(url);
your evidence
Ohlify (Flutter, with Paystack and wallet flows) and the low-end Android constraints of Nigerian users are your examples here. Be precise about what you have shipped in WebViews and what you have only designed. If WebView experience is thin, say so and show this chapter's understanding instead.
HYBRID AND WEBVIEW, ON REAL DEVICES
web flows embedded in native apps: the bridge, the gaps, and the performance of a cheap phone
swipe the figure sideways, or tap expand for full screen
1/6
why embed
Why embed: one web implementation of a complex, frequently changing flow (KYC, cashier) ships to web, iOS and Android without app-store releases. The cost: a WebView is a browser engine with less memory, different defaults and a host app in control of navigation, storage and permissions.