নিরাপত্তা কাঠামো
- Signed session সবসময় আপনার backend থেকে তৈরি করুন—Flutter, Android, iOS বা browser code থেকে নয়।
- প্রতিটি launch URL short-lived; active subscription ও game entitlement server-এ যাচাই হয়।
- Wallet callback signed ও idempotent; signature যাচাই করুন এবং reused nonce বাতিল করুন।
- WebView message origin ও event type allow-list দিয়ে যাচাই করুন।
Production launch flow
- 1আপনার app নিজের login system দিয়ে user authenticate করে।
- 2আপনার backend private app secret দিয়ে one-time game session চায়।
- 3Backend mobile app-কে শুধু launch URL দেয়।
- 4App full বা voice-room layout-এ URL WebView-তে খোলে।
- 5Fah Swe server subscription, entitlement, expiry ও session state যাচাই করে।
১. Backend-এ session তৈরি করুন
// Your trusted backend only — never put appSecret in a mobile app
const response = await fetch("https://game-api.fahswe.com/v1/sessions", {
method: "POST",
headers: {
"Content-Type": "application/json",
"X-App-Id": process.env.FAHSWE_APP_ID!,
"X-Timestamp": timestamp,
"X-Nonce": nonce,
"X-Signature": createHmacSignature(body, timestamp, nonce),
},
body: JSON.stringify({
gameId: "food-wheel",
externalUserId: user.id,
layout: "voice", // "full" or "voice"
}),
});
const { launchUrl } = await response.json();২. Client-এ launch URL খুলুন
final controller = WebViewController()
..setJavaScriptMode(JavaScriptMode.unrestricted)
..addJavaScriptChannel('FahSweGame', onMessageReceived: (event) {
final message = jsonDecode(event.message);
if (message['type'] == 'game.close') Navigator.pop(context);
})
..loadRequest(Uri.parse(launchUrl)); // URL received from your backendwebView.settings.javaScriptEnabled = true
webView.settings.domStorageEnabled = true
webView.addJavascriptInterface(GameBridge(), "FahSweGame")
webView.loadUrl(launchUrl) // one-time URL from your backend
class GameBridge {
@JavascriptInterface fun postMessage(json: String) {
// Parse an allow-listed event: game.ready, game.close, wallet.refresh
}
}let controller = WKUserContentController()
controller.add(self, name: "FahSweGame")
let config = WKWebViewConfiguration()
config.userContentController = controller
let webView = WKWebView(frame: .zero, configuration: config)
webView.load(URLRequest(url: launchUrl)) // obtained from your backend<WebView
source={{ uri: launchUrl }}
javaScriptEnabled
domStorageEnabled
originWhitelist={["https://games.fahswe.com"]}
onMessage={({ nativeEvent }) => {
const event = JSON.parse(nativeEvent.data);
if (event.type === "game.close") navigation.goBack();
}}
/><iframe
src={launchUrl}
title="Fah Swe game"
allow="autoplay; fullscreen"
sandbox="allow-scripts allow-same-origin"
referrerPolicy="strict-origin-when-cross-origin"
/>
// Validate event.origin === "https://games.fahswe.com" before processing.Bridge event
Game versioned JSON message পাঠায়: game.ready, game.close, game.result ও wallet.refresh। Message-কে untrusted input ধরুন; origin, type ও payload যাচাই করুন এবং WebView দেওয়া balance কখনও বিশ্বাস করবেন না।
Subscription ও downtime behavior
শুধু active subscriber session তৈরি করতে পারে। Grace period-এ payment warning দেখায়; grace শেষ হলে নতুন session বন্ধ হয়। Verified paid invoice backend দিয়ে service আবার স্বয়ংক্রিয়ভাবে চালু করে।
শুধু virtual entertainment
Fah Swe gambling, cash wagering, cash redemption বা transferable-value credit দেয় না। Age control, store policy, স্থানীয় আইন ও সঠিক disclosure integrator-এর দায়িত্ব।