diff --git a/background/steps/fill-plus-checkout.js b/background/steps/fill-plus-checkout.js index 89133ec..78168f2 100644 --- a/background/steps/fill-plus-checkout.js +++ b/background/steps/fill-plus-checkout.js @@ -423,8 +423,7 @@ } await addLog(`步骤 7:GPC 模式开始 OTP 验证(reference_id: ${referenceId})...`, 'info'); let otp = ''; - const useLocalSmsHelper = Boolean(state?.gopayHelperLocalSmsHelperEnabled) - && normalizeGpcOtpChannel(state?.gopayHelperOtpChannel) === 'sms'; + const useLocalSmsHelper = Boolean(state?.gopayHelperLocalSmsHelperEnabled); if (useLocalSmsHelper) { try { await addLog('步骤 7:正在从本地 SMS Helper 等待 GPC OTP...', 'info'); diff --git a/sidepanel/sidepanel.js b/sidepanel/sidepanel.js index 62525a5..dbbc2b9 100644 --- a/sidepanel/sidepanel.js +++ b/sidepanel/sidepanel.js @@ -3147,7 +3147,7 @@ function collectSettingsPayload() { ? selectGpcHelperOtpChannel.value : (latestState?.gopayHelperOtpChannel || 'whatsapp') ); - const selectedGpcLocalSmsHelperEnabled = selectedGpcOtpChannel === 'sms' && Boolean( + const selectedGpcLocalSmsHelperEnabled = Boolean( typeof inputGpcHelperLocalSmsEnabled !== 'undefined' && inputGpcHelperLocalSmsEnabled ? inputGpcHelperLocalSmsEnabled.checked : latestState?.gopayHelperLocalSmsHelperEnabled @@ -7014,8 +7014,8 @@ function updatePlusModeUI() { ? normalizePlusPaymentMethod(selectPlusPaymentMethod.value) : method; const gpcRowsVisible = enabled && selectedMethod === gpcValue; - const localSmsControlsVisible = gpcRowsVisible && gpcOtpChannel === 'sms'; - const effectiveLocalSmsEnabled = gpcOtpChannel === 'sms' && localSmsEnabled; + const localSmsControlsVisible = gpcRowsVisible; + const effectiveLocalSmsEnabled = localSmsEnabled; if (typeof selectPlusPaymentMethod !== 'undefined' && selectPlusPaymentMethod) { selectPlusPaymentMethod.value = method; if (selectPlusPaymentMethod.style) { @@ -11229,9 +11229,6 @@ selectPlusPaymentMethod?.addEventListener('change', () => { scheduleSettingsAutoSave(); }); input?.addEventListener('change', () => { - if (input === inputGpcHelperLocalSmsEnabled && input.checked && selectGpcHelperOtpChannel) { - selectGpcHelperOtpChannel.value = 'sms'; - } if (input === selectGpcHelperOtpChannel || input === inputGpcHelperLocalSmsEnabled) { updatePlusModeUI(); } diff --git a/tests/plus-checkout-billing-tab-resolution.test.js b/tests/plus-checkout-billing-tab-resolution.test.js index 43005ea..4fabdec 100644 --- a/tests/plus-checkout-billing-tab-resolution.test.js +++ b/tests/plus-checkout-billing-tab-resolution.test.js @@ -932,6 +932,65 @@ test('GPC billing reads OTP from local SMS helper when enabled', async () => { assert.equal(events.completed[0].step, 7); }); +test('GPC billing can read WhatsApp OTP from local helper when enabled', async () => { + const fetchCalls = []; + const { events, executor } = createExecutorHarness({ + frames: [], + stateByFrame: {}, + fetchImpl: async (url, options = {}) => { + fetchCalls.push({ url, options }); + if (url.startsWith('http://127.0.0.1:18767/otp')) { + return { + ok: true, + status: 200, + json: async () => ({ ok: true, otp: '765432', message_id: 'wa-1' }), + }; + } + if (url.endsWith('/api/gopay/otp')) { + return { + ok: true, + status: 200, + json: async () => ({ reference_id: 'ref_wa', challenge_id: 'challenge_wa' }), + }; + } + if (url.endsWith('/api/gopay/pin')) { + return { + ok: true, + status: 200, + json: async () => ({ stage: 'gopay_complete' }), + }; + } + throw new Error(`unexpected url: ${url}`); + }, + }); + + await executor.executePlusCheckoutBilling({ + plusPaymentMethod: 'gpc-helper', + plusCheckoutSource: 'gpc-helper', + gopayHelperReferenceId: 'ref_wa', + gopayHelperApiUrl: 'https://gopay.hwork.pro/', + gopayHelperPin: '654321', + gopayHelperCardKey: 'card_wa', + gopayHelperOtpChannel: 'whatsapp', + gopayHelperLocalSmsHelperEnabled: true, + gopayHelperLocalSmsHelperUrl: 'http://127.0.0.1:18767', + gopayHelperPhoneNumber: '+8613800138000', + }); + + assert.equal(events.states.some((state) => state.plusManualConfirmationMethod === 'gopay-otp'), false); + assert.equal(events.states.some((state) => state.gopayHelperResolvedOtp === '765432'), true); + const helperUrl = new URL(fetchCalls[0].url); + assert.equal(helperUrl.origin + helperUrl.pathname, 'http://127.0.0.1:18767/otp'); + assert.equal(helperUrl.searchParams.get('reference_id'), 'ref_wa'); + assert.equal(helperUrl.searchParams.get('phone_number'), '+8613800138000'); + assert.deepEqual(JSON.parse(fetchCalls[1].options.body), { + reference_id: 'ref_wa', + otp: '765432', + card_key: 'card_wa', + }); + assert.equal(events.completed[0].step, 7); +}); + test('GPC billing retries OTP with compatibility field after HTTP 400', async () => { const fetchCalls = []; let currentState = { diff --git a/tests/sidepanel-plus-payment-method.test.js b/tests/sidepanel-plus-payment-method.test.js index b05f552..dc0f5fa 100644 --- a/tests/sidepanel-plus-payment-method.test.js +++ b/tests/sidepanel-plus-payment-method.test.js @@ -257,24 +257,20 @@ return { assert.equal(api.rows.rowGpcHelperCardKey.style.display, ''); assert.equal(api.rows.rowGpcHelperPhone.style.display, ''); assert.equal(api.rows.rowGpcHelperOtpChannel.style.display, ''); - assert.equal(api.rows.rowGpcHelperLocalSmsEnabled.style.display, 'none'); + assert.equal(api.rows.rowGpcHelperLocalSmsEnabled.style.display, ''); assert.equal(api.rows.rowGpcHelperLocalSmsUrl.style.display, 'none'); assert.match(api.plusPaymentMethodCaption.textContent, /GPC/); - api.selectGpcHelperOtpChannel.value = 'sms'; - api.updatePlusModeUI(); - assert.equal(api.rows.rowGpcHelperLocalSmsEnabled.style.display, ''); - assert.equal(api.rows.rowGpcHelperLocalSmsUrl.style.display, 'none'); - api.inputGpcHelperLocalSmsEnabled.checked = true; api.updatePlusModeUI(); + assert.equal(api.selectGpcHelperOtpChannel.value, 'whatsapp'); assert.equal(api.rows.rowGpcHelperLocalSmsUrl.style.display, ''); - api.selectGpcHelperOtpChannel.value = 'whatsapp'; + api.selectGpcHelperOtpChannel.value = 'sms'; api.updatePlusModeUI(); - assert.equal(api.inputGpcHelperLocalSmsEnabled.checked, false); - assert.equal(api.rows.rowGpcHelperLocalSmsEnabled.style.display, 'none'); - assert.equal(api.rows.rowGpcHelperLocalSmsUrl.style.display, 'none'); + assert.equal(api.inputGpcHelperLocalSmsEnabled.checked, true); + assert.equal(api.rows.rowGpcHelperLocalSmsEnabled.style.display, ''); + assert.equal(api.rows.rowGpcHelperLocalSmsUrl.style.display, ''); api.selectPlusPaymentMethod.value = 'gopay'; api.updatePlusModeUI();