Commit a80eef0baf0 for woocommerce

commit a80eef0baf0483fd305fee2593edc4533bb089d4
Author: Jorge A. Torres <jorge.torres@automattic.com>
Date:   Wed Nov 11 11:30:52 2026 -0500

    Update payment method title as well on `OrderController` gateway update (#70275)

diff --git a/plugins/woocommerce/changelog/beijing-woocommerce-issue-69657-review-v2 b/plugins/woocommerce/changelog/beijing-woocommerce-issue-69657-review-v2
new file mode 100644
index 00000000000..95aea0af897
--- /dev/null
+++ b/plugins/woocommerce/changelog/beijing-woocommerce-issue-69657-review-v2
@@ -0,0 +1,4 @@
+Significance: patch
+Type: fix
+
+Show the correct payment method name on an order after its gateway changes during checkout.
diff --git a/plugins/woocommerce/includes/class-wc-order.php b/plugins/woocommerce/includes/class-wc-order.php
index 268c22fcb5b..48a5b657574 100644
--- a/plugins/woocommerce/includes/class-wc-order.php
+++ b/plugins/woocommerce/includes/class-wc-order.php
@@ -1691,7 +1691,7 @@ class WC_Order extends WC_Abstract_Order {
 	/**
 	 * Set the payment method.
 	 *
-	 * @param string $payment_method Supports WC_Payment_Gateway for bw compatibility with < 3.0.
+	 * @param string|WC_Payment_Gateway $payment_method Gateway id, or a gateway object (also sets the title).
 	 * @throws WC_Data_Exception Throws exception when invalid data is found.
 	 * @return void
 	 */
diff --git a/plugins/woocommerce/src/StoreApi/Utilities/CheckoutTrait.php b/plugins/woocommerce/src/StoreApi/Utilities/CheckoutTrait.php
index d8b1bbd512c..bf8e5aaddef 100644
--- a/plugins/woocommerce/src/StoreApi/Utilities/CheckoutTrait.php
+++ b/plugins/woocommerce/src/StoreApi/Utilities/CheckoutTrait.php
@@ -287,7 +287,7 @@ trait CheckoutTrait {
 		if ( null !== $payment_method ) {
 			WC()->session->set( 'chosen_payment_method', $payment_method->id );
 			$order->set_payment_method( $payment_method->id );
-			$order->set_payment_method_title( $payment_method->title );
+			$order->set_payment_method_title( $payment_method->get_title() );
 		} else {
 			$order_needs_payment = $order->needs_payment();
 			if ( $order_needs_payment && 'POST' === $request->get_method() ) {
diff --git a/plugins/woocommerce/src/StoreApi/Utilities/OrderController.php b/plugins/woocommerce/src/StoreApi/Utilities/OrderController.php
index e48f05cca5a..9fc06bfad89 100644
--- a/plugins/woocommerce/src/StoreApi/Utilities/OrderController.php
+++ b/plugins/woocommerce/src/StoreApi/Utilities/OrderController.php
@@ -98,7 +98,10 @@ class OrderController {
 		$order->set_customer_id( get_current_user_id() );
 		$order->set_customer_ip_address( \WC_Geolocation::get_ip_address() );
 		$order->set_customer_user_agent( wc_get_user_agent() );
-		$order->set_payment_method( PaymentUtils::get_checkout_payment_method() );
+		$payment_method_id   = PaymentUtils::get_checkout_payment_method();
+		$registered_gateways = WC()->payment_gateways()->payment_gateways();
+		$payment_method      = $registered_gateways[ $payment_method_id ] ?? $payment_method_id;
+		$order->set_payment_method( $payment_method );
 		$order->update_meta_data( 'is_vat_exempt', wc_bool_to_string( wc()->cart->get_customer()->get_is_vat_exempt() ) );
 		$order->calculate_totals();
 	}
diff --git a/plugins/woocommerce/tests/php/src/Blocks/StoreApi/Utilities/OrderControllerTests.php b/plugins/woocommerce/tests/php/src/Blocks/StoreApi/Utilities/OrderControllerTests.php
index 484bfb6166d..b4706476434 100644
--- a/plugins/woocommerce/tests/php/src/Blocks/StoreApi/Utilities/OrderControllerTests.php
+++ b/plugins/woocommerce/tests/php/src/Blocks/StoreApi/Utilities/OrderControllerTests.php
@@ -514,6 +514,15 @@ class OrderControllerTests extends \WC_Unit_Test_Case {
 		$this->assertSame( 'cod', $order->get_payment_method() );
 	}

+	/**
+	 * @testdox update_order_from_cart() sets the payment method title alongside the id, matching the gateway's own title.
+	 */
+	public function test_update_order_from_cart_sets_payment_method_title_with_the_session_choice(): void {
+		$order = $this->sync_order_from_cart_with_cod_enabled( 'cod' );
+
+		$this->assertSame( WC()->payment_gateways()->payment_gateways()['cod']->get_title(), $order->get_payment_method_title() );
+	}
+
 	/**
 	 * @testdox update_order_from_cart() writes the filtered default on the order when the shopper has not chosen a method.
 	 */
@@ -523,6 +532,32 @@ class OrderControllerTests extends \WC_Unit_Test_Case {
 		$this->assertSame( '', $order->get_payment_method() );
 	}

+	/**
+	 * @testdox update_order_from_cart() still pairs the title with the id when the chosen gateway is registered but disabled.
+	 */
+	public function test_update_order_from_cart_sets_payment_method_title_for_a_disabled_registered_gateway(): void {
+		$bacs                = WC()->payment_gateways()->payment_gateways()['bacs'];
+		$bacs_enabled_before = $bacs->enabled;
+		$bacs->enabled       = 'no';
+		WC()->session->set( 'chosen_payment_method', 'bacs' );
+
+		try {
+			WC()->cart->empty_cart();
+			WC()->cart->add_to_cart( WC_Helper_Product::create_simple_product()->get_id() );
+			$order = WC_Helper_Order::create_order();
+			$order->set_payment_method_title( 'Stale Title' );
+
+			$this->sut->update_order_from_cart( $order );
+
+			$this->assertSame( 'bacs', $order->get_payment_method() );
+			$this->assertSame( $bacs->get_title(), $order->get_payment_method_title() );
+		} finally {
+			WC()->cart->empty_cart();
+			$bacs->enabled = $bacs_enabled_before;
+			WC()->session->set( 'chosen_payment_method', null );
+		}
+	}
+
 	/**
 	 * Sync an order from a one-item cart with COD enabled, the given session choice and a callback that returns nothing.
 	 *