Commit 09707f2952a for woocommerce

commit 09707f2952a9d85278d63044e76fd17eb2b3b7a9
Author: Mayisha <33387139+Mayisha@users.noreply.github.com>
Date:   Thu Mar 5 22:11:40 2026 +0600

    PayPal Standard: Prevent duplicate order details requests on 404 (#63464)

    * prevent repeated auth capture method call when get order returns 404

    * add tests

    * Add changefile(s) from automation for the following project(s): woocommerce

    * address feedback about test

diff --git a/plugins/woocommerce/changelog/63464-fix-paypal-standard-404-prevent-duplicate-order-details-requests b/plugins/woocommerce/changelog/63464-fix-paypal-standard-404-prevent-duplicate-order-details-requests
new file mode 100644
index 00000000000..88f011fe8b7
--- /dev/null
+++ b/plugins/woocommerce/changelog/63464-fix-paypal-standard-404-prevent-duplicate-order-details-requests
@@ -0,0 +1,4 @@
+Significance: patch
+Type: fix
+
+Prevent repeated PayPal Standard order details API requests when the first request returns 404.
\ No newline at end of file
diff --git a/plugins/woocommerce/src/Gateways/PayPal/Request.php b/plugins/woocommerce/src/Gateways/PayPal/Request.php
index 992e5ba889b..e5d361088d5 100644
--- a/plugins/woocommerce/src/Gateways/PayPal/Request.php
+++ b/plugins/woocommerce/src/Gateways/PayPal/Request.php
@@ -541,7 +541,18 @@ class Request {
 			\WC_Gateway_Paypal::log( 'Authorization ID not found, trying to retrieve from PayPal order details as a fallback for backwards compatibility. Order ID: ' . $order->get_id() );

 			try {
-				$order_data         = $this->get_paypal_order_details( $paypal_order_id );
+				$order_data = $this->get_paypal_order_details( $paypal_order_id );
+			} catch ( Exception $e ) {
+				\WC_Gateway_Paypal::log( 'Error retrieving PayPal order details. Order ID: ' . $order->get_id() . '. Error: ' . $e->getMessage() );
+				// On 404 (order not found), set flag to prevent repeated API calls.
+				if ( false !== strpos( $e->getMessage(), 'HTTP 404' ) ) {
+					$order->update_meta_data( PayPalConstants::PAYPAL_ORDER_META_AUTHORIZATION_CHECKED, 'yes' );
+					$order->save();
+				}
+				return null;
+			}
+
+			try {
 				$authorization_data = $this->get_latest_transaction_data(
 					$order_data['purchase_units'][0]['payments']['authorizations'] ?? array()
 				);
diff --git a/plugins/woocommerce/tests/php/src/Gateways/PayPal/RequestTest.php b/plugins/woocommerce/tests/php/src/Gateways/PayPal/RequestTest.php
index 1d471bd085e..6cd66dc448f 100644
--- a/plugins/woocommerce/tests/php/src/Gateways/PayPal/RequestTest.php
+++ b/plugins/woocommerce/tests/php/src/Gateways/PayPal/RequestTest.php
@@ -522,6 +522,53 @@ class RequestTest extends \WC_Unit_Test_Case {
 		$this->assertEquals( 0, $capture_api_call_count, 'Expected no capture_auth API call when PayPal Order ID is missing' );
 	}

+	/**
+	 * Test that 404 from get order details sets authorization_checked flag and prevents repeated requests.
+	 *
+	 * @return void
+	 */
+	public function test_capture_authorized_payment_not_attempted_when_order_details_404(): void {
+		$order = \WC_Helper_Order::create_order();
+		$order->update_meta_data( PayPalConstants::PAYPAL_ORDER_META_ORDER_ID, 'PAYPAL_ORDER_123' );
+		$order->save();
+
+		$order_details_call_count = 0;
+		add_filter(
+			'pre_http_request',
+			function ( $value, $parsed_args, $url ) use ( &$order_details_call_count ) {
+				if (
+					isset( $parsed_args['method'] ) &&
+					'GET' === $parsed_args['method'] &&
+					strpos( $url, 'order/PAYPAL_ORDER_123' ) !== false
+				) {
+					++$order_details_call_count;
+					return array(
+						'response' => array( 'code' => 404 ),
+						'body'     => wp_json_encode( array( 'message' => 'Order not found' ) ),
+					);
+				}
+
+				return $value;
+			},
+			10,
+			3
+		);
+
+		$request = new PayPalRequest( new \WC_Gateway_Paypal() );
+		$request->capture_authorized_payment( $order );
+
+		// First call: one order details request, flag should be set.
+		$this->assertEquals( 1, $order_details_call_count, 'Expected one order details request on first capture attempt' );
+		$order = wc_get_order( $order->get_id() );
+		$this->assertSame( 'yes', $order->get_meta( PayPalConstants::PAYPAL_ORDER_META_AUTHORIZATION_CHECKED, true ), 'Expected authorization_checked flag to be set after 404' );
+
+		// Second call: should not hit order details again because flag is set.
+		$request->capture_authorized_payment( $order );
+		$this->assertEquals( 1, $order_details_call_count, 'Expected no additional order details request after 404 (flag prevents retry)' );
+
+		remove_all_filters( 'pre_http_request' );
+	}
+
 	/**
 	 * Test capture is skipped when payment is already captured (via capture_id).
 	 *