export const WECHAT_MINI_PROGRAM_PAYMENT_CHANNEL = 'wechat_mp'; export const WECHAT_H5_PAYMENT_CHANNEL = 'wechat_h5'; export const WECHAT_NATIVE_PAYMENT_CHANNEL = 'wechat_native'; export const MOCK_PAYMENT_CHANNEL = 'mock'; export type ProfileRechargeWechatPaymentChannel = | typeof WECHAT_MINI_PROGRAM_PAYMENT_CHANNEL | typeof WECHAT_H5_PAYMENT_CHANNEL | typeof WECHAT_NATIVE_PAYMENT_CHANNEL; type PaymentPlatformNavigator = Pick; export type PaymentPlatformContext = { location?: Pick | null; navigator?: Partial | null; matchMedia?: Window['matchMedia'] | null; }; export function shouldShowRechargeEntry( context: PaymentPlatformContext = {}, ) { const location = context.location ?? (typeof window !== 'undefined' ? window.location : null); const navigatorLike = context.navigator ?? (typeof navigator !== 'undefined' ? navigator : null); return ( isWechatMiniProgramRuntime(location) || isWechatBrowserRuntime(navigatorLike) ); } export function resolveProfileRechargePaymentChannel( context: PaymentPlatformContext = {}, ): ProfileRechargeWechatPaymentChannel { const location = context.location ?? (typeof window !== 'undefined' ? window.location : null); const navigatorLike = context.navigator ?? (typeof navigator !== 'undefined' ? navigator : null); const matchMedia = context.matchMedia ?? (typeof window !== 'undefined' && typeof window.matchMedia === 'function' ? window.matchMedia.bind(window) : null); if (isWechatMiniProgramRuntime(location)) { return WECHAT_MINI_PROGRAM_PAYMENT_CHANNEL; } if (isMobileWebRuntime(navigatorLike, matchMedia)) { return WECHAT_H5_PAYMENT_CHANNEL; } return WECHAT_NATIVE_PAYMENT_CHANNEL; } export function isManualMockPaymentChannel(paymentChannel: string) { return paymentChannel.trim() === MOCK_PAYMENT_CHANNEL; } function isWechatMiniProgramRuntime( location: Pick | null | undefined, ) { const params = new URLSearchParams(location?.search ?? ''); return ( params.get('clientRuntime') === 'wechat_mini_program' || params.get('clientType') === 'mini_program' ); } function isWechatBrowserRuntime( navigatorLike: Partial | null | undefined, ) { return ( navigatorLike?.userAgent?.toLowerCase().includes('micromessenger') ?? false ); } function isMobileWebRuntime( navigatorLike: Partial | null | undefined, matchMedia: Window['matchMedia'] | null | undefined, ) { const userAgent = navigatorLike?.userAgent?.toLowerCase() ?? ''; if (/android|iphone|ipad|ipod|mobile|windows phone/u.test(userAgent)) { return true; } if ((navigatorLike?.maxTouchPoints ?? 0) > 1) { return true; } return Boolean(matchMedia?.('(max-width: 767px)').matches); }