How it works
- Create a session via the API
- Construct the webview URL from the session ID and client secret
- Load that URL in your native WebView
- Listen for
postMessageevents to track payment progress
Create a session
Load the WebView
iOS (Swift)
Android (Kotlin)
React Native
Query parameters
| Parameter | Required | Values | Description |
|---|---|---|---|
session | Yes | string | Session ID |
cs | Yes | string | Client secret |
locale | No | es, fr, etc. | UI language (default: browser locale) |
theme | No | light, dark | Color theme (default: auto) |
layout | No | embed | Renders inline; omit for modal (default) |
Handle events
The WebView sends messages viapostMessage. The message format:
| Event | Description |
|---|---|
ready | Payment UI finished loading |
modalOpened | Modal became visible |
modalClosed | Modal was dismissed |
contentHeightChanged | Embedded content height changed |
paymentStarted | User’s deposit transaction is detected |
paymentCompleted | Funds delivered to destination |
payload object is empty. contentHeightChanged includes { "height": number } in CSS pixels. To get full session details (tx hash, chain, amounts, etc.) after any payment event, poll GET /v1/sessions/{sessionId}.
Fit embedded height
When you load the webview inside your own modal or bottom sheet, addlayout=embed and size the host container to the reported content height. This avoids showing a full-screen webview with empty space below the payment UI.
contentHeightChanged whenever its rendered height changes. In React Native, store that height and apply it to the WebView:
Theming
Set your org theme in the Daimo dashboard to match the hosted payment UI to your brand. The WebView loads it automatically from the session. Usetheme=light or theme=dark to force a mode. Otherwise, the UI follows the user’s system preference.
See Customization for the dashboard flow, token list, and per-session CSS override.
sendToHost protocol
The webview page communicates with the host container via asendToHost function that tries three transport layers in order:
- React Native / Expo —
window.ReactNativeWebView.postMessage(JSON.stringify(msg)) - iOS / macOS WKWebView —
window.webkit.messageHandlers.daimoPay.postMessage(msg) - Browser iframe / desktop WebView —
window.parent.postMessage(msg, "*")