跳转到内容

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。