diff --git a/changelog.txt b/changelog.txt
index acdd013efe5..b0951f1cd02 100644
--- a/changelog.txt
+++ b/changelog.txt
@@ -1,5 +1,8 @@
 *** WooPayments Changelog ***
 
+= 7.8.1 - 2024-06-25 =
+* Fix - Fix "Dispute not loaded" error that was affecting responding to disputes.
+
 = 7.8.0 - 2024-06-19 =
 * Add - Add a feedback survey modal upon deactivation.
 * Add - Add new select component to be used for reporting filters, e.g. Payments overview currency select
diff --git a/changelog/add-8951-support-style-settings-with-ece-buttons b/changelog/add-8951-support-style-settings-with-ece-buttons
new file mode 100644
index 00000000000..acb0ba496fd
--- /dev/null
+++ b/changelog/add-8951-support-style-settings-with-ece-buttons
@@ -0,0 +1,4 @@
+Significance: minor
+Type: add
+
+Support style settings for ECE buttons
diff --git a/changelog/fix-token-retrieval-per-payment-method b/changelog/fix-token-retrieval-per-payment-method
new file mode 100644
index 00000000000..1ec9a65c246
--- /dev/null
+++ b/changelog/fix-token-retrieval-per-payment-method
@@ -0,0 +1,4 @@
+Significance: minor
+Type: fix
+
+Retrieve saved tokens only relevant for the specific payment gateway.
diff --git a/changelog/revert-8901-update-route-param-validation b/changelog/revert-8901-update-route-param-validation
new file mode 100644
index 00000000000..77bc7eaeee5
--- /dev/null
+++ b/changelog/revert-8901-update-route-param-validation
@@ -0,0 +1,4 @@
+Significance: patch
+Type: fix
+
+Fix "Dispute not loaded" error that was affecting responding to disputes.
diff --git a/changelog/update-speedup-phpunit-tests b/changelog/update-speedup-phpunit-tests
new file mode 100644
index 00000000000..db651399352
--- /dev/null
+++ b/changelog/update-speedup-phpunit-tests
@@ -0,0 +1,5 @@
+Significance: patch
+Type: dev
+Comment: These changes only affect PHPUnit tests.
+
+
diff --git a/client/express-checkout/blocks/components/express-checkout-container.js b/client/express-checkout/blocks/components/express-checkout-container.js
index 9285227bf63..931e2a6223f 100644
--- a/client/express-checkout/blocks/components/express-checkout-container.js
+++ b/client/express-checkout/blocks/components/express-checkout-container.js
@@ -2,6 +2,7 @@
  * External dependencies
  */
 import { Elements } from '@stripe/react-stripe-js';
+import { getExpressCheckoutButtonAppearance } from 'wcpay/express-checkout/utils';
 
 /**
  * Internal dependencies
@@ -16,6 +17,7 @@ const ExpressCheckoutContainer = ( props ) => {
 		paymentMethodCreation: 'manual',
 		amount: billing.cartTotal.value,
 		currency: billing.currency.code.toLowerCase(),
+		appearance: getExpressCheckoutButtonAppearance(),
 	};
 
 	return (
diff --git a/client/express-checkout/blocks/hooks/use-express-checkout.js b/client/express-checkout/blocks/hooks/use-express-checkout.js
index e01c5eaf5bc..ee5f7be6ed4 100644
--- a/client/express-checkout/blocks/hooks/use-express-checkout.js
+++ b/client/express-checkout/blocks/hooks/use-express-checkout.js
@@ -5,7 +5,10 @@
  */
 import { useCallback } from '@wordpress/element';
 import { useStripe, useElements } from '@stripe/react-stripe-js';
-import { normalizeLineItems } from 'wcpay/express-checkout/utils';
+import {
+	getExpressCheckoutButtonStyleSettings,
+	normalizeLineItems,
+} from 'wcpay/express-checkout/utils';
 import { onConfirmHandler } from 'wcpay/express-checkout/event-handlers';
 
 export const useExpressCheckout = ( {
@@ -19,17 +22,7 @@ export const useExpressCheckout = ( {
 	const stripe = useStripe();
 	const elements = useElements();
 
-	const buttonOptions = {
-		paymentMethods: {
-			applePay: 'always',
-			googlePay: 'always',
-			link: 'auto',
-		},
-		buttonType: {
-			googlePay: wcpayExpressCheckoutParams.button.type,
-			applePay: wcpayExpressCheckoutParams.button.type,
-		},
-	};
+	const buttonOptions = getExpressCheckoutButtonStyleSettings();
 
 	const onCancel = () => {
 		onClose();
diff --git a/client/express-checkout/index.js b/client/express-checkout/index.js
index abcf1102b46..45fea02f042 100644
--- a/client/express-checkout/index.js
+++ b/client/express-checkout/index.js
@@ -6,7 +6,12 @@ import { __ } from '@wordpress/i18n';
  */
 import WCPayAPI from '../checkout/api';
 import '../checkout/express-checkout-buttons.scss';
-import { getExpressCheckoutData, normalizeLineItems } from './utils/index';
+import {
+	getExpressCheckoutButtonAppearance,
+	getExpressCheckoutButtonStyleSettings,
+	getExpressCheckoutData,
+	normalizeLineItems,
+} from './utils/index';
 import {
 	onConfirmHandler,
 	shippingAddressChangeHandler,
@@ -232,14 +237,13 @@ jQuery( ( $ ) => {
 				amount: options?.total,
 				currency: options?.currency,
 				paymentMethodCreation: 'manual',
+				appearance: getExpressCheckoutButtonAppearance(),
 			} );
 
-			const eceButton = wcpayECE.createButton( elements, {
-				buttonType: {
-					googlePay: getExpressCheckoutData( 'button' ).type,
-					applePay: getExpressCheckoutData( 'button' ).type,
-				},
-			} );
+			const eceButton = wcpayECE.createButton(
+				elements,
+				getExpressCheckoutButtonStyleSettings()
+			);
 
 			wcpayECE.showButton( eceButton );
 
diff --git a/client/express-checkout/utils/index.ts b/client/express-checkout/utils/index.ts
index b10d80b0960..abe139becec 100644
--- a/client/express-checkout/utils/index.ts
+++ b/client/express-checkout/utils/index.ts
@@ -87,8 +87,10 @@ declare global {
 	}
 }
 
-export const getExpressCheckoutData = (
-	key: keyof WCPayExpressCheckoutParams
+export const getExpressCheckoutData = <
+	K extends keyof WCPayExpressCheckoutParams
+>(
+	key: K
 ) => {
 	if ( window.wcpayExpressCheckoutParams ) {
 		return window.wcpayExpressCheckoutParams?.[ key ];
@@ -108,3 +110,78 @@ export const getErrorMessageFromNotice = ( notice: string ) => {
 	div.innerHTML = notice.trim();
 	return div.firstChild ? div.firstChild.textContent : '';
 };
+
+/**
+ * Returns the appearance settings for the Express Checkout buttons.
+ * Currently only configures border radius for the buttons.
+ */
+export const getExpressCheckoutButtonAppearance = () => {
+	return {
+		// variables: { borderRadius: '99999px' },
+	};
+};
+
+/**
+ * Returns the style settings for the Express Checkout buttons.
+ */
+export const getExpressCheckoutButtonStyleSettings = () => {
+	const buttonSettings = getExpressCheckoutData( 'button' );
+
+	const mapWooPaymentsThemeToButtonTheme = (
+		buttonType: string,
+		theme: string
+	) => {
+		switch ( theme ) {
+			case 'dark':
+				return 'black';
+			case 'light':
+				return 'white';
+			case 'light-outline':
+				if ( buttonType === 'googlePay' ) {
+					return 'white';
+				}
+
+				return 'white-outline';
+			default:
+				return 'black';
+		}
+	};
+
+	const googlePayType =
+		buttonSettings?.type === 'default'
+			? 'plain'
+			: buttonSettings?.type ?? 'buy';
+
+	const applePayType =
+		buttonSettings?.type === 'default'
+			? 'plain'
+			: buttonSettings?.type ?? 'plain';
+
+	return {
+		paymentMethods: {
+			applePay: 'always',
+			googlePay: 'always',
+			link: 'auto',
+		},
+		layout: { overflow: 'never' },
+		buttonTheme: {
+			googlePay: mapWooPaymentsThemeToButtonTheme(
+				'googlePay',
+				buttonSettings?.theme ?? 'black'
+			),
+			applePay: mapWooPaymentsThemeToButtonTheme(
+				'applePay',
+				buttonSettings?.theme ?? 'black'
+			),
+		},
+		buttonType: {
+			googlePay: googlePayType,
+			applePay: applePayType,
+		},
+		// Allowed height must be 40px to 55px.
+		buttonHeight: Math.min(
+			Math.max( parseInt( buttonSettings?.height ?? '48', 10 ), 40 ),
+			55
+		),
+	};
+};
diff --git a/includes/admin/class-wc-rest-payments-authorizations-controller.php b/includes/admin/class-wc-rest-payments-authorizations-controller.php
index a35f3fc85e3..1b2993e3c71 100644
--- a/includes/admin/class-wc-rest-payments-authorizations-controller.php
+++ b/includes/admin/class-wc-rest-payments-authorizations-controller.php
@@ -46,7 +46,7 @@ public function register_routes() {
 		);
 		register_rest_route(
 			$this->namespace,
-			'/' . $this->rest_base . '/(?P<payment_intent_id>(ch|pi|py)_[A-Za-z0-9]+)',
+			'/' . $this->rest_base . '/(?P<payment_intent_id>\w+)',
 			[
 				'methods'             => WP_REST_Server::READABLE,
 				'callback'            => [ $this, 'get_authorization' ],
diff --git a/includes/admin/class-wc-rest-payments-charges-controller.php b/includes/admin/class-wc-rest-payments-charges-controller.php
index 2297e3bd13a..34422cac647 100644
--- a/includes/admin/class-wc-rest-payments-charges-controller.php
+++ b/includes/admin/class-wc-rest-payments-charges-controller.php
@@ -28,7 +28,7 @@ class WC_REST_Payments_Charges_Controller extends WC_Payments_REST_Controller {
 	public function register_routes() {
 		register_rest_route(
 			$this->namespace,
-			'/' . $this->rest_base . '/(?P<charge_id>ch_[A-Za-z0-9]+)',
+			'/' . $this->rest_base . '/(?P<charge_id>\w+)',
 			[
 				'methods'             => WP_REST_Server::READABLE,
 				'callback'            => [ $this, 'get_charge' ],
@@ -37,7 +37,7 @@ public function register_routes() {
 		);
 		register_rest_route(
 			$this->namespace,
-			'/' . $this->rest_base . '/order/(?P<order_id>[A-Za-z0-9_\-]+)',
+			'/' . $this->rest_base . '/order/(?P<order_id>\w+)',
 			[
 				'methods'             => WP_REST_Server::READABLE,
 				'callback'            => [ $this, 'generate_charge_from_order' ],
diff --git a/includes/admin/class-wc-rest-payments-customer-controller.php b/includes/admin/class-wc-rest-payments-customer-controller.php
index 5ccce5c99d6..c0f43a97003 100644
--- a/includes/admin/class-wc-rest-payments-customer-controller.php
+++ b/includes/admin/class-wc-rest-payments-customer-controller.php
@@ -49,7 +49,7 @@ public function __construct(
 	public function register_routes() {
 		register_rest_route(
 			$this->namespace,
-			'/' . $this->rest_base . '/(?P<customer_id>[A-Za-z0-9_\-]+)/payment_methods',
+			'/' . $this->rest_base . '/(?P<customer_id>\w+)/payment_methods',
 			[
 				[
 					'methods'             => WP_REST_Server::READABLE,
diff --git a/includes/admin/class-wc-rest-payments-deposits-controller.php b/includes/admin/class-wc-rest-payments-deposits-controller.php
index da3b3c1afbc..1b5c808a314 100644
--- a/includes/admin/class-wc-rest-payments-deposits-controller.php
+++ b/includes/admin/class-wc-rest-payments-deposits-controller.php
@@ -55,7 +55,7 @@ public function register_routes() {
 		);
 		register_rest_route(
 			$this->namespace,
-			'/' . $this->rest_base . '/(?P<deposit_id>[A-Za-z0-9_\-]+)',
+			'/' . $this->rest_base . '/(?P<deposit_id>\w+)',
 			[
 				'methods'             => WP_REST_Server::READABLE,
 				'callback'            => [ $this, 'get_deposit' ],
diff --git a/includes/admin/class-wc-rest-payments-disputes-controller.php b/includes/admin/class-wc-rest-payments-disputes-controller.php
index 4dacf45ee5c..64e1e478a21 100644
--- a/includes/admin/class-wc-rest-payments-disputes-controller.php
+++ b/includes/admin/class-wc-rest-payments-disputes-controller.php
@@ -54,7 +54,7 @@ public function register_routes() {
 		);
 		register_rest_route(
 			$this->namespace,
-			'/' . $this->rest_base . '/(?P<dispute_id>(dp|dispute)_[A-Za-z0-9]+)',
+			'/' . $this->rest_base . '/(?P<dispute_id>\w+)',
 			[
 				'methods'             => WP_REST_Server::READABLE,
 				'callback'            => [ $this, 'get_dispute' ],
@@ -63,7 +63,7 @@ public function register_routes() {
 		);
 		register_rest_route(
 			$this->namespace,
-			'/' . $this->rest_base . '/(?P<dispute_id>(dp|dispute)_[A-Za-z0-9]+)',
+			'/' . $this->rest_base . '/(?P<dispute_id>\w+)',
 			[
 				'methods'             => WP_REST_Server::CREATABLE,
 				'callback'            => [ $this, 'update_dispute' ],
@@ -72,7 +72,7 @@ public function register_routes() {
 		);
 		register_rest_route(
 			$this->namespace,
-			'/' . $this->rest_base . '/(?P<dispute_id>(dp|dispute)_[A-Za-z0-9]+)/close',
+			'/' . $this->rest_base . '/(?P<dispute_id>\w+)/close',
 			[
 				'methods'             => WP_REST_Server::CREATABLE,
 				'callback'            => [ $this, 'close_dispute' ],
diff --git a/includes/admin/class-wc-rest-payments-files-controller.php b/includes/admin/class-wc-rest-payments-files-controller.php
index 6720b52b959..e66eedefffd 100644
--- a/includes/admin/class-wc-rest-payments-files-controller.php
+++ b/includes/admin/class-wc-rest-payments-files-controller.php
@@ -35,7 +35,7 @@ public function register_routes() {
 
 		register_rest_route(
 			$this->namespace,
-			'/' . $this->rest_base . '/(?P<file_id>[A-Za-z0-9_\-]+)/details',
+			'/' . $this->rest_base . '/(?P<file_id>\w+)/details',
 			[
 				'methods'             => WP_REST_Server::READABLE,
 				'callback'            => [ $this, 'get_file_detail' ],
@@ -45,7 +45,7 @@ public function register_routes() {
 
 		register_rest_route(
 			$this->namespace,
-			'/' . $this->rest_base . '/(?P<file_id>[A-Za-z0-9_\-]+)/content',
+			'/' . $this->rest_base . '/(?P<file_id>\w+)/content',
 			[
 				'methods'             => WP_REST_Server::READABLE,
 				'callback'            => [ $this, 'get_file_content' ],
@@ -55,7 +55,7 @@ public function register_routes() {
 
 		register_rest_route(
 			$this->namespace,
-			'/' . $this->rest_base . '/(?P<file_id>[A-Za-z0-9_\-]+)',
+			'/' . $this->rest_base . '/(?P<file_id>\w+)',
 			[
 				'methods'             => WP_REST_Server::READABLE,
 				'callback'            => [ $this, 'get_file' ],
diff --git a/includes/admin/class-wc-rest-payments-fraud-outcomes-controller.php b/includes/admin/class-wc-rest-payments-fraud-outcomes-controller.php
index 199e62255cf..7d0feb06024 100644
--- a/includes/admin/class-wc-rest-payments-fraud-outcomes-controller.php
+++ b/includes/admin/class-wc-rest-payments-fraud-outcomes-controller.php
@@ -25,7 +25,7 @@ class WC_REST_Payments_Fraud_Outcomes_Controller extends WC_Payments_REST_Contro
 	public function register_routes() {
 		register_rest_route(
 			$this->namespace,
-			'/' . $this->rest_base . '/(?P<id>[A-Za-z0-9_\-]+)/latest',
+			'/' . $this->rest_base . '/(?P<id>\w+)/latest',
 			[
 				'methods'             => WP_REST_Server::READABLE,
 				'callback'            => [ $this, 'get_latest_fraud_outcome' ],
diff --git a/includes/admin/class-wc-rest-payments-orders-controller.php b/includes/admin/class-wc-rest-payments-orders-controller.php
index f79e0a5fcfd..04c86f54197 100644
--- a/includes/admin/class-wc-rest-payments-orders-controller.php
+++ b/includes/admin/class-wc-rest-payments-orders-controller.php
@@ -68,7 +68,7 @@ public function __construct( WC_Payments_API_Client $api_client, WC_Payment_Gate
 	public function register_routes() {
 		register_rest_route(
 			$this->namespace,
-			$this->rest_base . '/(?P<order_id>[A-Za-z0-9_\-]+)/capture_terminal_payment',
+			$this->rest_base . '/(?P<order_id>\w+)/capture_terminal_payment',
 			[
 				'methods'             => WP_REST_Server::CREATABLE,
 				'callback'            => [ $this, 'capture_terminal_payment' ],
@@ -82,7 +82,7 @@ public function register_routes() {
 		);
 		register_rest_route(
 			$this->namespace,
-			$this->rest_base . '/(?P<order_id>[A-Za-z0-9_\-]+)/capture_authorization',
+			$this->rest_base . '/(?P<order_id>\w+)/capture_authorization',
 			[
 				'methods'             => WP_REST_Server::CREATABLE,
 				'callback'            => [ $this, 'capture_authorization' ],
@@ -96,7 +96,7 @@ public function register_routes() {
 		);
 		register_rest_route(
 			$this->namespace,
-			$this->rest_base . '/(?P<order_id>[A-Za-z0-9_\-]+)/cancel_authorization',
+			$this->rest_base . '/(?P<order_id>\w+)/cancel_authorization',
 			[
 				'methods'             => WP_REST_Server::CREATABLE,
 				'callback'            => [ $this, 'cancel_authorization' ],
@@ -110,7 +110,7 @@ public function register_routes() {
 		);
 		register_rest_route(
 			$this->namespace,
-			$this->rest_base . '/(?P<order_id>[A-Za-z0-9_\-]+)/create_terminal_intent',
+			$this->rest_base . '/(?P<order_id>\w+)/create_terminal_intent',
 			[
 				'methods'             => WP_REST_Server::CREATABLE,
 				'callback'            => [ $this, 'create_terminal_intent' ],
diff --git a/includes/admin/class-wc-rest-payments-payment-intents-controller.php b/includes/admin/class-wc-rest-payments-payment-intents-controller.php
index 9ba1a39fa67..670d15a3089 100644
--- a/includes/admin/class-wc-rest-payments-payment-intents-controller.php
+++ b/includes/admin/class-wc-rest-payments-payment-intents-controller.php
@@ -32,7 +32,7 @@ class WC_REST_Payments_Payment_Intents_Controller extends WC_Payments_REST_Contr
 	public function register_routes() {
 		register_rest_route(
 			$this->namespace,
-			'/' . $this->rest_base . '/(?P<payment_intent_id>(ch|pi|py)_[A-Za-z0-9]+)',
+			'/' . $this->rest_base . '/(?P<payment_intent_id>\w+)',
 			[
 				'methods'             => WP_REST_Server::READABLE,
 				'callback'            => [ $this, 'get_payment_intent' ],
diff --git a/includes/admin/class-wc-rest-payments-reader-controller.php b/includes/admin/class-wc-rest-payments-reader-controller.php
index 569e49bc9ed..fa6fa5192e0 100644
--- a/includes/admin/class-wc-rest-payments-reader-controller.php
+++ b/includes/admin/class-wc-rest-payments-reader-controller.php
@@ -114,7 +114,7 @@ public function register_routes() {
 
 		register_rest_route(
 			$this->namespace,
-			'/' . $this->rest_base . '/charges/(?P<transaction_id>[A-Za-z0-9_\-]+)',
+			'/' . $this->rest_base . '/charges/(?P<transaction_id>\w+)',
 			[
 				'methods'             => WP_REST_Server::READABLE,
 				'callback'            => [ $this, 'get_summary' ],
@@ -132,7 +132,7 @@ public function register_routes() {
 		);
 		register_rest_route(
 			$this->namespace,
-			'/' . $this->rest_base . '/receipts/(?P<payment_intent_id>(ch|pi|py)_[A-Za-z0-9]+)',
+			'/' . $this->rest_base . '/receipts/(?P<payment_intent_id>\w+)',
 			[
 				'methods'             => WP_REST_Server::READABLE,
 				'callback'            => [ $this, 'generate_print_receipt' ],
diff --git a/includes/admin/class-wc-rest-payments-terminal-locations-controller.php b/includes/admin/class-wc-rest-payments-terminal-locations-controller.php
index 90062ef3b8c..c0f0f7754ee 100644
--- a/includes/admin/class-wc-rest-payments-terminal-locations-controller.php
+++ b/includes/admin/class-wc-rest-payments-terminal-locations-controller.php
@@ -38,7 +38,7 @@ public function register_routes() {
 		);
 		register_rest_route(
 			$this->namespace,
-			'/' . $this->rest_base . '/(?P<location_id>[A-Za-z0-9_\-]+)',
+			'/' . $this->rest_base . '/(?P<location_id>\w+)',
 			[
 				'methods'             => WP_REST_Server::DELETABLE,
 				'callback'            => [ $this, 'delete_location' ],
@@ -47,7 +47,7 @@ public function register_routes() {
 		);
 		register_rest_route(
 			$this->namespace,
-			'/' . $this->rest_base . '/(?P<location_id>[A-Za-z0-9_\-]+)',
+			'/' . $this->rest_base . '/(?P<location_id>\w+)',
 			[
 				'methods'             => WP_REST_Server::CREATABLE,
 				'callback'            => [ $this, 'update_location' ],
@@ -66,7 +66,7 @@ public function register_routes() {
 		);
 		register_rest_route(
 			$this->namespace,
-			'/' . $this->rest_base . '/(?P<location_id>[A-Za-z0-9_\-]+)',
+			'/' . $this->rest_base . '/(?P<location_id>\w+)',
 			[
 				'methods'             => WP_REST_Server::READABLE,
 				'callback'            => [ $this, 'get_location' ],
diff --git a/includes/admin/class-wc-rest-payments-timeline-controller.php b/includes/admin/class-wc-rest-payments-timeline-controller.php
index 23a1c4136d1..c2c0f5ac87a 100644
--- a/includes/admin/class-wc-rest-payments-timeline-controller.php
+++ b/includes/admin/class-wc-rest-payments-timeline-controller.php
@@ -24,7 +24,7 @@ class WC_REST_Payments_Timeline_Controller extends WC_Payments_REST_Controller {
 	public function register_routes() {
 		register_rest_route(
 			$this->namespace,
-			'/' . $this->rest_base . '/(?P<intention_id>(ch|pi|py)_[A-Za-z0-9]+)',
+			'/' . $this->rest_base . '/(?P<intention_id>\w+)',
 			[
 				'methods'             => WP_REST_Server::READABLE,
 				'callback'            => [ $this, 'get_timeline' ],
diff --git a/includes/admin/class-wc-rest-payments-transactions-controller.php b/includes/admin/class-wc-rest-payments-transactions-controller.php
index 5c72a32ed0e..c3a783943b8 100644
--- a/includes/admin/class-wc-rest-payments-transactions-controller.php
+++ b/includes/admin/class-wc-rest-payments-transactions-controller.php
@@ -100,7 +100,7 @@ public function register_routes() {
 		);
 		register_rest_route(
 			$this->namespace,
-			'/' . $this->rest_base . '/(?P<transaction_id>[A-Za-z0-9_\-]+)',
+			'/' . $this->rest_base . '/(?P<transaction_id>\w+)',
 			[
 				'methods'             => WP_REST_Server::READABLE,
 				'callback'            => [ $this, 'get_transaction' ],
diff --git a/includes/class-wc-payments-token-service.php b/includes/class-wc-payments-token-service.php
index 6a8f9e21d0a..0eb810bce75 100644
--- a/includes/class-wc-payments-token-service.php
+++ b/includes/class-wc-payments-token-service.php
@@ -163,15 +163,7 @@ public function woocommerce_get_customer_payment_tokens( $tokens, $user_id, $gat
 				}
 			}
 
-			$retrievable_payment_method_types = [ Payment_Method::CARD ];
-
-			if ( in_array( Payment_Method::SEPA, WC_Payments::get_gateway()->get_upe_enabled_payment_method_ids(), true ) ) {
-				$retrievable_payment_method_types[] = Payment_Method::SEPA;
-			}
-
-			if ( in_array( Payment_Method::LINK, WC_Payments::get_gateway()->get_upe_enabled_payment_method_ids(), true ) ) {
-				$retrievable_payment_method_types[] = Payment_Method::LINK;
-			}
+			$retrievable_payment_method_types = $this->get_retrievable_payment_method_types( $gateway_id );
 
 			$payment_methods = [];
 
@@ -213,6 +205,77 @@ public function woocommerce_get_customer_payment_tokens( $tokens, $user_id, $gat
 		return $tokens;
 	}
 
+	/**
+	 * Retrieves the payment method types for which tokens should be retrieved.
+	 *
+	 * This function determines the appropriate payment method types based on the provided gateway ID.
+	 * - If a gateway ID is provided, it retrieves the payment methods specific to that gateway to prevent duplication of saved tokens under incorrect payment methods during checkout.
+	 * - If no gateway ID is provided, it retrieves the default payment methods to fetch all saved tokens, e.g., for the Blocks checkout or My Account page.
+	 *
+	 * @param string|null $gateway_id The optional ID of the gateway.
+	 * @return array The list of retrievable payment method types.
+	 */
+	private function get_retrievable_payment_method_types( $gateway_id = null ) {
+		if ( empty( $gateway_id ) ) {
+			return $this->get_all_retrievable_payment_types();
+		} else {
+			return $this->get_gateway_specific_retrievable_payment_types( $gateway_id );
+		}
+	}
+
+	/**
+	 * Returns all the enabled retrievable payment method types.
+	 *
+	 * @return array Enabled retrievable payment method types.
+	 */
+	private function get_all_retrievable_payment_types() {
+		$types = [ Payment_Method::CARD ];
+
+		if ( $this->is_payment_method_enabled( Payment_Method::SEPA ) ) {
+			$types[] = Payment_Method::SEPA;
+		}
+
+		if ( $this->is_payment_method_enabled( Payment_Method::LINK ) ) {
+			$types[] = Payment_Method::LINK;
+		}
+
+		return $types;
+	}
+	/**
+	 * Returns retrievable payment method types for a given gateway.
+	 *
+	 * @param string $gateway_id The ID of the gateway.
+	 * @return array Retrievable payment method types for the specified gateway.
+	 */
+	private function get_gateway_specific_retrievable_payment_types( $gateway_id ) {
+		$types = [];
+
+		foreach ( self::REUSABLE_GATEWAYS_BY_PAYMENT_METHOD as $payment_method => $gateway ) {
+			if ( $gateway !== $gateway_id ) {
+				continue;
+			}
+
+			// Stripe Link is part of the card gateway, so we need to check separately if Link is enabled.
+			if ( Payment_Method::LINK === $payment_method && ! $this->is_payment_method_enabled( Payment_Method::LINK ) ) {
+				continue;
+			}
+
+			$types[] = $payment_method;
+		}
+
+		return $types;
+	}
+
+	/**
+	 * Checks if a payment method is enabled.
+	 *
+	 * @param string $payment_method The payment method to check.
+	 * @return bool True if the payment method is enabled, false otherwise.
+	 */
+	private function is_payment_method_enabled( $payment_method ) {
+		return in_array( $payment_method, WC_Payments::get_gateway()->get_upe_enabled_payment_method_ids(), true );
+	}
+
 	/**
 	 * Delete token from Stripe.
 	 *
diff --git a/includes/reports/class-wc-rest-payments-reports-authorizations-controller.php b/includes/reports/class-wc-rest-payments-reports-authorizations-controller.php
index 20cba8bc6cf..0834d078eeb 100644
--- a/includes/reports/class-wc-rest-payments-reports-authorizations-controller.php
+++ b/includes/reports/class-wc-rest-payments-reports-authorizations-controller.php
@@ -40,7 +40,7 @@ public function register_routes() {
 		);
 		register_rest_route(
 			$this->namespace,
-			'/' . $this->rest_base . '/(?P<id>[A-Za-z0-9_\-]+)',
+			'/' . $this->rest_base . '/(?P<id>\w+)',
 			[
 				[
 					'methods'             => WP_REST_Server::READABLE,
diff --git a/includes/reports/class-wc-rest-payments-reports-transactions-controller.php b/includes/reports/class-wc-rest-payments-reports-transactions-controller.php
index 6e130400af2..1e38d6cd746 100644
--- a/includes/reports/class-wc-rest-payments-reports-transactions-controller.php
+++ b/includes/reports/class-wc-rest-payments-reports-transactions-controller.php
@@ -39,7 +39,7 @@ public function register_routes() {
 		);
 		register_rest_route(
 			$this->namespace,
-			'/' . $this->rest_base . '/(?P<id>[A-Za-z0-9_\-]+)',
+			'/' . $this->rest_base . '/(?P<id>\w+)',
 			[
 				[
 					'methods'             => WP_REST_Server::READABLE,
diff --git a/includes/wc-payment-api/class-wc-payments-api-client.php b/includes/wc-payment-api/class-wc-payments-api-client.php
index 4127e620606..626137a8458 100644
--- a/includes/wc-payment-api/class-wc-payments-api-client.php
+++ b/includes/wc-payment-api/class-wc-payments-api-client.php
@@ -518,17 +518,8 @@ public function get_disputes( array $filters = [] ) {
 	 *
 	 * @param string $dispute_id id of requested dispute.
 	 * @return array dispute object.
-	 * @throws API_Exception - Exception thrown in case route validation fails.
 	 */
 	public function get_dispute( $dispute_id ) {
-		if ( ! preg_match( '/(dp|dispute)_[A-Za-z0-9]+/', $dispute_id ) ) {
-			throw new API_Exception(
-				__( 'Route param validation failed.', 'woocommerce-payments' ),
-				'wcpay_route_validation_failure',
-				400
-			);
-		}
-
 		$dispute = $this->request( [], self::DISPUTES_API . '/' . $dispute_id, self::GET );
 
 		if ( is_wp_error( $dispute ) ) {
@@ -735,17 +726,8 @@ public function create_token( $request ) {
 	 * @return array
 	 *
 	 * @throws Exception - Exception thrown on request failure.
-	 * @throws API_Exception - Exception thrown in case route validation fails.
 	 */
 	public function get_timeline( $id ) {
-		if ( ! preg_match( '/(ch|pi|py)_[A-Za-z0-9]+/', $id ) ) {
-			throw new API_Exception(
-				__( 'Route param validation failed.', 'woocommerce-payments' ),
-				'wcpay_route_validation_failure',
-				400
-			);
-		}
-
 		$timeline = $this->request( [], self::TIMELINE_API . '/' . $id, self::GET );
 
 		$has_fraud_outcome_event = false;
@@ -1187,14 +1169,6 @@ public function update_charge( string $charge_id, array $data = [] ) {
 	 * @throws API_Exception
 	 */
 	public function get_charge( string $charge_id ) {
-		if ( ! preg_match( '/(ch|pi|py)_[A-Za-z0-9]+/', $charge_id ) ) {
-			throw new API_Exception(
-				__( 'Route param validation failed.', 'woocommerce-payments' ),
-				'wcpay_route_validation_failure',
-				400
-			);
-		}
-
 		return $this->request(
 			[],
 			self::CHARGES_API . '/' . $charge_id,
diff --git a/package-lock.json b/package-lock.json
index 60e9f7f8a8a..c02183691cd 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -1,12 +1,12 @@
 {
   "name": "woocommerce-payments",
-  "version": "7.8.0",
+  "version": "7.8.1",
   "lockfileVersion": 2,
   "requires": true,
   "packages": {
     "": {
       "name": "woocommerce-payments",
-      "version": "7.8.0",
+      "version": "7.8.1",
       "hasInstallScript": true,
       "license": "GPL-3.0-or-later",
       "dependencies": {
diff --git a/package.json b/package.json
index 5c001ab691d..ae3c8b791f0 100644
--- a/package.json
+++ b/package.json
@@ -1,6 +1,6 @@
 {
   "name": "woocommerce-payments",
-  "version": "7.8.0",
+  "version": "7.8.1",
   "main": "webpack.config.js",
   "author": "Automattic",
   "license": "GPL-3.0-or-later",
diff --git a/readme.txt b/readme.txt
index f0756550b7f..45f5ac455d7 100644
--- a/readme.txt
+++ b/readme.txt
@@ -4,7 +4,7 @@ Tags: woocommerce payments, apple pay, credit card, google pay, payment, payment
 Requires at least: 6.0
 Tested up to: 6.5
 Requires PHP: 7.3
-Stable tag: 7.8.0
+Stable tag: 7.8.1
 License: GPLv2 or later
 License URI: http://www.gnu.org/licenses/gpl-2.0.html
 
@@ -94,6 +94,10 @@ Please note that our support for the checkout block is still experimental and th
 
 == Changelog ==
 
+= 7.8.1 - 2024-06-25 =
+* Fix - Fix "Dispute not loaded" error that was affecting responding to disputes.
+
+
 = 7.8.0 - 2024-06-19 =
 * Add - Add a feedback survey modal upon deactivation.
 * Add - Add new select component to be used for reporting filters, e.g. Payments overview currency select
diff --git a/tests/WCPAY_UnitTestCase.php b/tests/WCPAY_UnitTestCase.php
index 21094b0c23c..4470710b519 100644
--- a/tests/WCPAY_UnitTestCase.php
+++ b/tests/WCPAY_UnitTestCase.php
@@ -15,6 +15,68 @@
  * Class WP_UnitTestCase
  */
 class WCPAY_UnitTestCase extends WP_UnitTestCase {
+	public function set_up() {
+		parent::set_up();
+
+		// Use a priority of 9 to ensure that these filters will allow tests that want to mock external requests
+		// to hook in with the regular 10 priority and do their thing.
+		// But by default we will intercept all external requests.
+		add_filter( 'pre_http_request', [ $this, 'filter_intercept_external_requests' ], 9, 3 );
+		add_filter( 'woocommerce_get_geolocation', [ $this, 'filter_mock_wc_geolocation' ], 9, 2 );
+	}
+
+	public function tear_down() {
+		remove_filter( 'pre_http_request', [ $this, 'filter_intercept_external_requests' ], 9, 3 );
+		remove_filter( 'woocommerce_get_geolocation', [ $this, 'filter_mock_wc_geolocation' ], 9, 2 );
+
+		parent::tear_down();
+	}
+
+	/**
+	 * Intercept external requests and return a service unavailable response.
+	 *
+	 * This way we don't allow relying on external services for tests (fragile and slow tests) and force those tests
+	 * that care about a response to mock the request response.
+	 *
+	 * @see WP_Http::request()
+	 *
+	 * @param false|array|WP_Error $response    A preemptive return value of an HTTP request. Default false.
+	 * @param array                $parsed_args HTTP request arguments.
+	 * @param string               $url         The request URL.
+	 *
+	 * @return array
+	 */
+	public function filter_intercept_external_requests( $response, $parsed_args, $url ) {
+		// Return a service unavailable response.
+		return [
+			'body'          => '',
+			'response'      => [
+				'code' => WP_Http::SERVICE_UNAVAILABLE,
+			],
+			'headers'       => [],
+			'cookies'       => [],
+			'http_response' => null,
+		];
+	}
+
+	/**
+	 * Intercept geolocation requests and return mock data.
+	 *
+	 * @param array $geolocation
+	 * @param string $ip_address
+	 *
+	 * @return array
+	 */
+	public function filter_mock_wc_geolocation( $geolocation, $ip_address ) {
+		$ip_geolocation_test_data = json_decode( file_get_contents( __DIR__ . '/unit/test-data/ip-geolocation.json' ), true );
+
+		if ( ! empty( $ip_geolocation_test_data[ $ip_address ] ) ) {
+			$geolocation = array_merge( $geolocation, $ip_geolocation_test_data[ $ip_address ] );
+		}
+
+		return $geolocation;
+	}
+
 	protected function is_wpcom() {
 		return defined( 'IS_WPCOM' ) && IS_WPCOM;
 	}
diff --git a/tests/unit/test-class-wc-payments-token-service.php b/tests/unit/test-class-wc-payments-token-service.php
index f9465769f89..4835cf32b09 100644
--- a/tests/unit/test-class-wc-payments-token-service.php
+++ b/tests/unit/test-class-wc-payments-token-service.php
@@ -489,17 +489,23 @@ public function test_woocommerce_get_customer_payment_tokens_multiple_tokens_mul
 		$gateway->settings['upe_enabled_payment_method_ids'] = $payment_methods;
 
 		// Array keys should match the database ID of the token.
-		$tokens = [
+		$card_tokens        = [
 			1 => $this->generate_card_token( 'pm_111', 1 ),
 			2 => $this->generate_card_token( 'pm_222', 2 ),
+		];
+		$sepa_tokens        = [
 			3 => $this->generate_sepa_token( 'pm_333', 3 ),
 			4 => $this->generate_sepa_token( 'pm_444', 4 ),
+		];
+		$stripe_link_tokens = [
 			5 => $this->generate_link_token( 'pm_555', 5 ),
 			6 => $this->generate_link_token( 'pm_666', 6 ),
 		];
 
+		$all_saved_tokens = $card_tokens + $sepa_tokens + $stripe_link_tokens;
+
 		$this->mock_customer_service
-			->expects( $this->once() )
+			->expects( $this->exactly( 2 ) )
 			->method( 'get_customer_id_by_user_id' )
 			->willReturn( $customer_id );
 
@@ -509,7 +515,6 @@ public function test_woocommerce_get_customer_payment_tokens_multiple_tokens_mul
 			->method( 'get_payment_methods_for_customer' )
 			->withConsecutive(
 				[ $customer_id, Payment_Method::CARD ],
-				[ $customer_id, Payment_Method::SEPA ],
 				[ $customer_id, Payment_Method::LINK ]
 			)
 			->willReturnOnConsecutiveCalls(
@@ -517,20 +522,27 @@ public function test_woocommerce_get_customer_payment_tokens_multiple_tokens_mul
 					$this->generate_card_pm_response( 'pm_111' ),
 					$this->generate_card_pm_response( 'pm_222' ),
 				],
-				[
-					$this->generate_sepa_pm_response( 'pm_333' ),
-					$this->generate_sepa_pm_response( 'pm_444' ),
-				],
 				[
 					$this->generate_link_pm_response( 'pm_555' ),
 					$this->generate_link_pm_response( 'pm_666' ),
+				],
+				[
+					$this->generate_sepa_pm_response( 'pm_333' ),
+					$this->generate_sepa_pm_response( 'pm_444' ),
 				]
 			);
 
-		$result = $this->token_service->woocommerce_get_customer_payment_tokens( $tokens, 1, 'woocommerce_payments' );
+		$card_and_link_result = $this->token_service->woocommerce_get_customer_payment_tokens( $all_saved_tokens, 1, WC_Payment_Gateway_WCPay::GATEWAY_ID );
+		$sepa_result          = $this->token_service->woocommerce_get_customer_payment_tokens( $all_saved_tokens, 1, WC_Payment_Gateway_WCPay::GATEWAY_ID . '_' . Payment_Method::SEPA );
+
 		$this->assertSame(
-			array_keys( $tokens ),
-			array_keys( $result )
+			array_keys( $card_tokens + $stripe_link_tokens ),
+			array_keys( $card_and_link_result )
+		);
+
+		$this->assertSame(
+			array_keys( $sepa_tokens ),
+			array_keys( $sepa_result )
 		);
 	}
 
@@ -656,51 +668,6 @@ public function test_woocommerce_get_customer_payment_tokens_not_added_twice_for
 		$this->assertEquals( 'pm_444', $result_tokens[3]->get_token() );
 	}
 
-	public function test_woocommerce_get_customer_payment_tokens_not_added_from_different_gateway() {
-		$this->mock_cache->method( 'get' )->willReturn( [ 'is_deferred_intent_creation_upe_enabled' => true ] );
-		$gateway_id      = WC_Payment_Gateway_WCPay::GATEWAY_ID;
-		$tokens          = [];
-		$payment_methods = [ Payment_Method::CARD, Payment_Method::SEPA ];
-
-		$gateway = WC_Payments::get_gateway();
-		$gateway->settings['upe_enabled_payment_method_ids'] = $payment_methods;
-
-		$this->mock_customer_service
-			->expects( $this->any() )
-			->method( 'get_customer_id_by_user_id' )
-			->willReturn( 'cus_12345' );
-
-		$this->mock_customer_service
-			->expects( $this->exactly( 2 ) )
-			->method( 'get_payment_methods_for_customer' )
-			->withConsecutive(
-				[ 'cus_12345', Payment_Method::CARD ],
-				[ 'cus_12345', Payment_Method::SEPA ]
-			)
-			->willReturnOnConsecutiveCalls(
-				[
-					$this->generate_card_pm_response( 'pm_mock0' ),
-					$this->generate_card_pm_response( 'pm_222' ),
-				],
-				[
-					$this->generate_sepa_pm_response( 'other_gateway_pm_111' ),
-					$this->generate_sepa_pm_response( 'other_gateway_pm_222' ),
-					$this->generate_sepa_pm_response( 'other_gateway_pm_333' ),
-					$this->generate_sepa_pm_response( 'other_gateway_pm_444' ),
-					$this->generate_sepa_pm_response( 'other_gateway_pm_555' ),
-				]
-			);
-
-		$result        = $this->token_service->woocommerce_get_customer_payment_tokens( $tokens, 1, $gateway_id );
-		$result_tokens = array_values( $result );
-
-		$this->assertEquals( 2, count( $result_tokens ) );
-		$this->assertEquals( $gateway_id, $result_tokens[0]->get_gateway_id() );
-		$this->assertEquals( $gateway_id, $result_tokens[1]->get_gateway_id() );
-		$this->assertEquals( 'pm_mock0', $result_tokens[0]->get_token() );
-		$this->assertEquals( 'pm_222', $result_tokens[1]->get_token() );
-	}
-
 	public function test_woocommerce_get_customer_payment_tokens_payment_methods_only_for_retrievable_types() {
 		$enabled_upe_payment_methods = [
 			Payment_Method::CARD,
@@ -716,7 +683,6 @@ public function test_woocommerce_get_customer_payment_tokens_payment_methods_onl
 		$gateway                     = WC_Payments::get_gateway();
 		$gateway->settings['upe_enabled_payment_method_ids'] = $enabled_upe_payment_methods;
 		$tokens      = [];
-		$gateway_id  = 'woocommerce_payments';
 		$customer_id = 'cus_12345';
 
 		$this->mock_customer_service
@@ -729,22 +695,23 @@ public function test_woocommerce_get_customer_payment_tokens_payment_methods_onl
 			->method( 'get_payment_methods_for_customer' )
 			->withConsecutive(
 				[ $customer_id, Payment_Method::CARD ],
+				[ $customer_id, Payment_Method::LINK ],
 				[ $customer_id, Payment_Method::SEPA ],
-				[ $customer_id, Payment_Method::LINK ]
 			)
 			->willReturnOnConsecutiveCalls(
 				[
 					$this->generate_card_pm_response( 'pm_mock0' ),
 				],
 				[
-					$this->generate_sepa_pm_response( 'pm_mock_2' ),
+					$this->generate_link_pm_response( 'pm_mock_3' ),
 				],
 				[
-					$this->generate_link_pm_response( 'pm_mock_3' ),
-				]
+					$this->generate_sepa_pm_response( 'pm_mock_2' ),
+				],
 			);
 
-		$this->token_service->woocommerce_get_customer_payment_tokens( $tokens, 1, $gateway_id );
+		$this->token_service->woocommerce_get_customer_payment_tokens( $tokens, 1, WC_Payment_Gateway_WCPay::GATEWAY_ID );
+		$this->token_service->woocommerce_get_customer_payment_tokens( $tokens, 1, WC_Payment_Gateway_WCPay::GATEWAY_ID . '_' . Payment_Method::SEPA );
 	}
 
 	/**
diff --git a/tests/unit/test-data/ip-geolocation.json b/tests/unit/test-data/ip-geolocation.json
new file mode 100644
index 00000000000..69313efa0d6
--- /dev/null
+++ b/tests/unit/test-data/ip-geolocation.json
@@ -0,0 +1,11 @@
+{
+  "206.71.50.230": {
+    "country": "US"
+  },
+  "187.34.8.193": {
+    "country": "BR"
+  },
+  "127.0.0.1": {
+    "country": "US"
+  }
+}
diff --git a/tests/unit/woopay/test-class-woopay-utilities.php b/tests/unit/woopay/test-class-woopay-utilities.php
index 13a8bcb5f01..72f7d30e480 100644
--- a/tests/unit/woopay/test-class-woopay-utilities.php
+++ b/tests/unit/woopay/test-class-woopay-utilities.php
@@ -30,7 +30,7 @@ public function tear_down() {
 	/**
 	 * Data provider for test_should_enable_woopay.
 	 *
-	 * @return boolean
+	 * @return array
 	 */
 	public function should_enable_woopay_data_provider() {
 		return [
@@ -61,9 +61,11 @@ public function test_should_enable_woopay( $woopay_eligible, $gateway_woopay_ena
 	}
 
 	/**
-	 * Data provider for test_should_enable_woopay.
+	 * Data provider for test_is_country_available.
+	 *
+	 * @see test-data/ip_geolocation.json
 	 *
-	 * @return boolean
+	 * @return array
 	 */
 	public function is_country_available_data_provider() {
 		return [
@@ -84,7 +86,7 @@ public function test_is_country_available( $ip_address, $expected ) {
 		WC_Payments::mode()->live();
 
 		$woopay_utilities = new WooPay_Utilities();
-		$actual           = $woopay_utilities->is_country_available( $this->gateway_mock );
+		$actual           = $woopay_utilities->is_country_available();
 		$this->assertSame( $expected, $actual );
 	}
 
@@ -92,7 +94,7 @@ public function test_is_country_available_in_test_mode_return_true() {
 		WC_Payments::mode()->test();
 
 		$woopay_utilities = new WooPay_Utilities();
-		$actual           = $woopay_utilities->is_country_available( $this->gateway_mock );
+		$actual           = $woopay_utilities->is_country_available();
 		$this->assertSame( true, $actual );
 	}
 
diff --git a/woocommerce-payments.php b/woocommerce-payments.php
index f49664ad999..ac10ffab61c 100644
--- a/woocommerce-payments.php
+++ b/woocommerce-payments.php
@@ -11,7 +11,7 @@
  * WC tested up to: 8.9.3
  * Requires at least: 6.0
  * Requires PHP: 7.3
- * Version: 7.8.0
+ * Version: 7.8.1
  * Requires Plugins: woocommerce
  *
  * @package WooCommerce\Payments