WebView 桥接
原生壳里的网页无法直接访问 StoreKit 或 Play Billing。桥接让页面通过 postMessage 调用 getProducts、purchase、restore、getCustomer 和 ads.showRewarded。原生端用 SDK 执行这些调用,再把结果发回页面。
import { useMemo, useRef } from "react";import { WebView } from "react-native-webview";import { Kasskeep, KASSKEEP_WEBVIEW_INJECTED_JS, createKasskeepWebViewBridge } from "@kasskeep/react-native";
export function GameScreen() { const ref = useRef<WebView>(null); const bridge = useMemo( () => createKasskeepWebViewBridge({ webViewRef: ref, allowedOrigins: ["https://game.example.com"], methods: ["getProducts", "purchase", "restore", "getCustomer", "setAppUserId"], onAppUserId: (id) => { if (Kasskeep.appUserId) Kasskeep.setAppUserId(id); else Kasskeep.configure({ apiKey: "pk_...", baseUrl: "https://api.kasskeep.com", appUserId: id }); }, }), [], ); return ( <WebView ref={ref} source={{ uri: "https://game.example.com/" }} originWhitelist={["https://game.example.com"]} injectedJavaScriptBeforeContentLoaded={KASSKEEP_WEBVIEW_INJECTED_JS} onMessage={(e) => { if (bridge.onMessage(e)) return; }} /> );}createKasskeepWebViewBridge(options) 返回 { onMessage(event): boolean, dispose() }。对于非桥接消息,onMessage 返回 false,壳可以自行处理。
| 选项 | 含义 |
|---|---|
webViewRef |
指向 WebView 的 ref |
allowedOrigins |
必填。精确的 scheme://host[:port] origin。来自其他 origin 的消息直接丢弃,不作答复 |
methods |
允许列表。默认为 getProducts、purchase、restore、getCustomer、ads.showRewarded。setAppUserId 只有列出时才允许 |
onAppUserId(id) |
收到 setAppUserId 时调用,通常在页面登录后用来调用 Kasskeep.configure |
onRejected(r) |
以 { reason: "origin" | "version" | "method" | "malformed", origin, method? } 调用 |
版本 1。页面发送:
{"tag": "kasskeep", "v": 1, "id": "<request id>", "method": "purchase", "params": {}}原生端调用 window.__kasskeepBridgeReceive 作答,参数为 {"tag": "kasskeep", "v": 1, "id": "<same id>", "ok": true, "result": ...} 或 {"ok": false, "error": {"code", "message", "retryable?", "status?"}}。只有当 location.origin 仍是发出请求时的 origin,答复才会送达。结果经过 JSON 转义,无法逃逸出注入的脚本。
页面端请使用实现了这套协议的 kasskeep-web.js。