增加Gopay模式

This commit is contained in:
QLHazyCoder
2026-04-30 23:43:02 +08:00
parent 7e05b42e3c
commit 4bb734fd1d
11 changed files with 631 additions and 67 deletions
+64 -1
View File
@@ -20,6 +20,7 @@
clearStopRequest,
closeLocalhostCallbackTabs,
closeTabsByUrlPrefix,
completeStepFromBackground,
deleteHotmailAccount,
deleteHotmailAccounts,
deleteIcloudAlias,
@@ -418,6 +419,54 @@
return { ok: true };
}
case 'RESOLVE_PLUS_MANUAL_CONFIRMATION': {
const currentState = await getState();
const step = Number(message.payload?.step) || Number(currentState?.plusManualConfirmationStep) || 0;
const confirmed = Boolean(message.payload?.confirmed);
const requestId = String(message.payload?.requestId || '').trim();
const currentRequestId = String(currentState?.plusManualConfirmationRequestId || '').trim();
if (!currentState?.plusManualConfirmationPending) {
return { ok: true, ignored: true };
}
if (requestId && currentRequestId && requestId !== currentRequestId) {
return { ok: true, ignored: true };
}
const clearManualConfirmationState = {
plusManualConfirmationPending: false,
plusManualConfirmationRequestId: '',
plusManualConfirmationStep: 0,
plusManualConfirmationMethod: '',
plusManualConfirmationTitle: '',
plusManualConfirmationMessage: '',
};
await setState(clearManualConfirmationState);
if (typeof broadcastDataUpdate === 'function') {
broadcastDataUpdate(clearManualConfirmationState);
}
if (confirmed) {
const methodLabel = String(currentState?.plusManualConfirmationMethod || '').trim().toLowerCase() === 'gopay'
? 'GoPay'
: '手动';
await addLog(`步骤 ${step}:已确认${methodLabel}订阅完成,准备继续下一步。`, 'ok');
await completeStepFromBackground(step, {
plusManualConfirmationMethod: currentState?.plusManualConfirmationMethod || '',
plusManualConfirmedAt: Date.now(),
});
return { ok: true };
}
const cancelMessage = String(currentState?.plusManualConfirmationMethod || '').trim().toLowerCase() === 'gopay'
? '已取消 GoPay 订阅确认'
: '已取消当前手动确认';
await setStepStatus(step, 'failed');
await addLog(`步骤 ${step}${cancelMessage}`, 'warn');
await appendManualAccountRunRecordIfNeeded(`step${step}_failed`, null, cancelMessage);
notifyStepError(step, cancelMessage);
return { ok: true };
}
case 'GET_STATE': {
return await getState();
}
@@ -649,12 +698,19 @@
const sessionUpdates = buildLuckmailSessionSettingsPayload(message.payload || {});
const modeChanged = Object.prototype.hasOwnProperty.call(updates, 'plusModeEnabled')
&& Boolean(currentState?.plusModeEnabled) !== Boolean(updates.plusModeEnabled);
const plusPaymentChanged = Object.prototype.hasOwnProperty.call(updates, 'plusPaymentMethod')
&& String(currentState?.plusPaymentMethod || 'paypal').trim().toLowerCase()
!== String(updates.plusPaymentMethod || 'paypal').trim().toLowerCase();
const nextPlusModeEnabled = Object.prototype.hasOwnProperty.call(updates, 'plusModeEnabled')
? Boolean(updates.plusModeEnabled)
: Boolean(currentState?.plusModeEnabled);
const stepModeChanged = modeChanged || (nextPlusModeEnabled && plusPaymentChanged);
await setPersistentSettings(updates);
const stateUpdates = {
...updates,
...sessionUpdates,
};
if (modeChanged && typeof getStepIdsForState === 'function') {
if (stepModeChanged && typeof getStepIdsForState === 'function') {
const nextStateForSteps = { ...currentState, ...stateUpdates };
stateUpdates.stepStatuses = Object.fromEntries(
getStepIdsForState(nextStateForSteps).map((stepId) => [stepId, 'pending'])
@@ -705,6 +761,13 @@
: 'Plus 模式已关闭,已恢复普通注册授权步骤。',
'info'
);
} else if (plusPaymentChanged && nextPlusModeEnabled) {
const selectedPlusPaymentMethod = String(
stateUpdates.plusPaymentMethod ?? currentState?.plusPaymentMethod ?? 'paypal'
).trim().toLowerCase() === 'gopay'
? 'GoPay'
: 'PayPal';
await addLog(`Plus 鏀粯鏂瑰紡宸插垏鎹负 ${selectedPlusPaymentMethod}锛屽凡鏇存柊瀵瑰簲鐨?Plus 姝ラ銆?`, 'info');
}
return { ok: true, state: await getState(), proxyRouting };
}
+22 -9
View File
@@ -18,11 +18,21 @@
waitForTabCompleteUntilStopped,
} = deps;
function normalizePlusPaymentMethod(value = '') {
return String(value || '').trim().toLowerCase() === 'gopay' ? 'gopay' : 'paypal';
}
function getCheckoutModeLabel(state = {}) {
return normalizePlusPaymentMethod(state?.plusPaymentMethod) === 'gopay'
? 'GoPay 订阅页'
: 'Plus Checkout';
}
async function openFreshChatGptTabForCheckoutCreate() {
const tab = await chrome.tabs.create({ url: PLUS_CHECKOUT_ENTRY_URL, active: true });
const tabId = Number(tab?.id);
if (!Number.isInteger(tabId)) {
throw new Error('步骤 6:打开 ChatGPT 页面失败,未获取到有效标签页 ID。');
throw new Error('步骤 6:打开 ChatGPT 页面失败,无法创建订阅页。');
}
if (typeof registerTab === 'function') {
await registerTab(PLUS_CHECKOUT_SOURCE, tabId);
@@ -30,8 +40,9 @@
return tabId;
}
async function executePlusCheckoutCreate() {
await addLog('步骤 6:正在新打开 ChatGPT 会话页,准备创建 Plus Checkout...', 'info');
async function executePlusCheckoutCreate(state = {}) {
const checkoutModeLabel = getCheckoutModeLabel(state);
await addLog(`步骤 6:正在打开新的 ChatGPT 会话,准备创建${checkoutModeLabel}...`, 'info');
const tabId = await openFreshChatGptTabForCheckoutCreate();
await waitForTabCompleteUntilStopped(tabId);
@@ -39,30 +50,32 @@
await ensureContentScriptReadyOnTabUntilStopped(PLUS_CHECKOUT_SOURCE, tabId, {
inject: PLUS_CHECKOUT_INJECT_FILES,
injectSource: PLUS_CHECKOUT_SOURCE,
logMessage: '步骤 6ChatGPT 页面仍在加载,等待 Plus Checkout 脚本就绪...',
logMessage: '步骤 6正在等待 ChatGPT 页面完成加载,再继续创建订阅页...',
});
const result = await sendTabMessageUntilStopped(tabId, PLUS_CHECKOUT_SOURCE, {
type: 'CREATE_PLUS_CHECKOUT',
source: 'background',
payload: {},
payload: {
paymentMethod: normalizePlusPaymentMethod(state?.plusPaymentMethod),
},
});
if (result?.error) {
throw new Error(result.error);
}
if (!result?.checkoutUrl) {
throw new Error('步骤 6Plus Checkout 创建后未返回支付链接。');
throw new Error(`步骤 6${checkoutModeLabel}未返回可用的订阅链接。`);
}
await addLog('步骤 6Plus Checkout 已创建,正在打开支付页面...', 'ok');
await addLog(`步骤 6${checkoutModeLabel}已创建,正在打开订阅页面...`, 'ok');
await chrome.tabs.update(tabId, { url: result.checkoutUrl, active: true });
await waitForTabCompleteUntilStopped(tabId);
await sleepWithStop(1000);
await ensureContentScriptReadyOnTabUntilStopped(PLUS_CHECKOUT_SOURCE, tabId, {
inject: PLUS_CHECKOUT_INJECT_FILES,
injectSource: PLUS_CHECKOUT_SOURCE,
logMessage: '步骤 6Checkout 页面仍在加载,等待页面脚本就绪...',
logMessage: '步骤 6正在等待订阅页面完成加载...',
});
await setState({
@@ -72,7 +85,7 @@
plusCheckoutCurrency: result.currency || 'EUR',
});
await addLog('步骤 6Plus Checkout 页面已就绪,准备继续下一步。', 'info');
await addLog(`步骤 6${checkoutModeLabel}已就绪。`, 'info');
await completeStepFromBackground(6, {
plusCheckoutCountry: result.country || 'DE',
+94
View File
@@ -0,0 +1,94 @@
(function attachBackgroundGoPayManualConfirm(root, factory) {
root.MultiPageBackgroundGoPayManualConfirm = factory();
})(typeof self !== 'undefined' ? self : globalThis, function createBackgroundGoPayManualConfirmModule() {
const PLUS_CHECKOUT_SOURCE = 'plus-checkout';
const DEFAULT_CONFIRM_TITLE = 'GoPay 订阅确认';
const DEFAULT_CONFIRM_MESSAGE = 'GoPay 订阅页已打开。请先手动完成订阅,完成后确认继续 OAuth 登录。';
function createGoPayManualConfirmExecutor(deps = {}) {
const {
addLog,
broadcastDataUpdate,
chrome,
getTabId,
isTabAlive,
registerTab,
setState,
} = deps;
function buildRequestId() {
return `gopay-${Date.now()}-${Math.random().toString(36).slice(2, 8)}`;
}
async function resolveCheckoutTabId(state = {}) {
const registeredTabId = typeof getTabId === 'function'
? await getTabId(PLUS_CHECKOUT_SOURCE)
: null;
if (registeredTabId && typeof isTabAlive === 'function' && await isTabAlive(PLUS_CHECKOUT_SOURCE)) {
return Number(registeredTabId) || 0;
}
const storedTabId = Number(state?.plusCheckoutTabId) || 0;
if (storedTabId && chrome?.tabs?.get) {
const tab = await chrome.tabs.get(storedTabId).catch(() => null);
if (tab?.id) {
if (typeof registerTab === 'function') {
await registerTab(PLUS_CHECKOUT_SOURCE, tab.id);
}
return tab.id;
}
}
const checkoutUrl = String(state?.plusCheckoutUrl || '').trim();
if (!checkoutUrl) {
throw new Error('步骤 7:未检测到 GoPay 订阅页,请先执行步骤 6。');
}
if (!chrome?.tabs?.create) {
throw new Error('步骤 7:无法自动重新打开 GoPay 订阅页。');
}
const tab = await chrome.tabs.create({ url: checkoutUrl, active: true });
const tabId = Number(tab?.id) || 0;
if (!tabId) {
throw new Error('步骤 7:重新打开 GoPay 订阅页失败。');
}
if (typeof registerTab === 'function') {
await registerTab(PLUS_CHECKOUT_SOURCE, tabId);
}
return tabId;
}
async function executeGoPayManualConfirm(state = {}) {
const tabId = await resolveCheckoutTabId(state);
if (chrome?.tabs?.update && tabId) {
await chrome.tabs.update(tabId, { active: true }).catch(() => {});
}
const payload = {
plusCheckoutTabId: tabId,
plusManualConfirmationPending: true,
plusManualConfirmationRequestId: buildRequestId(),
plusManualConfirmationStep: 7,
plusManualConfirmationMethod: 'gopay',
plusManualConfirmationTitle: DEFAULT_CONFIRM_TITLE,
plusManualConfirmationMessage: DEFAULT_CONFIRM_MESSAGE,
};
await setState(payload);
if (typeof broadcastDataUpdate === 'function') {
broadcastDataUpdate(payload);
}
await addLog('步骤 7:正在等待手动完成 GoPay 订阅,确认后继续 OAuth 登录。', 'info');
}
return {
executeGoPayManualConfirm,
};
}
return {
createGoPayManualConfirmExecutor,
};
});