Repository: Automattic/woocommerce-payments
Pull request #10554: Display failure message on order received page for failed orders
Author: login: mdmoore
Created: 2025-03-12T20:01:53Z | Merged: 2025-03-14T16:41:56Z

Fixes #10508 

#### Changes proposed in this Pull Request

<!--
Title: A descriptive, yet concise, title.
-->

<!--
Description: Write a brief summary about this PR. As you compose your summary, consider each of these questions and address them if appropriate. Why is this change needed? What does this change do? Were there other solutions you considered? Why did you choose to pursue this solution? Describe any trade-offs you might have had to make.
-->

<!--
Questions for PR author:
- How can this code break?
- What are we doing to make sure this code doesn't break?
-->

<!--
Images or gifs: Include before and after screenshots or gifs/videos when it makes sense.
-->

Currently, if the Order Received page is viewed for a failed order, a generic "Thank you. Your order has been received." message is displayed. This PR changes that message to, "Unfortunately, your order has failed. Please try checking out again." with a link to return to checkout.

This issue came out of the need to indicate payment failures for payment methods that redirect from third-party pages, like WeChat Pay in test mode.

#### Testing instructions

<!--
Testing instructions: How should this be tested and how can a reviewer test the end-user functionality? Are there known issues that you plan to address in a future PR? Are there any side effects that readers should be aware of?
-->

<!--
Add as many details as possible to help others reproduce the issue and test the fix.
"Before / After" screenshots can also be very helpful when the change is visual.
-->

* Fail an order order with a card payment. Changing the order status on a previous order is fine.
* Visit the Order Received page - http://localhost:8082/checkout/order-received/{order_id}
* The text should be "Unfortunately, your order has failed. Please try checking out again."
* Follow steps [here](https://github.com/Automattic/woocommerce-payments/pull/10442) to enable WeChat Pay if needed
* Place an order with WeChat Pay
* Fail the order on the third-party page
* When redirected, the text should be "Unfortunately, your order has failed. Please try checking out again."
-------------------

- [x] Run `npm run changelog` to add a changelog file, choose `patch` to leave it empty if the change is not significant. You can add multiple changelog files in one PR by running this command a few times. 
- [x] Covered with tests (or have a good reason not to test in description ☝️)
- [ ] Tested on mobile (or does not apply)

**Post merge**

<!--
Make sure you edit the page for the current release when adding testing instructions.
We often create a blank page ahead of time for the next release.
If this PR need not be QA tested, edit to 'QA Testing Not Applicable'
-->

- [ ] Link to testing instructions from [release testing doc](https://github.com/Automattic/woocommerce-payments/wiki/Release-testing-instructions) following [these instructions](https://github.com/Automattic/woocommerce-payments/wiki/How-to-write-good-manual-testing-scenarios) : _Add link here / 'QA Testing Not Applicable'_
- [ ] Add or update [critical flows](https://github.com/Automattic/woocommerce-payments/wiki/Critical-flows) and [testing instructions for critical flows](https://github.com/Automattic/woocommerce-payments/wiki/Testing-instructions-for-critical-flows), if applicable.
- [ ] Add what's changed (description, screenshot, demo videos etc.) to the release announcement post, if applicable.


Linked issue #10508: Display order failure notice on Order Received page
### Describe the bug
<!-- A clear and concise description of what the bug is. Please be as descriptive as possible. -->
Currently, visiting the Order Received page for a failed order will display generic message that the order was received.

### To Reproduce
<!-- Describe the steps to reproduce the behavior. -->

1. Fail an order
2. Visit an order received page for that order - http://localhost:8082/checkout/order-received/{order_id}
3. Notice the text is "Thank you. Your order has been received."


### Actual behavior
<!-- A clear and concise description of what actually happens. -->
Visiting the Order Received page for a failed order will display generic message that the order was received.

### Expected behavior
<!-- A clear and concise description of what you expected to happen. -->
The Order Received page should note that the order has failed and include a link to try checkout out again.


Linked issue comments: user: login: anu-rock
created_at: 2025-03-10T13:53:32Z
body: **Triaging alert:** This issue concerns checkout. Sending it to @Automattic/heisenberg as per Pc2DNy-3z-p2 by adding the relevant focus label. cc @FangedParakeet 
author_association: CONTRIBUTOR
user: login: mdmoore
created_at: 2025-03-14T16:31:53Z
body: While I initially expected this to be a simple case of checking the order status and then filtering the text via `woocommerce_thankyou_order_received_text`, that didn’t work as smoothly as anticipated. I encountered an issue with retrieving the correct order status on the thank-you page for WeChat Pay. The AJAX order status update occurs on the original checkout page and takes longer to complete than the redirect to the thank-you page. As a result, I spent a significant amount of time testing different approaches to retrieve the order status and ultimately landed on a solution that leverages the intent status.

Additionally, I discovered that block-based themes implement a separate message on the Order Received page when no order key is present in the page request. I explored various options for filtering that text or modifying permissions to prevent the second text string from displaying, but none were successful. In the end, I decided to simply hide the text on the front end. Given the additional scope that wasn’t initially accounted for, I’m bumping this to a 3 to reflect the extra time spent.
author_association: CONTRIBUTOR

Diff:
diff --git a/changelog/10508-order-received-failure-notice b/changelog/10508-order-received-failure-notice
new file mode 100644
index 00000000000..ffd78c8adae
--- /dev/null
+++ b/changelog/10508-order-received-failure-notice
@@ -0,0 +1,4 @@
+Significance: minor
+Type: add
+
+Add order failure message on Order Received page.
diff --git a/includes/class-wc-payments-order-success-page.php b/includes/class-wc-payments-order-success-page.php
index a892771e456..c63beced02d 100644
--- a/includes/class-wc-payments-order-success-page.php
+++ b/includes/class-wc-payments-order-success-page.php
@@ -7,12 +7,22 @@
 
 use WCPay\Constants\Payment_Method;
 use WCPay\Duplicate_Payment_Prevention_Service;
+use WCPay\Core\Server\Request\Get_Intention;
+use WCPay\Constants\Intent_Status;
+use WCPay\Constants\Order_Status;
 
 /**
  * Class handling order success page.
  */
 class WC_Payments_Order_Success_Page {
 
+	/**
+	 * Whether to hide the blocks status description.
+	 *
+	 * @var bool
+	 */
+	private $should_hide_status_description = false;
+
 	/**
 	 * Constructor.
 	 */
@@ -22,7 +32,9 @@ public function __construct() {
 		add_action( 'woocommerce_order_details_before_order_table', [ $this, 'unregister_payment_method_override' ] );
 		add_filter( 'woocommerce_thankyou_order_received_text', [ $this, 'add_notice_previous_paid_order' ], 11 );
 		add_filter( 'woocommerce_thankyou_order_received_text', [ $this, 'add_notice_previous_successful_intent' ], 11 );
+		add_filter( 'woocommerce_thankyou_order_received_text', [ $this, 'replace_order_received_text_for_failed_orders' ], 11 );
 		add_action( 'wp_enqueue_scripts', [ $this, 'enqueue_scripts' ] );
+		add_action( 'wp_footer', [ $this, 'output_footer_scripts' ] );
 	}
 
 	/**
@@ -221,7 +233,6 @@ public function add_notice_previous_successful_intent( $text ) {
 		return $text;
 	}
 
-
 	/**
 	 * Formats the additional text to be displayed on the thank you page, with the side effect
 	 * as a workaround for an issue in Woo core 8.1.x and 8.2.x.
@@ -255,6 +266,81 @@ private function format_addtional_thankyou_order_received_text( string $addition
 		return sprintf( '<div class="woocommerce-info">%s</div>', $additional_text );
 	}
 
+	/**
+	 * Replace the order received text with a failure message when the order status is 'failed'.
+	 *
+	 * @param string $text The original thank you text.
+	 * @return string
+	 */
+	public function replace_order_received_text_for_failed_orders( $text ) {
+		global $wp;
+
+		$order_id = absint( $wp->query_vars['order-received'] );
+		$order    = wc_get_order( $order_id );
+
+		if ( ! $order ||
+			! $order->needs_payment() ||
+			0 !== strpos( $order->get_payment_method(), WC_Payment_Gateway_WCPay::GATEWAY_ID )
+		) {
+			return $text;
+		}
+
+		$intent_id      = $order->get_meta( '_intent_id', true );
+		$payment_method = $order->get_payment_method();
+
+		// Strip the gateway ID prefix from the payment method.
+		$payment_method_type = str_replace( WC_Payment_Gateway_WCPay::GATEWAY_ID . '_', '', $payment_method );
+
+		$should_show_failure = false;
+
+		// Check order status first to avoid unnecessary API calls.
+		if ( $order->has_status( Order_Status::FAILED ) ) {
+			$should_show_failure = true;
+		} elseif ( ! empty( $intent_id ) && ! empty( $payment_method_type ) && in_array( $payment_method_type, Payment_Method::REDIRECT_PAYMENT_METHODS, true ) ) {
+			// For redirect-based payment methods that haven't been marked as failed yet, check the intent status.
+			// Add a small delay to allow the intent to be updated.
+			sleep( 1 );
+
+			$intent        = Get_Intention::create( $intent_id );
+			$intent        = $intent->send();
+			$intent_status = $intent->get_status();
+
+			if ( Intent_Status::REQUIRES_PAYMENT_METHOD === $intent_status && $intent->get_last_payment_error() ) {
+				$should_show_failure = true;
+			}
+		}
+
+		if ( $should_show_failure ) {
+			// Store the failure state to use in wp_footer.
+			$this->should_hide_status_description = true;
+
+			$checkout_url = wc_get_checkout_url();
+			return sprintf(
+				/* translators: %s: checkout URL */
+				__( 'Unfortunately, your order has failed. Please <a href="%s">try checking out again</a>.', 'woocommerce-payments' ),
+				esc_url( $checkout_url )
+			);
+		}
+
+		return $text;
+	}
+
+	/**
+	 * Output any necessary footer scripts
+	 */
+	public function output_footer_scripts() {
+		if ( ! empty( $this->should_hide_status_description ) ) {
+			echo "
+				<script type='text/javascript'>
+					const element = document.querySelector('.wc-block-order-confirmation-status-description');
+					if (element) {
+						element.style.display = 'none';
+					}
+				</script>
+			";
+		}
+	}
+
 	/**
 	 * Enqueue style to the order success page
 	 */
diff --git a/includes/constants/class-payment-method.php b/includes/constants/class-payment-method.php
index 013e3b6c9fa..087026db37b 100644
--- a/includes/constants/class-payment-method.php
+++ b/includes/constants/class-payment-method.php
@@ -49,4 +49,8 @@ class Payment_Method extends Base_Constant {
 		self::AFTERPAY,
 		self::KLARNA,
 	];
+
+	const REDIRECT_PAYMENT_METHODS = [
+		self::WECHAT_PAY,
+	];
 }
diff --git a/tests/unit/test-class-wc-payments-order-success-page.php b/tests/unit/test-class-wc-payments-order-success-page.php
index 4fc35ce02d1..7bdbbd1ab88 100644
--- a/tests/unit/test-class-wc-payments-order-success-page.php
+++ b/tests/unit/test-class-wc-payments-order-success-page.php
@@ -6,6 +6,8 @@
  */
 
 use WCPay\Payment_Methods\UPE_Payment_Method;
+use WCPay\Core\Server\Request\Get_Intention;
+use WCPay\Constants\Payment_Method;
 
 /**
  * WC_Payments_Order_Success_Page unit tests.
@@ -125,4 +127,80 @@ public function test_show_lpm_payment_method_name_icon_not_found() {
 
 		$this->assertFalse( $result );
 	}
+
+	public function test_replace_order_received_text_for_failed_orders_with_failed_status() {
+		$order = WC_Helper_Order::create_order();
+		$order->set_status( 'failed' );
+		$order->set_payment_method( 'woocommerce_payments' );
+		$order->set_total( 50 ); // Ensure order needs payment.
+		$order->save();
+
+		// Set up global wp query vars.
+		global $wp;
+		$wp->query_vars['order-received'] = $order->get_id();
+
+		$original_text = 'Thank you. Your order has been received.';
+		$result        = $this->payments_order_success_page->replace_order_received_text_for_failed_orders( $original_text );
+
+		$this->assertStringContainsString( 'Unfortunately, your order has failed', $result );
+		$this->assertStringContainsString( wc_get_checkout_url(), $result );
+	}
+
+	public function test_replace_order_received_text_for_failed_orders_with_redirect_payment_failed_intent() {
+		$order = WC_Helper_Order::create_order();
+		$order->set_payment_method( 'woocommerce_payments_wechat_pay' );
+		$order->set_total( 50 ); // Ensure order needs payment.
+		$order->add_meta_data( '_intent_id', 'pi_123' );
+		$order->save();
+
+		// Set up global wp query vars.
+		global $wp;
+		$wp->query_vars['order-received'] = $order->get_id();
+
+		// Mock the Get_Intention request.
+		$mock_intent = WC_Helper_Intention::create_intention(
+			[
+				'id'                 => 'pi_123',
+				'status'             => 'requires_payment_method',
+				'last_payment_error' => [ 'message' => 'Payment failed' ],
+			]
+		);
+
+		$this->mock_wcpay_request( Get_Intention::class, 1, 'pi_123' )
+			->expects( $this->once() )
+			->method( 'format_response' )
+			->willReturn( $mock_intent );
+
+		$original_text = 'Thank you. Your order has been received.';
+		$result        = $this->payments_order_success_page->replace_order_received_text_for_failed_orders( $original_text );
+
+		$this->assertStringContainsString( 'Unfortunately, your order has failed', $result );
+		$this->assertStringContainsString( wc_get_checkout_url(), $result );
+	}
+
+	public function test_replace_order_received_text_for_non_failed_order() {
+		$order = WC_Helper_Order::create_order();
+		$order->set_status( 'processing' );
+		$order->save();
+
+		// Set up global wp query vars.
+		global $wp;
+		$wp->query_vars['order-received'] = $order->get_id();
+
+		$original_text = 'Thank you. Your order has been received.';
+		$result        = $this->payments_order_success_page->replace_order_received_text_for_failed_orders( $original_text );
+
+		$this->assertEquals( $original_text, $result );
+	}
+
+	public function test_replace_order_received_text_for_invalid_order() {
+		// Set up global wp query vars with invalid order ID.
+		global $wp;
+		$wp->query_vars['order-received'] = 999999;
+
+		$original_text = 'Thank you. Your order has been received.';
+		$result        = $this->payments_order_success_page->replace_order_received_text_for_failed_orders( $original_text );
+
+		$this->assertEquals( $original_text, $result );
+	}
 }


Reviews:
user: login: mdmoore
state: COMMENTED
author_association: CONTRIBUTOR
submitted_at: 2025-03-12T20:02:55Z
user: login: mdmoore
state: COMMENTED
author_association: CONTRIBUTOR
submitted_at: 2025-03-12T20:11:06Z
user: login: danielmx-dev
state: COMMENTED
author_association: CONTRIBUTOR
submitted_at: 2025-03-13T14:00:39Z
user: login: mdmoore
state: COMMENTED
author_association: CONTRIBUTOR
submitted_at: 2025-03-13T18:27:32Z
user: login: danielmx-dev
state: COMMENTED
author_association: CONTRIBUTOR
submitted_at: 2025-03-13T18:41:45Z
user: login: danielmx-dev
state: COMMENTED
author_association: CONTRIBUTOR
submitted_at: 2025-03-13T18:43:10Z
user: login: mdmoore
state: COMMENTED
author_association: CONTRIBUTOR
submitted_at: 2025-03-13T18:44:10Z
user: login: mdmoore
state: COMMENTED
author_association: CONTRIBUTOR
submitted_at: 2025-03-13T18:45:02Z
user: login: danielmx-dev
state: COMMENTED
author_association: CONTRIBUTOR
submitted_at: 2025-03-13T18:49:38Z
user: login: mdmoore
state: COMMENTED
author_association: CONTRIBUTOR
submitted_at: 2025-03-13T18:56:34Z
user: login: danielmx-dev
state: COMMENTED
author_association: CONTRIBUTOR
submitted_at: 2025-03-13T19:00:14Z
user: login: mdmoore
state: COMMENTED
author_association: CONTRIBUTOR
submitted_at: 2025-03-13T19:06:39Z
user: login: mdmoore
state: COMMENTED
author_association: CONTRIBUTOR
submitted_at: 2025-03-13T19:07:24Z
user: login: danielmx-dev
state: COMMENTED
author_association: CONTRIBUTOR
submitted_at: 2025-03-13T19:08:50Z
user: login: mdmoore
state: COMMENTED
author_association: CONTRIBUTOR
submitted_at: 2025-03-13T20:38:49Z
user: login: danielmx-dev
body: Works well, the notice is now gone:
![image](https://github.com/user-attachments/assets/cbdfc91d-2a1b-49a3-83dc-3791382f57de)

I also verified that the regular order received page is not affected negatively by this change
![image](https://github.com/user-attachments/assets/a3cbbb8e-3687-42dd-aeaa-e060c76bf37c)

state: APPROVED
author_association: CONTRIBUTOR
submitted_at: 2025-03-14T16:02:48Z

Review comments:
diff_hunk: @@ -255,6 +258,59 @@ private function format_addtional_thankyou_order_received_text( string $addition
 		return sprintf( '<div class="woocommerce-info">%s</div>', $additional_text );
 	}
 
+	/**
+	 * Replace the order received text with a failure message when the order status is 'failed'.
+	 *
+	 * @param string $text The original thank you text.
+	 * @return string
+	 */
+	public function replace_order_received_text_for_failed_orders( $text ) {
+		global $wp;
+
+		$order_id = absint( $wp->query_vars['order-received'] );
+		$order    = wc_get_order( $order_id );
+
+		if ( ! $order ) {
+			return $text;
+		}
+
+		$intent_id      = $order->get_meta( '_intent_id', true );
+		$payment_method = $order->get_payment_method();
+
+		// Strip the gateway ID prefix from the payment method.
+		$payment_method_type = str_replace( WC_Payment_Gateway_WCPay::GATEWAY_ID . '_', '', $payment_method );
+
+		$should_show_failure = false;
+
+		// Check order status first to avoid unnecessary API calls.
+		if ( $order->has_status( Order_Status::FAILED ) ) {
+			$should_show_failure = true;
+		} elseif ( ! empty( $intent_id ) && ! empty( $payment_method_type ) && in_array( $payment_method_type, Payment_Method::REDIRECT_PAYMENT_METHODS, true ) ) {
+			// For redirect-based payment methods that haven't been marked as failed yet, check the intent status.
+			// Add a small delay to allow the intent to be updated.
+			sleep( 1 );
path: includes/class-wc-payments-order-success-page.php
user: login: mdmoore
body: Without some delay here, the intent hasn't yet been updated with the new status and error.
created_at: 2025-03-12T20:02:55Z
author_association: CONTRIBUTOR
diff_hunk: @@ -255,6 +258,59 @@ private function format_addtional_thankyou_order_received_text( string $addition
 		return sprintf( '<div class="woocommerce-info">%s</div>', $additional_text );
 	}
 
+	/**
+	 * Replace the order received text with a failure message when the order status is 'failed'.
+	 *
+	 * @param string $text The original thank you text.
+	 * @return string
+	 */
+	public function replace_order_received_text_for_failed_orders( $text ) {
+		global $wp;
+
+		$order_id = absint( $wp->query_vars['order-received'] );
+		$order    = wc_get_order( $order_id );
+
+		if ( ! $order ) {
+			return $text;
+		}
+
+		$intent_id      = $order->get_meta( '_intent_id', true );
+		$payment_method = $order->get_payment_method();
+
+		// Strip the gateway ID prefix from the payment method.
+		$payment_method_type = str_replace( WC_Payment_Gateway_WCPay::GATEWAY_ID . '_', '', $payment_method );
+
+		$should_show_failure = false;
+
+		// Check order status first to avoid unnecessary API calls.
+		if ( $order->has_status( Order_Status::FAILED ) ) {
+			$should_show_failure = true;
+		} elseif ( ! empty( $intent_id ) && ! empty( $payment_method_type ) && in_array( $payment_method_type, Payment_Method::REDIRECT_PAYMENT_METHODS, true ) ) {
+			// For redirect-based payment methods that haven't been marked as failed yet, check the intent status.
+			// Add a small delay to allow the intent to be updated.
+			sleep( 1 );
+
+			$intent        = Get_Intention::create( $intent_id );
+			$intent        = $intent->send();
+			$intent_status = $intent->get_status();
+
path: includes/class-wc-payments-order-success-page.php
user: login: mdmoore
body: The order status for some payment methods, like WeChat Pay, is updated via AJAX and the order hasn't yet updated by the time the `woocommerce_thankyou_order_received_text` runs. Getting the error status from the intent seems to be the best way.
created_at: 2025-03-12T20:11:06Z
author_association: CONTRIBUTOR
diff_hunk: @@ -255,6 +258,59 @@ private function format_addtional_thankyou_order_received_text( string $addition
 		return sprintf( '<div class="woocommerce-info">%s</div>', $additional_text );
 	}
 
+	/**
+	 * Replace the order received text with a failure message when the order status is 'failed'.
+	 *
+	 * @param string $text The original thank you text.
+	 * @return string
+	 */
+	public function replace_order_received_text_for_failed_orders( $text ) {
+		global $wp;
+
+		$order_id = absint( $wp->query_vars['order-received'] );
+		$order    = wc_get_order( $order_id );
+
+		if ( ! $order ) {
+			return $text;
+		}
+
+		$intent_id      = $order->get_meta( '_intent_id', true );
+		$payment_method = $order->get_payment_method();
+
+		// Strip the gateway ID prefix from the payment method.
+		$payment_method_type = str_replace( WC_Payment_Gateway_WCPay::GATEWAY_ID . '_', '', $payment_method );
+
+		$should_show_failure = false;
+
+		// Check order status first to avoid unnecessary API calls.
+		if ( $order->has_status( Order_Status::FAILED ) ) {
+			$should_show_failure = true;
+		} elseif ( ! empty( $intent_id ) && ! empty( $payment_method_type ) && in_array( $payment_method_type, Payment_Method::REDIRECT_PAYMENT_METHODS, true ) ) {
+			// For redirect-based payment methods that haven't been marked as failed yet, check the intent status.
+			// Add a small delay to allow the intent to be updated.
+			sleep( 1 );
+
+			$intent        = Get_Intention::create( $intent_id );
+			$intent        = $intent->send();
+			$intent_status = $intent->get_status();
+
path: includes/class-wc-payments-order-success-page.php
user: login: danielmx-dev
body: Can we avoid the intent request and poll for the order status? Something like this (pseudocode):
```
while (retries left) {
  check order status (make sure the value is refetch from the DB, not the cache)
  if (failed) show_error = true; break;
  if (no longer needs payment) break;
 sleep
 retries++
}
```

created_at: 2025-03-13T13:48:15Z
author_association: CONTRIBUTOR
diff_hunk: @@ -255,6 +258,59 @@ private function format_addtional_thankyou_order_received_text( string $addition
 		return sprintf( '<div class="woocommerce-info">%s</div>', $additional_text );
 	}
 
+	/**
+	 * Replace the order received text with a failure message when the order status is 'failed'.
+	 *
+	 * @param string $text The original thank you text.
+	 * @return string
+	 */
+	public function replace_order_received_text_for_failed_orders( $text ) {
+		global $wp;
+
+		$order_id = absint( $wp->query_vars['order-received'] );
+		$order    = wc_get_order( $order_id );
+
+		if ( ! $order ) {
+			return $text;
+		}
+
+		$intent_id      = $order->get_meta( '_intent_id', true );
+		$payment_method = $order->get_payment_method();
+
+		// Strip the gateway ID prefix from the payment method.
+		$payment_method_type = str_replace( WC_Payment_Gateway_WCPay::GATEWAY_ID . '_', '', $payment_method );
+
+		$should_show_failure = false;
+
+		// Check order status first to avoid unnecessary API calls.
+		if ( $order->has_status( Order_Status::FAILED ) ) {
+			$should_show_failure = true;
+		} elseif ( ! empty( $intent_id ) && ! empty( $payment_method_type ) && in_array( $payment_method_type, Payment_Method::REDIRECT_PAYMENT_METHODS, true ) ) {
path: includes/class-wc-payments-order-success-page.php
user: login: danielmx-dev
body: Should we also check if `$order->needs_payment()` before doing any of this?
created_at: 2025-03-13T13:48:44Z
author_association: CONTRIBUTOR
diff_hunk: @@ -255,6 +258,59 @@ private function format_addtional_thankyou_order_received_text( string $addition
 		return sprintf( '<div class="woocommerce-info">%s</div>', $additional_text );
 	}
 
+	/**
+	 * Replace the order received text with a failure message when the order status is 'failed'.
+	 *
+	 * @param string $text The original thank you text.
+	 * @return string
+	 */
+	public function replace_order_received_text_for_failed_orders( $text ) {
+		global $wp;
+
+		$order_id = absint( $wp->query_vars['order-received'] );
+		$order    = wc_get_order( $order_id );
+
+		if ( ! $order ) {
+			return $text;
+		}
+
+		$intent_id      = $order->get_meta( '_intent_id', true );
+		$payment_method = $order->get_payment_method();
+
+		// Strip the gateway ID prefix from the payment method.
+		$payment_method_type = str_replace( WC_Payment_Gateway_WCPay::GATEWAY_ID . '_', '', $payment_method );
path: includes/class-wc-payments-order-success-page.php
user: login: danielmx-dev
body: Before removing the GATEWAY_ID can we first validate that the payment method used indeed has that prefix so we can avoid acting on orders using other gateways ?
created_at: 2025-03-13T13:50:15Z
author_association: CONTRIBUTOR
diff_hunk: @@ -255,6 +258,59 @@ private function format_addtional_thankyou_order_received_text( string $addition
 		return sprintf( '<div class="woocommerce-info">%s</div>', $additional_text );
 	}
 
+	/**
+	 * Replace the order received text with a failure message when the order status is 'failed'.
+	 *
+	 * @param string $text The original thank you text.
+	 * @return string
+	 */
+	public function replace_order_received_text_for_failed_orders( $text ) {
+		global $wp;
+
+		$order_id = absint( $wp->query_vars['order-received'] );
+		$order    = wc_get_order( $order_id );
+
+		if ( ! $order ) {
+			return $text;
+		}
+
+		$intent_id      = $order->get_meta( '_intent_id', true );
+		$payment_method = $order->get_payment_method();
+
+		// Strip the gateway ID prefix from the payment method.
+		$payment_method_type = str_replace( WC_Payment_Gateway_WCPay::GATEWAY_ID . '_', '', $payment_method );
+
+		$should_show_failure = false;
+
+		// Check order status first to avoid unnecessary API calls.
+		if ( $order->has_status( Order_Status::FAILED ) ) {
+			$should_show_failure = true;
+		} elseif ( ! empty( $intent_id ) && ! empty( $payment_method_type ) && in_array( $payment_method_type, Payment_Method::REDIRECT_PAYMENT_METHODS, true ) ) {
+			// For redirect-based payment methods that haven't been marked as failed yet, check the intent status.
+			// Add a small delay to allow the intent to be updated.
+			sleep( 1 );
+
+			$intent        = Get_Intention::create( $intent_id );
+			$intent        = $intent->send();
+			$intent_status = $intent->get_status();
+
path: includes/class-wc-payments-order-success-page.php
user: login: mdmoore
body: This works also, but I'm not sure it's faster. I've tried it here: [c73fafa](https://github.com/Automattic/woocommerce-payments/pull/10554/commits/c73fafa66fbe2f49283f420d1810cf52cae3fb83). The number of retries seems arbitrary but 6 seemed to be the sweet spot in my local testing. Let me know what you think. 
created_at: 2025-03-13T18:27:32Z
author_association: CONTRIBUTOR
diff_hunk: @@ -255,6 +258,59 @@ private function format_addtional_thankyou_order_received_text( string $addition
 		return sprintf( '<div class="woocommerce-info">%s</div>', $additional_text );
 	}
 
+	/**
+	 * Replace the order received text with a failure message when the order status is 'failed'.
+	 *
+	 * @param string $text The original thank you text.
+	 * @return string
+	 */
+	public function replace_order_received_text_for_failed_orders( $text ) {
+		global $wp;
+
+		$order_id = absint( $wp->query_vars['order-received'] );
+		$order    = wc_get_order( $order_id );
+
+		if ( ! $order ) {
+			return $text;
+		}
+
+		$intent_id      = $order->get_meta( '_intent_id', true );
+		$payment_method = $order->get_payment_method();
+
+		// Strip the gateway ID prefix from the payment method.
+		$payment_method_type = str_replace( WC_Payment_Gateway_WCPay::GATEWAY_ID . '_', '', $payment_method );
+
+		$should_show_failure = false;
+
+		// Check order status first to avoid unnecessary API calls.
+		if ( $order->has_status( Order_Status::FAILED ) ) {
+			$should_show_failure = true;
+		} elseif ( ! empty( $intent_id ) && ! empty( $payment_method_type ) && in_array( $payment_method_type, Payment_Method::REDIRECT_PAYMENT_METHODS, true ) ) {
+			// For redirect-based payment methods that haven't been marked as failed yet, check the intent status.
+			// Add a small delay to allow the intent to be updated.
+			sleep( 1 );
+
+			$intent        = Get_Intention::create( $intent_id );
+			$intent        = $intent->send();
+			$intent_status = $intent->get_status();
+
path: includes/class-wc-payments-order-success-page.php
user: login: danielmx-dev
body: Yes, it seems that the results are not very consistent, I'm also surprised it takes that long to update the order, in my case the 6 retries were not enough. 

I think we have two options here:
1. Poll less times, but if the order still needs payment maybe provide a custom message that says that the process hasn't completed and ask the user to refresh the page (or go a step further and move the polling to the frontend, although that would definitely increase the scope significantly).
2. Restore the get intent approach (but maybe keep the polling mechanism with less retries?)

Although I like not having to make requests to the server, I think (2)  may give us more efficient results? 
created_at: 2025-03-13T18:41:45Z
author_association: CONTRIBUTOR
diff_hunk: @@ -255,6 +258,70 @@ private function format_addtional_thankyou_order_received_text( string $addition
 		return sprintf( '<div class="woocommerce-info">%s</div>', $additional_text );
 	}
 
+	/**
+	 * Replace the order received text with a failure message when the order status is 'failed'.
+	 *
+	 * @param string $text The original thank you text.
+	 * @return string
+	 */
+	public function replace_order_received_text_for_failed_orders( $text ) {
+		global $wp;
+
+		$order_id = absint( $wp->query_vars['order-received'] );
+		$order    = wc_get_order( $order_id );
+
+		if ( ! $order ||
+			! $order->needs_payment() ||
+			0 !== strpos( $order->get_payment_method(), WC_Payment_Gateway_WCPay::GATEWAY_ID )
path: includes/class-wc-payments-order-success-page.php
user: login: danielmx-dev
body: I think the `REDIRECT_PAYMENT_METHODS` check should be restored, just to make sure this doesn't causes any conflicts with vouchers (e.g. multibanco).
created_at: 2025-03-13T18:43:10Z
author_association: CONTRIBUTOR
diff_hunk: @@ -255,6 +258,59 @@ private function format_addtional_thankyou_order_received_text( string $addition
 		return sprintf( '<div class="woocommerce-info">%s</div>', $additional_text );
 	}
 
+	/**
+	 * Replace the order received text with a failure message when the order status is 'failed'.
+	 *
+	 * @param string $text The original thank you text.
+	 * @return string
+	 */
+	public function replace_order_received_text_for_failed_orders( $text ) {
+		global $wp;
+
+		$order_id = absint( $wp->query_vars['order-received'] );
+		$order    = wc_get_order( $order_id );
+
+		if ( ! $order ) {
+			return $text;
+		}
+
+		$intent_id      = $order->get_meta( '_intent_id', true );
+		$payment_method = $order->get_payment_method();
+
+		// Strip the gateway ID prefix from the payment method.
+		$payment_method_type = str_replace( WC_Payment_Gateway_WCPay::GATEWAY_ID . '_', '', $payment_method );
+
+		$should_show_failure = false;
+
+		// Check order status first to avoid unnecessary API calls.
+		if ( $order->has_status( Order_Status::FAILED ) ) {
+			$should_show_failure = true;
+		} elseif ( ! empty( $intent_id ) && ! empty( $payment_method_type ) && in_array( $payment_method_type, Payment_Method::REDIRECT_PAYMENT_METHODS, true ) ) {
path: includes/class-wc-payments-order-success-page.php
user: login: mdmoore
body: Yes, this is a good idea to avoid the polling when it's not needed. Added in [c73fafa](https://github.com/Automattic/woocommerce-payments/pull/10554/commits/c73fafa66fbe2f49283f420d1810cf52cae3fb83).
created_at: 2025-03-13T18:44:10Z
author_association: CONTRIBUTOR
diff_hunk: @@ -255,6 +258,59 @@ private function format_addtional_thankyou_order_received_text( string $addition
 		return sprintf( '<div class="woocommerce-info">%s</div>', $additional_text );
 	}
 
+	/**
+	 * Replace the order received text with a failure message when the order status is 'failed'.
+	 *
+	 * @param string $text The original thank you text.
+	 * @return string
+	 */
+	public function replace_order_received_text_for_failed_orders( $text ) {
+		global $wp;
+
+		$order_id = absint( $wp->query_vars['order-received'] );
+		$order    = wc_get_order( $order_id );
+
+		if ( ! $order ) {
+			return $text;
+		}
+
+		$intent_id      = $order->get_meta( '_intent_id', true );
+		$payment_method = $order->get_payment_method();
+
+		// Strip the gateway ID prefix from the payment method.
+		$payment_method_type = str_replace( WC_Payment_Gateway_WCPay::GATEWAY_ID . '_', '', $payment_method );
path: includes/class-wc-payments-order-success-page.php
user: login: mdmoore
body: Also a good idea. Added in [7b0b5ff](https://github.com/Automattic/woocommerce-payments/pull/10554/commits/7b0b5ff032a255096bbd36fa1459ee19bb05de2c).
created_at: 2025-03-13T18:45:02Z
author_association: CONTRIBUTOR
diff_hunk: @@ -255,6 +258,70 @@ private function format_addtional_thankyou_order_received_text( string $addition
 		return sprintf( '<div class="woocommerce-info">%s</div>', $additional_text );
 	}
 
+	/**
+	 * Replace the order received text with a failure message when the order status is 'failed'.
+	 *
+	 * @param string $text The original thank you text.
+	 * @return string
+	 */
+	public function replace_order_received_text_for_failed_orders( $text ) {
+		global $wp;
+
+		$order_id = absint( $wp->query_vars['order-received'] );
+		$order    = wc_get_order( $order_id );
+
+		if ( ! $order ||
+			! $order->needs_payment() ||
+			0 !== strpos( $order->get_payment_method(), WC_Payment_Gateway_WCPay::GATEWAY_ID )
path: includes/class-wc-payments-order-success-page.php
user: login: danielmx-dev
body: Nevermind, I don't think this comment is accurate, since multibanco should set the order to `on-hold`, and only `failed` and `pending` orders will return true when `needs_payment` is called. https://github.com/woocommerce/woocommerce/blob/trunk/plugins/woocommerce/includes/class-wc-order.php#L1788
created_at: 2025-03-13T18:49:38Z
author_association: CONTRIBUTOR
diff_hunk: @@ -255,6 +258,59 @@ private function format_addtional_thankyou_order_received_text( string $addition
 		return sprintf( '<div class="woocommerce-info">%s</div>', $additional_text );
 	}
 
+	/**
+	 * Replace the order received text with a failure message when the order status is 'failed'.
+	 *
+	 * @param string $text The original thank you text.
+	 * @return string
+	 */
+	public function replace_order_received_text_for_failed_orders( $text ) {
+		global $wp;
+
+		$order_id = absint( $wp->query_vars['order-received'] );
+		$order    = wc_get_order( $order_id );
+
+		if ( ! $order ) {
+			return $text;
+		}
+
+		$intent_id      = $order->get_meta( '_intent_id', true );
+		$payment_method = $order->get_payment_method();
+
+		// Strip the gateway ID prefix from the payment method.
+		$payment_method_type = str_replace( WC_Payment_Gateway_WCPay::GATEWAY_ID . '_', '', $payment_method );
+
+		$should_show_failure = false;
+
+		// Check order status first to avoid unnecessary API calls.
+		if ( $order->has_status( Order_Status::FAILED ) ) {
+			$should_show_failure = true;
+		} elseif ( ! empty( $intent_id ) && ! empty( $payment_method_type ) && in_array( $payment_method_type, Payment_Method::REDIRECT_PAYMENT_METHODS, true ) ) {
+			// For redirect-based payment methods that haven't been marked as failed yet, check the intent status.
+			// Add a small delay to allow the intent to be updated.
+			sleep( 1 );
+
+			$intent        = Get_Intention::create( $intent_id );
+			$intent        = $intent->send();
+			$intent_status = $intent->get_status();
+
path: includes/class-wc-payments-order-success-page.php
user: login: mdmoore
body: If I understand, option 2 proposes to keep the current polling mechanism with, say 3 retries, then move to the get intent approach if polling fails to capture the status update? If so, that sounds fine to me.
created_at: 2025-03-13T18:56:34Z
author_association: CONTRIBUTOR
diff_hunk: @@ -255,6 +258,59 @@ private function format_addtional_thankyou_order_received_text( string $addition
 		return sprintf( '<div class="woocommerce-info">%s</div>', $additional_text );
 	}
 
+	/**
+	 * Replace the order received text with a failure message when the order status is 'failed'.
+	 *
+	 * @param string $text The original thank you text.
+	 * @return string
+	 */
+	public function replace_order_received_text_for_failed_orders( $text ) {
+		global $wp;
+
+		$order_id = absint( $wp->query_vars['order-received'] );
+		$order    = wc_get_order( $order_id );
+
+		if ( ! $order ) {
+			return $text;
+		}
+
+		$intent_id      = $order->get_meta( '_intent_id', true );
+		$payment_method = $order->get_payment_method();
+
+		// Strip the gateway ID prefix from the payment method.
+		$payment_method_type = str_replace( WC_Payment_Gateway_WCPay::GATEWAY_ID . '_', '', $payment_method );
+
+		$should_show_failure = false;
+
+		// Check order status first to avoid unnecessary API calls.
+		if ( $order->has_status( Order_Status::FAILED ) ) {
+			$should_show_failure = true;
+		} elseif ( ! empty( $intent_id ) && ! empty( $payment_method_type ) && in_array( $payment_method_type, Payment_Method::REDIRECT_PAYMENT_METHODS, true ) ) {
+			// For redirect-based payment methods that haven't been marked as failed yet, check the intent status.
+			// Add a small delay to allow the intent to be updated.
+			sleep( 1 );
+
+			$intent        = Get_Intention::create( $intent_id );
+			$intent        = $intent->send();
+			$intent_status = $intent->get_status();
+
path: includes/class-wc-payments-order-success-page.php
user: login: danielmx-dev
body: For option two I actually meant to remove the order status polling and only poll the intents with a few retries. As the order status has proven to be way slower (I think the slowness is because the order is updated by an AJAX call performed by the original checkout page, so that's an additional roundtrip besides all the additional processing done by the endpoint)
created_at: 2025-03-13T19:00:14Z
author_association: CONTRIBUTOR
diff_hunk: @@ -255,6 +258,59 @@ private function format_addtional_thankyou_order_received_text( string $addition
 		return sprintf( '<div class="woocommerce-info">%s</div>', $additional_text );
 	}
 
+	/**
+	 * Replace the order received text with a failure message when the order status is 'failed'.
+	 *
+	 * @param string $text The original thank you text.
+	 * @return string
+	 */
+	public function replace_order_received_text_for_failed_orders( $text ) {
+		global $wp;
+
+		$order_id = absint( $wp->query_vars['order-received'] );
+		$order    = wc_get_order( $order_id );
+
+		if ( ! $order ) {
+			return $text;
+		}
+
+		$intent_id      = $order->get_meta( '_intent_id', true );
+		$payment_method = $order->get_payment_method();
+
+		// Strip the gateway ID prefix from the payment method.
+		$payment_method_type = str_replace( WC_Payment_Gateway_WCPay::GATEWAY_ID . '_', '', $payment_method );
+
+		$should_show_failure = false;
+
+		// Check order status first to avoid unnecessary API calls.
+		if ( $order->has_status( Order_Status::FAILED ) ) {
+			$should_show_failure = true;
+		} elseif ( ! empty( $intent_id ) && ! empty( $payment_method_type ) && in_array( $payment_method_type, Payment_Method::REDIRECT_PAYMENT_METHODS, true ) ) {
+			// For redirect-based payment methods that haven't been marked as failed yet, check the intent status.
+			// Add a small delay to allow the intent to be updated.
+			sleep( 1 );
+
+			$intent        = Get_Intention::create( $intent_id );
+			$intent        = $intent->send();
+			$intent_status = $intent->get_status();
+
path: includes/class-wc-payments-order-success-page.php
user: login: mdmoore
body: Got it! We can go with that. Though I was seeing consistent results using a short delay before checking the intent. Were you getting different results and think polling is necessary?
created_at: 2025-03-13T19:06:38Z
author_association: CONTRIBUTOR
diff_hunk: @@ -255,6 +258,70 @@ private function format_addtional_thankyou_order_received_text( string $addition
 		return sprintf( '<div class="woocommerce-info">%s</div>', $additional_text );
 	}
 
+	/**
+	 * Replace the order received text with a failure message when the order status is 'failed'.
+	 *
+	 * @param string $text The original thank you text.
+	 * @return string
+	 */
+	public function replace_order_received_text_for_failed_orders( $text ) {
+		global $wp;
+
+		$order_id = absint( $wp->query_vars['order-received'] );
+		$order    = wc_get_order( $order_id );
+
+		if ( ! $order ||
+			! $order->needs_payment() ||
+			0 !== strpos( $order->get_payment_method(), WC_Payment_Gateway_WCPay::GATEWAY_ID )
path: includes/class-wc-payments-order-success-page.php
user: login: mdmoore
body: Ah ok. Thanks for checking and clarifying!
created_at: 2025-03-13T19:07:24Z
author_association: CONTRIBUTOR
diff_hunk: @@ -255,6 +258,59 @@ private function format_addtional_thankyou_order_received_text( string $addition
 		return sprintf( '<div class="woocommerce-info">%s</div>', $additional_text );
 	}
 
+	/**
+	 * Replace the order received text with a failure message when the order status is 'failed'.
+	 *
+	 * @param string $text The original thank you text.
+	 * @return string
+	 */
+	public function replace_order_received_text_for_failed_orders( $text ) {
+		global $wp;
+
+		$order_id = absint( $wp->query_vars['order-received'] );
+		$order    = wc_get_order( $order_id );
+
+		if ( ! $order ) {
+			return $text;
+		}
+
+		$intent_id      = $order->get_meta( '_intent_id', true );
+		$payment_method = $order->get_payment_method();
+
+		// Strip the gateway ID prefix from the payment method.
+		$payment_method_type = str_replace( WC_Payment_Gateway_WCPay::GATEWAY_ID . '_', '', $payment_method );
+
+		$should_show_failure = false;
+
+		// Check order status first to avoid unnecessary API calls.
+		if ( $order->has_status( Order_Status::FAILED ) ) {
+			$should_show_failure = true;
+		} elseif ( ! empty( $intent_id ) && ! empty( $payment_method_type ) && in_array( $payment_method_type, Payment_Method::REDIRECT_PAYMENT_METHODS, true ) ) {
+			// For redirect-based payment methods that haven't been marked as failed yet, check the intent status.
+			// Add a small delay to allow the intent to be updated.
+			sleep( 1 );
+
+			$intent        = Get_Intention::create( $intent_id );
+			$intent        = $intent->send();
+			$intent_status = $intent->get_status();
+
path: includes/class-wc-payments-order-success-page.php
user: login: danielmx-dev
body: I thought of it more like a failsafe measure but we can remove it to keep things simple and just add the short delay at the beginning. In the future it may make sense to revisit option (1), so I think it's fine if for now we keep things straightforward, IMO.
created_at: 2025-03-13T19:08:50Z
author_association: CONTRIBUTOR
diff_hunk: @@ -255,6 +258,59 @@ private function format_addtional_thankyou_order_received_text( string $addition
 		return sprintf( '<div class="woocommerce-info">%s</div>', $additional_text );
 	}
 
+	/**
+	 * Replace the order received text with a failure message when the order status is 'failed'.
+	 *
+	 * @param string $text The original thank you text.
+	 * @return string
+	 */
+	public function replace_order_received_text_for_failed_orders( $text ) {
+		global $wp;
+
+		$order_id = absint( $wp->query_vars['order-received'] );
+		$order    = wc_get_order( $order_id );
+
+		if ( ! $order ) {
+			return $text;
+		}
+
+		$intent_id      = $order->get_meta( '_intent_id', true );
+		$payment_method = $order->get_payment_method();
+
+		// Strip the gateway ID prefix from the payment method.
+		$payment_method_type = str_replace( WC_Payment_Gateway_WCPay::GATEWAY_ID . '_', '', $payment_method );
+
+		$should_show_failure = false;
+
+		// Check order status first to avoid unnecessary API calls.
+		if ( $order->has_status( Order_Status::FAILED ) ) {
+			$should_show_failure = true;
+		} elseif ( ! empty( $intent_id ) && ! empty( $payment_method_type ) && in_array( $payment_method_type, Payment_Method::REDIRECT_PAYMENT_METHODS, true ) ) {
+			// For redirect-based payment methods that haven't been marked as failed yet, check the intent status.
+			// Add a small delay to allow the intent to be updated.
+			sleep( 1 );
+
+			$intent        = Get_Intention::create( $intent_id );
+			$intent        = $intent->send();
+			$intent_status = $intent->get_status();
+
path: includes/class-wc-payments-order-success-page.php
user: login: mdmoore
body: Sounds good. For now, this should only affect a single payment method and only in test mode. But option 1 sounds like a good path to take should we ever need to revisit it.
created_at: 2025-03-13T20:38:49Z
author_association: CONTRIBUTOR

PR comments:
user: login: botwoo
created_at: 2025-03-12T20:05:46Z
body: ### Test the build 

#### Option 1. Jetpack Beta

- Install and activate [Jetpack Beta](https://jetpack.com/download-jetpack-beta/).
- Use this build by searching for PR number `10554` or branch name `10508-order-received-failure-notice` in your-test.site/wp-admin/admin.php?page=jetpack-beta&plugin=woocommerce-payments          

#### Option 2. Jurassic Ninja - available for logged-in A12s

:rocket: [Launch a JN site with this branch](https://jurassic.ninja/create/?jetpack-beta&shortlived&nojetpack&woocommerce&woocommerce-payments-dev-tools&branches.woocommerce-payments=10508-order-received-failure-notice) :rocket:

:information_source: Install this [Tampermonkey script](https://github.com/Automattic/woocommerce-payments/tree/develop/bin/wcpay-live-branches) to get more options.

---

Build info: 

- Latest commit: 22fc769883e0f0586cd8cb40b0ac6757f23c32a6
- Build time: 2025-03-14 15:58:33 UTC

_Note: the build is updated when a new commit is pushed to this PR._
author_association: COLLABORATOR
user: login: github-actions[bot]
created_at: 2025-03-12T20:08:21Z
body: **Size Change:** 0 B 

**Total Size:** 1.3 MB



<details><summary>ℹ️ <strong>View Unchanged</strong></summary>

| Filename | Size |
| :--- | :---: |
| `release/woocommerce-payments/assets/css/admin.css` | 1.4 kB |
| `release/woocommerce-payments/assets/css/admin.rtl.css` | 1.4 kB |
| `release/woocommerce-payments/assets/css/success.css` | 189 B |
| `release/woocommerce-payments/assets/css/success.rtl.css` | 190 B |
| `release/woocommerce-payments/dist/blocks-checkout-rtl.css` | 2.74 kB |
| `release/woocommerce-payments/dist/blocks-checkout.css` | 2.74 kB |
| `release/woocommerce-payments/dist/blocks-checkout.js` | 56.2 kB |
| `release/woocommerce-payments/dist/cart-block.js` | 17.3 kB |
| `release/woocommerce-payments/dist/cart.js` | 5.73 kB |
| `release/woocommerce-payments/dist/checkout-rtl.css` | 1.28 kB |
| `release/woocommerce-payments/dist/checkout.css` | 1.28 kB |
| `release/woocommerce-payments/dist/checkout.js` | 34.7 kB |
| `release/woocommerce-payments/dist/express-checkout-rtl.css` | 236 B |
| `release/woocommerce-payments/dist/express-checkout.css` | 236 B |
| `release/woocommerce-payments/dist/express-checkout.js` | 15.9 kB |
| `release/woocommerce-payments/dist/frontend-tracks.js` | 854 B |
| `release/woocommerce-payments/dist/index-rtl.css` | 35.8 kB |
| `release/woocommerce-payments/dist/index.css` | 35.8 kB |
| `release/woocommerce-payments/dist/index.js` | 239 kB |
| `release/woocommerce-payments/dist/multi-currency-analytics.js` | 1.08 kB |
| `release/woocommerce-payments/dist/multi-currency-rtl.css` | 4.29 kB |
| `release/woocommerce-payments/dist/multi-currency-switcher-block.js` | 60.8 kB |
| `release/woocommerce-payments/dist/multi-currency.css` | 4.29 kB |
| `release/woocommerce-payments/dist/multi-currency.js` | 58.1 kB |
| `release/woocommerce-payments/dist/order-rtl.css` | 740 B |
| `release/woocommerce-payments/dist/order.css` | 740 B |
| `release/woocommerce-payments/dist/order.js` | 42.3 kB |
| `release/woocommerce-payments/dist/payment-gateways-rtl.css` | 1.34 kB |
| `release/woocommerce-payments/dist/payment-gateways.css` | 1.34 kB |
| `release/woocommerce-payments/dist/payment-gateways.js` | 39 kB |
| `release/woocommerce-payments/dist/plugins-page-rtl.css` | 375 B |
| `release/woocommerce-payments/dist/plugins-page.css` | 375 B |
| `release/woocommerce-payments/dist/plugins-page.js` | 20.1 kB |
| `release/woocommerce-payments/dist/product-details-rtl.css` | 433 B |
| `release/woocommerce-payments/dist/product-details.css` | 436 B |
| `release/woocommerce-payments/dist/product-details.js` | 12.7 kB |
| `release/woocommerce-payments/dist/settings-rtl.css` | 11.4 kB |
| `release/woocommerce-payments/dist/settings.css` | 11.4 kB |
| `release/woocommerce-payments/dist/settings.js` | 223 kB |
| `release/woocommerce-payments/dist/subscription-edit-page.js` | 703 B |
| `release/woocommerce-payments/dist/subscription-product-onboarding-modal-rtl.css` | 524 B |
| `release/woocommerce-payments/dist/subscription-product-onboarding-modal.css` | 524 B |
| `release/woocommerce-payments/dist/subscription-product-onboarding-modal.js` | 20.2 kB |
| `release/woocommerce-payments/dist/subscription-product-onboarding-toast.js` | 730 B |
| `release/woocommerce-payments/dist/subscriptions-empty-state-rtl.css` | 120 B |
| `release/woocommerce-payments/dist/subscriptions-empty-state.css` | 120 B |
| `release/woocommerce-payments/dist/subscriptions-empty-state.js` | 19.3 kB |
| `release/woocommerce-payments/dist/tokenized-express-checkout-rtl.css` | 236 B |
| `release/woocommerce-payments/dist/tokenized-express-checkout.css` | 236 B |
| `release/woocommerce-payments/dist/tokenized-express-checkout.js` | 16.9 kB |
| `release/woocommerce-payments/dist/tos-rtl.css` | 235 B |
| `release/woocommerce-payments/dist/tos.css` | 235 B |
| `release/woocommerce-payments/dist/tos.js` | 21.8 kB |
| `release/woocommerce-payments/dist/woopay-direct-checkout.js` | 6.13 kB |
| `release/woocommerce-payments/dist/woopay-express-button.js` | 23.5 kB |
| `release/woocommerce-payments/dist/woopay-rtl.css` | 4.31 kB |
| `release/woocommerce-payments/dist/woopay.css` | 4.28 kB |
| `release/woocommerce-payments/dist/woopay.js` | 71.1 kB |
| `release/woocommerce-payments/includes/subscriptions/assets/css/plugin-page.css` | 625 B |
| `release/woocommerce-payments/includes/subscriptions/assets/js/plugin-page.js` | 814 B |
| `release/woocommerce-payments/vendor/automattic/jetpack-assets/build/i18n-loader.js` | 2.46 kB |
| `release/woocommerce-payments/vendor/automattic/jetpack-assets/build/jetpack-script-data.js` | 957 B |
| `release/woocommerce-payments/vendor/automattic/jetpack-assets/src/js/i18n-loader.js` | 1.02 kB |
| `release/woocommerce-payments/vendor/automattic/jetpack-assets/src/js/script-data.js` | 69 B |
| `release/woocommerce-payments/vendor/automattic/jetpack-connection/babel.config.js` | 163 B |
| `release/woocommerce-payments/vendor/automattic/jetpack-connection/dist/identity-crisis.css` | 2.47 kB |
| `release/woocommerce-payments/vendor/automattic/jetpack-connection/dist/identity-crisis.js` | 14.3 kB |
| `release/woocommerce-payments/vendor/automattic/jetpack-connection/dist/identity-crisis.rtl.css` | 2.47 kB |
| `release/woocommerce-payments/vendor/automattic/jetpack-connection/dist/jetpack-connection.css` | 10.1 kB |
| `release/woocommerce-payments/vendor/automattic/jetpack-connection/dist/jetpack-connection.js` | 29.7 kB |
| `release/woocommerce-payments/vendor/automattic/jetpack-connection/dist/jetpack-connection.rtl.css` | 10.1 kB |
| `release/woocommerce-payments/vendor/automattic/jetpack-connection/dist/jetpack-sso-admin-create-user.css` | 198 B |
| `release/woocommerce-payments/vendor/automattic/jetpack-connection/dist/jetpack-sso-admin-create-user.js` | 280 B |
| `release/woocommerce-payments/vendor/automattic/jetpack-connection/dist/jetpack-sso-admin-create-user.rtl.css` | 198 B |
| `release/woocommerce-payments/vendor/automattic/jetpack-connection/dist/jetpack-sso-login.css` | 625 B |
| `release/woocommerce-payments/vendor/automattic/jetpack-connection/dist/jetpack-sso-login.js` | 333 B |
| `release/woocommerce-payments/vendor/automattic/jetpack-connection/dist/jetpack-sso-login.rtl.css` | 626 B |
| `release/woocommerce-payments/vendor/automattic/jetpack-connection/dist/jetpack-sso-users.js` | 417 B |
| `release/woocommerce-payments/vendor/automattic/jetpack-connection/dist/jetpack-users-connection.js` | 161 B |
| `release/woocommerce-payments/vendor/automattic/jetpack-connection/dist/tracks-ajax.js` | 521 B |
| `release/woocommerce-payments/vendor/automattic/jetpack-connection/dist/tracks-callables.js` | 585 B |
| `release/woocommerce-payments/vendor/automattic/jetpack-connection/src/sso/jetpack-sso-admin-create-user.css` | 215 B |
| `release/woocommerce-payments/vendor/automattic/jetpack-connection/src/sso/jetpack-sso-admin-create-user.js` | 521 B |
| `release/woocommerce-payments/vendor/automattic/jetpack-connection/src/sso/jetpack-sso-login.css` | 721 B |
| `release/woocommerce-payments/vendor/automattic/jetpack-connection/src/sso/jetpack-sso-login.js` | 412 B |
| `release/woocommerce-payments/vendor/automattic/jetpack-connection/src/sso/jetpack-sso-users.js` | 625 B |
| `release/woocommerce-payments/vendor/woocommerce/subscriptions-core/assets/css/about.css` | 1.04 kB |
| `release/woocommerce-payments/vendor/woocommerce/subscriptions-core/assets/css/admin-empty-state.css` | 294 B |
| `release/woocommerce-payments/vendor/woocommerce/subscriptions-core/assets/css/admin-order-statuses.css` | 408 B |
| `release/woocommerce-payments/vendor/woocommerce/subscriptions-core/assets/css/admin.css` | 3.59 kB |
| `release/woocommerce-payments/vendor/woocommerce/subscriptions-core/assets/css/checkout.css` | 301 B |
| `release/woocommerce-payments/vendor/woocommerce/subscriptions-core/assets/css/modal.css` | 746 B |
| `release/woocommerce-payments/vendor/woocommerce/subscriptions-core/assets/css/view-subscription.css` | 574 B |
| `release/woocommerce-payments/vendor/woocommerce/subscriptions-core/assets/css/wcs-upgrade.css` | 414 B |
| `release/woocommerce-payments/vendor/woocommerce/subscriptions-core/assets/js/admin/admin-pointers.js` | 543 B |
| `release/woocommerce-payments/vendor/woocommerce/subscriptions-core/assets/js/admin/admin.js` | 9.4 kB |
| `release/woocommerce-payments/vendor/woocommerce/subscriptions-core/assets/js/admin/jstz.js` | 6.78 kB |
| `release/woocommerce-payments/vendor/woocommerce/subscriptions-core/assets/js/admin/jstz.min.js` | 3.84 kB |
| `release/woocommerce-payments/vendor/woocommerce/subscriptions-core/assets/js/admin/meta-boxes-coupon.js` | 545 B |
| `release/woocommerce-payments/vendor/woocommerce/subscriptions-core/assets/js/admin/meta-boxes-subscription.js` | 2.52 kB |
| `release/woocommerce-payments/vendor/woocommerce/subscriptions-core/assets/js/admin/moment.js` | 22.2 kB |
| `release/woocommerce-payments/vendor/woocommerce/subscriptions-core/assets/js/admin/moment.min.js` | 11.7 kB |
| `release/woocommerce-payments/vendor/woocommerce/subscriptions-core/assets/js/admin/payment-method-restrictions.js` | 1.29 kB |
| `release/woocommerce-payments/vendor/woocommerce/subscriptions-core/assets/js/admin/wcs-meta-boxes-order.js` | 507 B |
| `release/woocommerce-payments/vendor/woocommerce/subscriptions-core/assets/js/frontend/payment-methods.js` | 358 B |
| `release/woocommerce-payments/vendor/woocommerce/subscriptions-core/assets/js/frontend/single-product.js` | 428 B |
| `release/woocommerce-payments/vendor/woocommerce/subscriptions-core/assets/js/frontend/view-subscription.js` | 1.38 kB |
| `release/woocommerce-payments/vendor/woocommerce/subscriptions-core/assets/js/frontend/wcs-cart.js` | 782 B |
| `release/woocommerce-payments/vendor/woocommerce/subscriptions-core/assets/js/modal.js` | 1.09 kB |
| `release/woocommerce-payments/vendor/woocommerce/subscriptions-core/assets/js/wcs-upgrade.js` | 1.26 kB |
| `release/woocommerce-payments/vendor/woocommerce/subscriptions-core/build/index.css` | 391 B |
| `release/woocommerce-payments/vendor/woocommerce/subscriptions-core/build/index.js` | 3.04 kB |

</details>



<a href="https://github.com/preactjs/compressed-size-action"><sub>compressed-size-action</sub></a>
author_association: CONTRIBUTOR
user: login: danielmx-dev
created_at: 2025-03-14T13:23:09Z
body: The changes work well, however the message below the heading is a bit confusing, but I don't think there's a way to hide it or change it, is it?

![image](https://github.com/user-attachments/assets/ed41ab0a-ea5d-46ec-8efd-589f84b3e8f3)

If this is expected and we are ok with it please let me know so I can approve the PR.
author_association: CONTRIBUTOR
user: login: mdmoore
created_at: 2025-03-14T16:04:41Z
body: That's unfortunate. I hadn't seen this messaging coming from the blocks order confirmation implementation. The message is displayed because there's no order key in the URL

>I don't think there's a way to hide it or change it, is it?

There isn't. Even if the text were filterable, it looks like there's a bug in blocks that is displaying 2 messages. For example, here's an order with WooPayments disabled: 

<img width="1353" alt="Screenshot 2025-03-14 at 11 51 23 AM" src="https://github.com/user-attachments/assets/392d0241-8f1d-40a9-a6d7-c4fb8d1334bc" />

I think in this case, hiding the blocks text is the best way to go. I can report the issue in blocks as well as request some filters be added to these confirmation strings. Many strings are already filterable in [Status.php](https://github.com/woocommerce/woocommerce/blob/3f5f8fd80610a52a1f53fc17a11d4c90d6715c85/plugins/woocommerce/src/Blocks/BlockTypes/OrderConfirmation/Status.php#L75) via the `woocommerce_thankyou_order_received_text` filter.

Another option would be to skip this change on block themes, but I think just hiding the duplicate text for this case is fine.
author_association: CONTRIBUTOR