feat: gate recharge payment by login device

This commit is contained in:
2026-05-15 08:43:21 +08:00
parent 5b70ec6af7
commit c94f22e26c
12 changed files with 527 additions and 72 deletions

View File

@@ -2,6 +2,7 @@ import { describe, expect, test } from 'vitest';
import {
resolveProfileRechargePaymentChannel,
shouldShowRechargeEntry,
WECHAT_H5_PAYMENT_CHANNEL,
WECHAT_MINI_PROGRAM_PAYMENT_CHANNEL,
WECHAT_NATIVE_PAYMENT_CHANNEL,
@@ -51,6 +52,19 @@ describe('resolveProfileRechargePaymentChannel', () => {
).toBe(WECHAT_NATIVE_PAYMENT_CHANNEL);
});
test('桌面微信内网页选择 wechat_native', () => {
expect(
resolveProfileRechargePaymentChannel({
location: { search: '' },
navigator: {
userAgent:
'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit MicroMessenger/8.0',
},
matchMedia: () => ({ matches: false }) as unknown as MediaQueryList,
}),
).toBe(WECHAT_NATIVE_PAYMENT_CHANNEL);
});
test('默认路径永远不会解析成 mock', () => {
expect(
resolveProfileRechargePaymentChannel({
@@ -61,3 +75,44 @@ describe('resolveProfileRechargePaymentChannel', () => {
).not.toBe('mock');
});
});
describe('shouldShowRechargeEntry', () => {
test('小程序运行态显示充值入口', () => {
expect(
shouldShowRechargeEntry({
location: { search: '?clientRuntime=wechat_mini_program' },
navigator: { userAgent: 'Mozilla/5.0 (iPhone)' },
}),
).toBe(true);
});
test('微信内网页显示充值入口', () => {
expect(
shouldShowRechargeEntry({
location: { search: '' },
navigator: {
userAgent:
'Mozilla/5.0 (Linux; Android 14) AppleWebKit MicroMessenger/8.0 Mobile',
},
}),
).toBe(true);
});
test('普通浏览器不显示充值入口', () => {
expect(
shouldShowRechargeEntry({
location: { search: '' },
navigator: {
userAgent:
'Mozilla/5.0 (iPhone; CPU iPhone OS 17_0 like Mac OS X) Mobile',
},
}),
).toBe(false);
expect(
shouldShowRechargeEntry({
location: { search: '' },
navigator: { userAgent: 'Mozilla/5.0 (Windows NT 10.0; Win64; x64)' },
}),
).toBe(false);
});
});

View File

@@ -16,6 +16,20 @@ export type PaymentPlatformContext = {
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 {
@@ -55,16 +69,21 @@ function isWechatMiniProgramRuntime(
);
}
function isWechatBrowserRuntime(
navigatorLike: Partial<PaymentPlatformNavigator> | null | undefined,
) {
return (
navigatorLike?.userAgent?.toLowerCase().includes('micromessenger') ??
false
);
}
function isMobileWebRuntime(
navigatorLike: Partial<PaymentPlatformNavigator> | null | undefined,
matchMedia: Window['matchMedia'] | null | undefined,
) {
const userAgent = navigatorLike?.userAgent?.toLowerCase() ?? '';
if (
/android|iphone|ipad|ipod|mobile|micromessenger|windows phone/u.test(
userAgent,
)
) {
if (/android|iphone|ipad|ipod|mobile|windows phone/u.test(userAgent)) {
return true;
}