Fix PayPal hosted checkout flow
This commit is contained in:
@@ -35,12 +35,12 @@
|
||||
const PAYPAL_HOSTED_STEP_CREATE_ACCOUNT = 'paypal-hosted-create-account';
|
||||
const PAYPAL_HOSTED_STEP_REVIEW = 'paypal-hosted-review';
|
||||
const PAYPAL_HOSTED_STEP_META = Object.freeze({
|
||||
[PAYPAL_HOSTED_STEP_OPENAI_CHECKOUT]: { step: 7, label: '无卡直绑 OpenAI Checkout' },
|
||||
[PAYPAL_HOSTED_STEP_EMAIL]: { step: 8, label: '无卡直绑 PayPal 邮箱页' },
|
||||
[PAYPAL_HOSTED_STEP_VERIFICATION]: { step: 9, label: '无卡直绑 PayPal 验证码页' },
|
||||
[PAYPAL_HOSTED_STEP_CARD]: { step: 10, label: '无卡直绑 PayPal 资料页' },
|
||||
[PAYPAL_HOSTED_STEP_CREATE_ACCOUNT]: { step: 11, label: '无卡直绑 PayPal 创建确认页' },
|
||||
[PAYPAL_HOSTED_STEP_REVIEW]: { step: 12, label: '无卡直绑 PayPal 授权复核页' },
|
||||
[PAYPAL_HOSTED_STEP_OPENAI_CHECKOUT]: { step: 6, label: '创建 PayPal 无卡直绑 Checkout' },
|
||||
[PAYPAL_HOSTED_STEP_EMAIL]: { step: 7, label: '无卡直绑 PayPal 邮箱页' },
|
||||
[PAYPAL_HOSTED_STEP_VERIFICATION]: { step: 8, label: '无卡直绑 PayPal 验证码页' },
|
||||
[PAYPAL_HOSTED_STEP_CARD]: { step: 9, label: '无卡直绑 PayPal 资料页' },
|
||||
[PAYPAL_HOSTED_STEP_CREATE_ACCOUNT]: { step: 10, label: '无卡直绑 PayPal 创建确认页' },
|
||||
[PAYPAL_HOSTED_STEP_REVIEW]: { step: 11, label: '无卡直绑 PayPal 授权复核页' },
|
||||
});
|
||||
|
||||
function createPlusCheckoutCreateExecutor(deps = {}) {
|
||||
@@ -686,7 +686,7 @@
|
||||
throw new Error('步骤 6:PayPal 无卡直绑未返回可用的订阅链接。');
|
||||
}
|
||||
|
||||
await addLog('步骤 6:PayPal 无卡直绑链接已创建,正在打开 hosted checkout 页面...', 'ok');
|
||||
await addLog('步骤 6:PayPal 无卡直绑链接已创建,正在打开并提交 OpenAI Checkout 页面...', 'ok');
|
||||
await chrome.tabs.update(tabId, { url: targetCheckoutUrl, active: true });
|
||||
await waitForTabCompleteUntilStopped(tabId);
|
||||
|
||||
@@ -697,26 +697,37 @@
|
||||
500
|
||||
);
|
||||
const landedUrl = String(landedTab?.url || targetCheckoutUrl || '').trim();
|
||||
let completedUrl = landedUrl;
|
||||
|
||||
const isAlreadySuccessful = isHostedCheckoutSuccessUrl(landedUrl);
|
||||
if (isHostedOpenAiCheckoutUrl(completedUrl)) {
|
||||
const { profile, config } = await ensureHostedGuestProfile(state);
|
||||
await addLog(`步骤 6:正在提交 OpenAI Checkout,等待跳转到 PayPal 邮箱页(电话使用本地号码 ${profile.phone})。`, 'info');
|
||||
completedUrl = String(await runHostedOpenAiCheckout(tabId, profile, config) || await getHostedCurrentUrl(tabId) || '').trim();
|
||||
}
|
||||
|
||||
if (isPayPalUrl(completedUrl)) {
|
||||
await waitForTabCompleteUntilStopped(tabId).catch(() => {});
|
||||
}
|
||||
|
||||
const isAlreadySuccessful = isHostedCheckoutSuccessUrl(completedUrl);
|
||||
await setState({
|
||||
plusCheckoutTabId: tabId,
|
||||
plusCheckoutUrl: landedUrl,
|
||||
plusCheckoutUrl: completedUrl,
|
||||
plusCheckoutCountry: result.country || 'US',
|
||||
plusCheckoutCurrency: result.currency || 'USD',
|
||||
plusCheckoutSource: PLUS_PAYMENT_METHOD_PAYPAL_HOSTED,
|
||||
plusReturnUrl: isAlreadySuccessful ? landedUrl : '',
|
||||
plusReturnUrl: isAlreadySuccessful ? completedUrl : '',
|
||||
plusHostedCheckoutCompleted: isAlreadySuccessful,
|
||||
});
|
||||
|
||||
await addLog(`步骤 6:PayPal 无卡直绑页面已就绪(${result.country || 'US'} ${result.currency || 'USD'}),准备进入页面级直绑节点。`, 'info');
|
||||
await addLog(`步骤 6:PayPal 无卡直绑已提交 OpenAI Checkout(${result.country || 'US'} ${result.currency || 'USD'}),准备进入 PayPal 邮箱页。`, 'info');
|
||||
|
||||
await completeNodeFromBackground('plus-checkout-create', {
|
||||
plusCheckoutCountry: result.country || 'US',
|
||||
plusCheckoutCurrency: result.currency || 'USD',
|
||||
plusCheckoutSource: PLUS_PAYMENT_METHOD_PAYPAL_HOSTED,
|
||||
plusCheckoutUrl: landedUrl,
|
||||
plusReturnUrl: isAlreadySuccessful ? landedUrl : '',
|
||||
plusCheckoutUrl: completedUrl,
|
||||
plusReturnUrl: isAlreadySuccessful ? completedUrl : '',
|
||||
plusHostedCheckoutCompleted: isAlreadySuccessful,
|
||||
});
|
||||
}
|
||||
|
||||
@@ -5,8 +5,8 @@
|
||||
const PLUS_CHECKOUT_INJECT_FILES = ['content/utils.js', 'content/operation-delay.js', 'content/plus-checkout.js'];
|
||||
const PLUS_CHECKOUT_URL_PATTERN = /^https:\/\/chatgpt\.com\/checkout(?:\/|$)/i;
|
||||
const PLUS_CHECKOUT_FRAME_READY_DELAY_MS = 500;
|
||||
const PLUS_CHECKOUT_SUBMIT_MAX_ATTEMPTS = 3;
|
||||
const PLUS_CHECKOUT_PAYPAL_REDIRECT_TIMEOUT_MS = 20000;
|
||||
const PLUS_CHECKOUT_SUBMIT_MAX_ATTEMPTS = 5;
|
||||
const PLUS_CHECKOUT_PAYPAL_REDIRECT_TIMEOUT_MS = 10000;
|
||||
const PLUS_PAYMENT_METHOD_PAYPAL = 'paypal';
|
||||
const PLUS_PAYMENT_METHOD_GOPAY = 'gopay';
|
||||
const PLUS_PAYMENT_METHOD_GPC_HELPER = 'gpc-helper';
|
||||
@@ -1883,7 +1883,7 @@
|
||||
await addLog(
|
||||
attempt === 1
|
||||
? '步骤 7:账单地址已填写完成,等待 3 秒让 checkout 完成校验...'
|
||||
: `步骤 7:准备第 ${attempt}/${PLUS_CHECKOUT_SUBMIT_MAX_ATTEMPTS} 次重新提交账单地址...`,
|
||||
: `步骤 7:准备第 ${attempt}/${PLUS_CHECKOUT_SUBMIT_MAX_ATTEMPTS} 次重新检测订阅按钮...`,
|
||||
attempt === 1 ? 'info' : 'warn'
|
||||
);
|
||||
await sleepWithStop(3000);
|
||||
@@ -1907,17 +1907,27 @@
|
||||
continue;
|
||||
}
|
||||
|
||||
await addLog(`步骤 7:账单地址已提交,正在等待跳转到 ${paymentConfig.label}(${attempt}/${PLUS_CHECKOUT_SUBMIT_MAX_ATTEMPTS})...`, 'info');
|
||||
const subscribeClicked = subscribeResult?.clicked !== false;
|
||||
const subscribeButtonText = String(subscribeResult?.subscribeButtonText || '').trim();
|
||||
const subscribeButtonStatus = String(subscribeResult?.subscribeButtonStatus || '').trim();
|
||||
if (subscribeClicked) {
|
||||
await addLog(`步骤 7:已点击订阅按钮,正在等待跳转到 ${paymentConfig.label}(${attempt}/${PLUS_CHECKOUT_SUBMIT_MAX_ATTEMPTS})...`, 'info');
|
||||
} else {
|
||||
const buttonStateLabel = subscribeButtonText || subscribeButtonStatus || 'unknown';
|
||||
await addLog(`步骤 7:订阅按钮当前为「${buttonStateLabel}」,本轮未点击,正在等待页面是否跳转到 ${paymentConfig.label}(${attempt}/${PLUS_CHECKOUT_SUBMIT_MAX_ATTEMPTS})...`, 'warn');
|
||||
}
|
||||
redirectedToPayment = await waitForPaymentRedirectAfterSubmit(tabId, paymentMethod);
|
||||
if (redirectedToPayment) {
|
||||
break;
|
||||
}
|
||||
lastSubmitError = `提交后 ${Math.round(PLUS_CHECKOUT_PAYPAL_REDIRECT_TIMEOUT_MS / 1000)} 秒内未跳转到 ${paymentConfig.label}`;
|
||||
await addLog(`步骤 7:${lastSubmitError},将重试提交。`, 'warn');
|
||||
lastSubmitError = subscribeClicked
|
||||
? `点击订阅后 ${Math.round(PLUS_CHECKOUT_PAYPAL_REDIRECT_TIMEOUT_MS / 1000)} 秒内未跳转到 ${paymentConfig.label}`
|
||||
: `订阅按钮当前为「${subscribeButtonText || subscribeButtonStatus || 'unknown'}」,${Math.round(PLUS_CHECKOUT_PAYPAL_REDIRECT_TIMEOUT_MS / 1000)} 秒内未跳转到 ${paymentConfig.label}`;
|
||||
await addLog(`步骤 7:${lastSubmitError},将重新检测订阅按钮。`, 'warn');
|
||||
}
|
||||
|
||||
if (!redirectedToPayment) {
|
||||
throw new Error(`步骤 7:多次提交账单地址后仍未跳转到 ${paymentConfig.label}。${lastSubmitError}`);
|
||||
throw new Error(`步骤 7:多次检测订阅按钮后仍未跳转到 ${paymentConfig.label}。${lastSubmitError}`);
|
||||
}
|
||||
|
||||
await completeNodeFromBackground('plus-checkout-billing', {
|
||||
|
||||
Reference in New Issue
Block a user