fix: Force gateway settings reload from database (THE REAL CULPRIT!)

🔴 THE REAL PROBLEM: Gateway Instance Cache

Problem Analysis:
1.  API call works
2.  Database saves correctly
3.  Cache clears properly
4.  Gateway instance still has OLD settings in memory!

Root Cause:
WC()->payment_gateways()->payment_gateways() returns gateway INSTANCES
These instances load settings ONCE on construction
Even after DB save + cache clear, instances still have old $gateway->enabled value!

The Culprit (Line 83):
'enabled' => $gateway->enabled === 'yes'  //  Reading from stale instance!

The Fix:
Before transforming gateway, force reload from DB:
$gateway->init_settings();  //  Reloads from database!

This makes $gateway->enabled read fresh value from wp_options.

Changes:
1. get_gateway(): Added $gateway->init_settings()
2. get_gateways(): Added $gateway->init_settings() in loop
3. PaymentsController: Better boolean handling with filter_var()

Why This Wasn't Obvious:
- Cache clearing worked (wp_cache_flush )
- WC reload worked (WC()->payment_gateways()->init() )
- But gateway INSTANCES weren't reloading their settings!

WooCommerce Gateway Lifecycle:
1. Gateway constructed → Loads settings from DB
2. Settings cached in $gateway->settings property
3. We save new value to DB 
4. We clear cache 
5. We reload WC gateway manager 
6. BUT: Existing instances still have old $gateway->settings 
7. FIX: Call $gateway->init_settings() to reload 

Result:  Toggle now works perfectly!

Files Modified:
- PaymentGatewaysProvider.php: Force init_settings() before transform
- PaymentsController.php: Better boolean validation

This was a subtle WooCommerce internals issue - gateway instances
cache their settings and don't auto-reload even after DB changes!
This commit is contained in:
dwindown
2025-11-05 23:25:59 +07:00
parent ac8870c104
commit cf4fb03ffa
2 changed files with 10 additions and 1 deletions

View File

@@ -208,7 +208,10 @@ class PaymentsController extends WP_REST_Controller {
$gateway_id = $request->get_param('id');
$enabled = $request->get_param('enabled');
if (!is_bool($enabled)) {
// Convert to boolean (handles both bool and string "true"/"false")
$enabled = filter_var($enabled, FILTER_VALIDATE_BOOLEAN, FILTER_NULL_ON_FAILURE);
if ($enabled === null) {
return new WP_Error(
'invalid_enabled_value',
'The "enabled" parameter must be a boolean',

View File

@@ -33,6 +33,9 @@ class PaymentGatewaysProvider {
continue;
}
// Force gateway to reload settings from database
$gateway->init_settings();
$gateways[] = self::transform_gateway($gateway);
}
@@ -62,6 +65,9 @@ class PaymentGatewaysProvider {
return null;
}
// Force gateway to reload settings from database
$gateway->init_settings();
return self::transform_gateway($gateway);
}