Commit 3f95780c7c1 for woocommerce
commit 3f95780c7c1048843a943f8e349a3303a25c4dac
Author: Vlad Olaru <vlad.olaru@automattic.com>
Date: Wed Aug 5 17:46:47 2026 +0300
[Payments NOX] Use Helcim setup state for account connectivity (#67398)
* fix: derive Helcim connectivity from setup state
Helcim's gateway already owns the active credential schema and exposes whether setup is still required. Duplicating its token option names in WooCommerce makes the provider vulnerable to extension-side schema changes.\n\nUse the gateway's setup requirement as the account-connectivity signal while retaining the generic fallback for setup-check failures and legacy gateways.\n\nRefs #67378
* chore: add Helcim connectivity changelog
Record the patch-level change that aligns Helcim account connectivity with the gateway's setup status.\n\nRefs #67378
* fix: avoid Helcim provider setup re-entry
The generic provider setup fallback re-enters account connectivity after the gateway reports that setup is not needed. Since Helcim derives connectivity from that same gateway signal, this caused an unnecessary second setup query and obscured why the call path terminates.\n\nOverride the provider setup method so it trusts the gateway directly, preserves the generic connection fallback on exceptions, and keeps account connectivity as its inverse.\n\nRefs #67378
* revert: remove Helcim provider setup override
The provider-level override removed a repeated gateway setup query but produced the same setup and connectivity signals as the base provider for Helcim's deterministic gateway implementation. Keeping it duplicated the generic fallback policy and required an implementation-specific call-count test.\n\nRestore the connectivity-only change so the base provider continues deriving setup state while Helcim owns only its account-connectivity mapping.\n\nRefs #67378
* test: Strengthen Helcim provider coverage
The legacy compatibility test used FakePaymentGateway, whose own needs_setup() override meant it did not model the inherited WooCommerce default described by the test. The exception fallback test also asserted the fake gateway's default true value, so a hardcoded true could satisfy it without consulting the parent heuristic.
Exercise the default setup contract through a direct WC_Payment_Gateway subclass and give the fallback probe an explicit false result. This keeps the compatibility case while making both tests distinguish the intended paths.
Refs #67378
diff --git a/plugins/woocommerce/changelog/fix-67378-helcim-account-connected b/plugins/woocommerce/changelog/fix-67378-helcim-account-connected
new file mode 100644
index 00000000000..558c4c6255e
--- /dev/null
+++ b/plugins/woocommerce/changelog/fix-67378-helcim-account-connected
@@ -0,0 +1,4 @@
+Significance: patch
+Type: fix
+
+Ensure Helcim account connectivity follows the gateway's setup status.
diff --git a/plugins/woocommerce/src/Internal/Admin/Settings/PaymentsProviders/Helcim.php b/plugins/woocommerce/src/Internal/Admin/Settings/PaymentsProviders/Helcim.php
index eef792757f2..56715a7b679 100644
--- a/plugins/woocommerce/src/Internal/Admin/Settings/PaymentsProviders/Helcim.php
+++ b/plugins/woocommerce/src/Internal/Admin/Settings/PaymentsProviders/Helcim.php
@@ -28,13 +28,7 @@ class Helcim extends PaymentGateway {
*/
public function is_account_connected( WC_Payment_Gateway $payment_gateway ): bool {
try {
- $sandbox_mode = $this->is_helcim_in_sandbox_mode( $payment_gateway );
- // Let null results bubble up to the parent class.
- if ( null !== $sandbox_mode ) {
- $token_key = $sandbox_mode ? 'sandbox_api_token' : 'live_api_token';
-
- return '' !== trim( (string) $payment_gateway->get_option( $token_key, '' ) );
- }
+ return ! wc_string_to_bool( $payment_gateway->needs_setup() );
} catch ( Throwable $e ) {
// Do nothing but log so we can investigate.
SafeGlobalFunctionProxy::wc_get_logger()->debug(
diff --git a/plugins/woocommerce/tests/php/src/Internal/Admin/Settings/PaymentsProviders/HelcimTest.php b/plugins/woocommerce/tests/php/src/Internal/Admin/Settings/PaymentsProviders/HelcimTest.php
index 0993f4e3936..5329dd03480 100644
--- a/plugins/woocommerce/tests/php/src/Internal/Admin/Settings/PaymentsProviders/HelcimTest.php
+++ b/plugins/woocommerce/tests/php/src/Internal/Admin/Settings/PaymentsProviders/HelcimTest.php
@@ -9,6 +9,7 @@ use Automattic\WooCommerce\Testing\Tools\DependencyManagement\MockableLegacyProx
use Automattic\WooCommerce\Testing\Tools\TestingContainer;
use Automattic\WooCommerce\Tests\Internal\Admin\Settings\Mocks\FakePaymentGateway;
use PHPUnit\Framework\MockObject\MockObject;
+use WC_Payment_Gateway;
use WC_Unit_Test_Case;
/**
@@ -49,53 +50,45 @@ class HelcimTest extends WC_Unit_Test_Case {
}
/**
- * @testdox Should report account connected when a sandbox API token is set in sandbox mode.
+ * @testdox Should report account connected when the gateway does not need setup.
*/
- public function test_is_account_connected_true_when_sandbox_token_set(): void {
+ public function test_is_account_connected_true_when_gateway_does_not_need_setup(): void {
$fake_gateway = new FakePaymentGateway(
'helcimjs',
array(
- 'settings' => array(
- 'environment' => 'sandbox',
- 'sandbox_api_token' => 'bogus_sandbox_token',
+ 'settings' => array(
+ 'environment' => 'live',
+ 'renamed_api_token' => 'bogus_live_token',
),
+ 'needs_setup' => false,
),
);
- $this->assertTrue( $this->sut->is_account_connected( $fake_gateway ) );
- }
-
- /**
- * @testdox Should report account not connected when no sandbox API token is set in sandbox mode.
- */
- public function test_is_account_connected_false_when_sandbox_token_missing(): void {
- $fake_gateway = new FakePaymentGateway(
- 'helcimjs',
- array(
- 'settings' => array(
- 'environment' => 'sandbox',
- ),
- ),
+ $this->assertTrue(
+ $this->sut->is_account_connected( $fake_gateway ),
+ 'The gateway setup requirement should be authoritative when its token option keys change.'
);
-
- $this->assertFalse( $this->sut->is_account_connected( $fake_gateway ) );
}
/**
- * @testdox Should report account connected when a live API token is set in live mode.
+ * @testdox Should report account not connected when the gateway needs setup.
*/
- public function test_is_account_connected_true_when_live_token_set(): void {
+ public function test_is_account_connected_false_when_gateway_needs_setup(): void {
$fake_gateway = new FakePaymentGateway(
'helcimjs',
array(
- 'settings' => array(
- 'environment' => 'live',
- 'live_api_token' => 'bogus_live_token',
+ 'settings' => array(
+ 'environment' => 'sandbox',
+ 'sandbox_api_token' => 'stale_or_irrelevant_token',
),
+ 'needs_setup' => true,
),
);
- $this->assertTrue( $this->sut->is_account_connected( $fake_gateway ) );
+ $this->assertFalse(
+ $this->sut->is_account_connected( $fake_gateway ),
+ 'The gateway setup requirement should take precedence over assumed token option keys.'
+ );
}
/**
@@ -131,43 +124,45 @@ class HelcimTest extends WC_Unit_Test_Case {
}
/**
- * @testdox Should fall back to the generic account-connected heuristic when the environment option is entirely absent.
+ * @testdox Should report a legacy gateway connected when it inherits the default setup requirement.
*/
- public function test_is_account_connected_falls_back_when_environment_option_missing(): void {
- // Simulates a pre-v5 Helcim install: same gateway id, but no 'environment'
- // option was ever registered, so it's absent from both settings and form_fields.
- $fake_gateway = new FakePaymentGateway(
- 'helcimjs',
- array(
- 'settings' => array(
- 'legacy_api_token' => 'real_legacy_live_token',
- ),
- 'account_connected' => true,
- ),
- );
+ public function test_is_account_connected_true_for_legacy_gateway_with_default_setup_requirement(): void {
+ $legacy_gateway = new class() extends WC_Payment_Gateway {};
+ $legacy_gateway->id = 'helcimjs';
- $this->assertTrue( $this->sut->is_account_connected( $fake_gateway ) );
+ $this->assertTrue(
+ $this->sut->is_account_connected( $legacy_gateway ),
+ 'Legacy gateways inheriting the default setup requirement should retain the connected state.'
+ );
}
/**
- * @testdox Should fall back to the generic account-connected heuristic for an unrecognized environment value.
+ * @testdox Should fall back to the generic account-connected heuristic when the setup check fails.
*/
- public function test_is_account_connected_falls_back_for_unrecognized_environment(): void {
- // account_connected is true here (not false) so the assertion can't pass
- // by coincidence: an incorrectly-sandbox or incorrectly-live read would
- // look up an absent token option and return false either way, while only
- // a correct null (unrecognized -> defer to parent) read reaches this true.
- $fake_gateway = new FakePaymentGateway(
+ public function test_is_account_connected_falls_back_when_setup_check_fails(): void {
+ $fake_gateway = new class(
'helcimjs',
array(
'settings' => array(
- 'environment' => 'staging',
+ 'environment' => 'live',
),
- 'account_connected' => true,
+ 'account_connected' => false,
),
+ ) extends FakePaymentGateway {
+ /**
+ * Simulate a gateway setup check failure.
+ *
+ * @throws \RuntimeException Always.
+ */
+ public function needs_setup() {
+ throw new \RuntimeException( 'Failed to check the gateway setup.' );
+ }
+ };
+
+ $this->assertFalse(
+ $this->sut->is_account_connected( $fake_gateway ),
+ 'Setup check failures should return the generic account-connected heuristic result.'
);
-
- $this->assertTrue( $this->sut->is_account_connected( $fake_gateway ) );
}
/**