From e38936a4f362c6d4e1ef70ea5a7f97bb2ebd5c1f Mon Sep 17 00:00:00 2001 From: SalmanTwo Date: Fri, 16 Jan 2026 11:40:44 +0000 Subject: [PATCH 1/2] KNA-3176/fix: field reset when checkout is cached too early --- class/WC_Twoinc_Checkout.php | 45 ++++++++++++++++++++++++++++++++++++ 1 file changed, 45 insertions(+) diff --git a/class/WC_Twoinc_Checkout.php b/class/WC_Twoinc_Checkout.php index 1402575..e61351a 100644 --- a/class/WC_Twoinc_Checkout.php +++ b/class/WC_Twoinc_Checkout.php @@ -38,6 +38,51 @@ public function __construct($wc_twoinc) // Order pay page customization add_action('woocommerce_pay_order_before_submit', [$this, 'order_pay_page_customize'], 24); + + // Fix for checkout field caching conflicts with other plugins (e.g., PPOM, Dokan) + // Some plugins trigger WC_Checkout::get_checkout_fields() early during wp_loaded, + // before Two's filters are registered, causing fields to be cached without Two's additions. + add_action('woocommerce_checkout_init', [$this, 'maybe_clear_checkout_field_cache'], 1); + } + + /** + * Clear WooCommerce checkout field cache if Two's fields are missing. + * + * This fixes compatibility issues with plugins that trigger checkout field + * initialization before Two's filters are registered (e.g., PPOM, Dokan). + * + * @param WC_Checkout $checkout The checkout instance. + * @return void + */ + public function maybe_clear_checkout_field_cache($checkout) + { + if (!$checkout instanceof WC_Checkout) { + return; + } + + try { + $reflection = new ReflectionClass($checkout); + + if (!$reflection->hasProperty('fields')) { + return; + } + + $fields_property = $reflection->getProperty('fields'); + $fields_property->setAccessible(true); + $cached_fields = $fields_property->getValue($checkout); + + // Only clear cache if fields are already set but Two's fields are missing + if ( + is_array($cached_fields) && + isset($cached_fields['billing']) && + !isset($cached_fields['billing']['company_id']) + ) { + $fields_property->setValue($checkout, null); + } + } catch (ReflectionException $e) { + // Silently fail - cache clearing is a best-effort optimization + // The checkout will still work, just without Two's custom fields in edge cases + } } /** From 43338880d40c31a8b0f42e1da015e1e06536c8e4 Mon Sep 17 00:00:00 2001 From: SalmanTwo Date: Fri, 16 Jan 2026 12:31:07 +0000 Subject: [PATCH 2/2] KNA-3176/fix: Addressing PR feedback --- class/WC_Twoinc_Checkout.php | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/class/WC_Twoinc_Checkout.php b/class/WC_Twoinc_Checkout.php index e61351a..dbe671c 100644 --- a/class/WC_Twoinc_Checkout.php +++ b/class/WC_Twoinc_Checkout.php @@ -75,12 +75,20 @@ public function maybe_clear_checkout_field_cache($checkout) if ( is_array($cached_fields) && isset($cached_fields['billing']) && + is_array($cached_fields['billing']) && !isset($cached_fields['billing']['company_id']) ) { $fields_property->setValue($checkout, null); } } catch (ReflectionException $e) { - // Silently fail - cache clearing is a best-effort optimization + // Log the exception for debugging - helps identify issues if WooCommerce internals change + if (function_exists('wc_get_logger')) { + wc_get_logger()->warning( + 'Two: Failed to clear checkout field cache due to ReflectionException: ' . $e->getMessage(), + ['source' => 'two-payment-gateway'] + ); + } + // Silently continue - cache clearing is a best-effort optimization // The checkout will still work, just without Two's custom fields in edge cases } }