55 lines
1.7 KiB
TypeScript
55 lines
1.7 KiB
TypeScript
/**
|
|
* 打开支付URL(系统浏览器 / 内嵌 WebView / 小游戏 API),可插拔
|
|
*
|
|
*/
|
|
|
|
import { sys } from "cc";
|
|
|
|
export type OpenStrategy = "system" | "inapp" | "minigame";
|
|
|
|
export interface IPaymentOpener {
|
|
open(url: string): Promise<void>;
|
|
canReturnSignal(): boolean; // 是否能“自动感知回到App”(inapp/minigame一般可以)
|
|
}
|
|
|
|
/** 系统浏览器:使用 sys.openURL。无法自动知道用户何时完成,靠“回到前台”事件触发轮询 */
|
|
class SystemBrowserOpener implements IPaymentOpener {
|
|
async open(url: string) { sys.openURL(url); }
|
|
canReturnSignal() { return false; }
|
|
}
|
|
|
|
// 如需内嵌 WebView,可封装一个组件并在 open 里显示;此处给空壳
|
|
class InAppWebViewOpener implements IPaymentOpener {
|
|
async open(url: string) {
|
|
// TODO: 实现你的 WebView 弹窗并加载 url;可拦截 redirect_uri 关闭弹窗
|
|
sys.openURL(url); // 临时:用系统浏览器兜底
|
|
}
|
|
canReturnSignal() { return true; } // 拦截回跳时可立即开始轮询
|
|
}
|
|
|
|
// 小游戏:使用平台API打开/内嵌webview,回跳后触发事件
|
|
class MiniGameOpener implements IPaymentOpener {
|
|
async open(url: string) {
|
|
const g: any = globalThis as any;
|
|
if (g.tt?.openAwemeUserProfile) {
|
|
// 示例:按实际平台API替换
|
|
g.tt.openSchema({ schema: url });
|
|
} else if (g.wx?.openUrl) {
|
|
g.wx.openUrl({ url });
|
|
} else {
|
|
sys.openURL(url);
|
|
}
|
|
}
|
|
canReturnSignal() { return true; }
|
|
}
|
|
|
|
export class PaymentOpenerFactory {
|
|
static create(strategy: OpenStrategy): IPaymentOpener {
|
|
switch (strategy) {
|
|
case "inapp": return new InAppWebViewOpener();
|
|
case "minigame": return new MiniGameOpener();
|
|
default: return new SystemBrowserOpener();
|
|
}
|
|
}
|
|
}
|